【问题标题】:How to send POST for both master and detail tables?如何为主表和详细表发送 POST?
【发布时间】:2020-08-27 17:34:29
【问题描述】:

目前我正在使用以下 post 方法,它返回错误 500 内部服务器错误。 System.NullReferenceException:对象引用未设置为对象的实例。在 WebApi.Controllers.OrderController.PostOrder(Order order)

        public async Task<ActionResult<Order>> PostOrder(Order order)
        {
            
            // order table
            _context.OrderRequests.Add(order);
            
            // orderitem table
            foreach (var item in order.OrderItems)
            {
                _context.OrderItems.Add(item);
            }
            
            await _context.SaveChangesAsync();

            return CreatedAtAction("GetOrder", new { id = order.OrderID}, order);
            
         }

怎么了?如何在两个表上提交 POST?还是我必须为 OrderItems 创建一个单独的 Web api 控制器?

System.NullReferenceException:对象引用未设置为对象的实例。 在 C:\dev\Test\WebApi\Controllers\OrderController.cs:line 91 中的 WebApi.Controllers.OrderController.PostOrder(Order order) 在 lambda_method(闭包,对象) 在 Microsoft.Extensions.Internal.ObjectMethodExecutorAwaitable.Awaiter.GetResult() 在 Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.AwaitableObjectResultExecutor.Execute(IActionResultTypeMapper 映射器,ObjectMethodExecutor 执行器,对象控制器,对象 [] 参数) 在 Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.g__Awaited|12_0(ControllerActionInvoker 调用程序,ValueTask`1 actionResultValueTask) 在 Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.g__Awaited|10_0(ControllerActionInvoker 调用程序,任务 lastTask,下一个状态,作用域范围,对象状态,布尔 isCompleted) 在 Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed 上下文) 在 Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(状态&下一个,范围&范围,对象&状态,布尔& isCompleted) 在 Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync() --- 从先前抛出异常的位置结束堆栈跟踪 --- 在 Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|19_0(ResourceInvoker 调用程序,任务 lastTask,下一个状态,作用域范围,对象状态,布尔 isCompleted) 在 Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|17_0(ResourceInvoker 调用程序,任务任务,IDisposable 范围) 在 Microsoft.AspNetCore.Routing.EndpointMiddleware.g__AwaitRequestTask|6_0(端点端点,任务 requestTask,ILogger 记录器) 在 Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext 上下文) 在 Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext 上下文)

【问题讨论】:

  • 您无需为嵌套项创建单独的 API 控制器。我尝试使用像您这样的嵌套结构来复制场景(父类具有 List 类作为其成员之一)并且可以成功发布数据。模型绑定似乎没有任何问题。 500 可能是因为服务器端问题。查看异常的堆栈跟踪可以提供更多信息。
  • 我添加了整个异常细节。我在前端使用角度。你认为问题会在那里吗?还是在 asp.net core web api 上?

标签: json asp.net-core entity-framework-core asp.net-core-webapi


【解决方案1】:

只需在添加“子”记录之前将更改保存到上下文:

    public async Task<ActionResult<Order>> PostOrder(Order order)
    {
        
        // order table
        _context.OrderRequests.Add(order);
        await _context.SaveChangesAsync();
        
        // orderitem table
        foreach (var item in order.OrderItems)
        {
            _context.OrderItems.Add(item);
        }
        
        await _context.SaveChangesAsync();

        return CreatedAtAction("GetOrder", new { id = order.OrderID}, order);
        
     }

【讨论】:

  • 很好用,但现在我可以更新订单表,但订单详细信息表没有更新,它仍然返回与上述相同的错误 500。我必须使用 dto 来隐藏外键吗?
  • "但是订单明细表没有更新" - 什么意思?
  • 好的,所以订单的 json 是 {"OrderID":9,"OrderNo":"358602","CreatedOn":"2020-08-12","UserID":4,"用户":null,"OrderItems":null}。在 POST 之后,Order 表更新为 OrderID:9、OrderNo:“258602”、CreatedOn:“2020-08-12”、UserID:4 值。但是 OrderItems 表中没有填满所选项目。
  • 哦,我在模型中发现了一个错字...所以现在 OrderItems 表也已更新。但不知何故,仍然出现错误 500。为什么会这样? Microsoft.EntityFrameworkCore.DbUpdateException:更新条目时出错。有关详细信息,请参阅内部异常。 ---> Microsoft.Data.SqlClient.SqlException (0x80131904):当 IDENTITY_INSERT 设置为 OFF 时,无法在表“OrderItems”中插入标识列的显式值。
猜你喜欢
  • 2017-10-30
  • 2018-07-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多