【问题标题】:JSON retrieve with only some elements of its modelJSON 只检索其模型的一些元素
【发布时间】:2020-12-18 12:17:11
【问题描述】:

在我的后端,我有一个这样定义的模型:

    using System;
    using System.Collections.Generic;
    
    namespace App.API.Models
    {
        public class Situation
        {
            public int Id { get; set; }
            public string Description { get; set; }
            public bool IsMain { get; set; }
            public int UserId { get; set; }
            public bool IsApproved { get; set;}

        }
    }

在我的前端我有一个定义了这个函数的服务:

rejectSituation(id: number) {
  return this.http
  .put(
    this.baseUrl + 'Situation/' + id,
    {
      "id": id,
      "isApproved": "false" 
    }
  );
}

就我只想更改前端模型的 IsApproved 变量而言,我只将它与我的函数服务一起发送。而且,我从组件的 .ts 文件中调用此服务:

   approveSituation(situacionId: number) {
     this.situacionesService.approveSituation(situacionId).subscribe(() => {
      // 1) Searches for the Id in the array 
      let index = this.situaciones.findIndex(p => p.id === this.situacion.id);
      // 2) Put this in situation's array
      this.situaciones[index].isApproved = true;
     }, error => {
      console.log(error);
     });
  }

但不幸的是我最后发现了这个错误:

Microsoft.EntityFrameworkCore.DbUpdateException: An error occurred while updating the entries. See the inner exception for details.
     ---> Microsoft.Data.Sqlite.SqliteException (0x80004005): SQLite Error 19: 'FOREIGN KEY constraint failed'.
       at Microsoft.Data.Sqlite.SqliteException.ThrowExceptionForRC(Int32 rc, sqlite3 db)
       at Microsoft.Data.Sqlite.SqliteDataReader.NextResult()
       at Microsoft.Data.Sqlite.SqliteCommand.ExecuteReader(CommandBehavior behavior)
       at Microsoft.Data.Sqlite.SqliteCommand.ExecuteReaderAsync(CommandBehavior behavior, CancellationToken cancellationToken)
       at Microsoft.Data.Sqlite.SqliteCommand.ExecuteDbDataReaderAsync(CommandBehavior behavior, CancellationToken cancellationToken)
       at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken)
       at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken)
       at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken)
       at Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.ExecuteAsync(IRelationalConnection connection, CancellationToken cancellationToken)
       --- End of inner exception stack trace ---
       at Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.ExecuteAsync(IRelationalConnection connection, CancellationToken cancellationToken)
       at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.ExecuteAsync(IEnumerable`1 commandBatches, IRelationalConnection connection, CancellationToken cancellationToken)
       at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.ExecuteAsync(IEnumerable`1 commandBatches, IRelationalConnection connection, CancellationToken cancellationToken)
       at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChangesAsync(IList`1 entriesToSave, CancellationToken cancellationToken)
       at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChangesAsync(DbContext _, Boolean acceptAllChangesOnSuccess, CancellationToken cancellationToken)
       at Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync(Boolean acceptAllChangesOnSuccess, CancellationToken cancellationToken)
       at App.API.Data.VVRepository.SaveAll() in D:\Project6\App\App.API\Data\VVRepository.cs:line 181
       at App.API.Helpers.LogUserActivity.OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) in D:\Project6\App\App.API\Helpers\LogUserActivity.cs:line 21
       at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
       at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
       at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
       at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync()
    --- End of stack trace from previous location where exception was thrown ---
       at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
       at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Logged|17_1(ResourceInvoker invoker)
       at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
       at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
       at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
       at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
    
    HEADERS
    =======
    Connection: keep-alive
    Content-Type: application/json
    Accept: application/json, text/plain, */*
    Accept-Encoding: gzip, deflate, br
    Accept-Language: es,es-ES;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6
    Authorization: Bearer eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJuYW1laWQiOiIxIiwidW5pcXVlX25hbWUiOiJMb2xhIiwicm9sZSI6IkFkbWluIiwibmJmIjoxNTk4NzE1NjEyLCJleHAiOjE1OTg4MDIwMTIsImlhdCI6MTU5ODcxNTYxMn0.WHy68UGhoJfN1Z8REEDe3FgltNdMf04JZrQ9694rMvq2Re62NBLR71pKuDPghQu4r5I-XzCDearzz25H1Jo9yQ
    Host: localhost:5000
    Referer: http://localhost:4200/admin
    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.83 Safari/537.36 Edg/85.0.564.41
    DNT: 1
    Origin: http://localhost:4200
    Content-Length: 25
    Sec-Fetch-Site: same-site
    Sec-Fetch-Mode: cors
    Sec-Fetch-Dest: empty

我认为...这是由于我从前端发送到后端的 JSON 结构,因为模型需要它的所有项目。但是前端正在发送与订单不匹配的 JSON。换句话说,如果我发送 'id' 和 'isApproved' 而不发送其他项目:Description、IsMain 和 UserId ......这是行不通的。但是...如何在后端更改该项目而不发送有关其他项目的信息?

尝试这个...导致失败...为什么?

【问题讨论】:

  • 能否在要忽略的属性顶部添加 [JsonIgnore] 注释并再次测试它?
  • 错误!如果我在每个关键行中将它放在 C# 中的模型上,它将使其他方法失败。如果我把它放在我的 .ts 文件上,Angular 将无法编译。
  • 您为什么不创建另一个适合您的前端输入的模型?或者为什么不从前面传递所有参数但具有 null 或空值?
  • 使属性可以为空:public int Id { get; set; } public string Description { get; set; } public bool? IsMain { get; set; } public int? UserId { get; set; } public bool? IsApproved { get; set;}
  • 您应该确保发送的模型具有分配给所有属性的值。如果这不可能,您应该首先从数据库中检索数据对象(假设模型具有Id 属性集,这是表的PK),从模型属性值设置它的属性,这些属性值不为空并保存数据对象返回数据库。

标签: c# json angular frontend backend


【解决方案1】:

您应该确保发送的模型具有分配给所有属性的值。如果这不可能,您应该首先从数据库中检索数据对象(假设模型具有 Id 属性集,它是表的 PK),从模型属性值设置它的属性,而不是 null 并将数据对象保存回数据库。

#Chetan 是对的,你需要发送 PUT 的完整模型。如果您只想发送模型中的更改,则需要使用 PATCH 动词和 JsonPatch 文档。 jsonpatch.com – 昨天的达伦街

这就是解决方案!谢谢!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-05-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-19
    相关资源
    最近更新 更多