【问题标题】:NullReferenceException from JsonSerializer in POST methodPOST 方法中来自 JsonSerializer 的 NullReferenceException
【发布时间】:2019-12-09 01:48:51
【问题描述】:

我正在尝试在#C 中编写一个简单的 REST API,但是在编写 POST 处理程序时很早就遇到了一个问题,即一个相当无用的错误消息。我使用的是 .NET Core 3.0,该项目是使用 Visual Studio 中的 ASP.NET Core API 模板创建的。

这是我的代码的简化版本,但仍会触发问题(类位于完整项目中的单独文件中):

[Route("api/blub")]
[ApiController]
public class BlubController : ControllerBase
{
    [HttpGet]
    public IEnumerable<Blub> Get()
    {
        return new Blub[0];
    }

    [HttpPost]
    public ActionResult<Blub> PostBlub([FromBody] string[] paths)
    {
        return new Blub(paths);
    }
}

public class Blub
{
    public Blub(string[] paths)
    {
        this.Paths = paths;
        StartedAt = DateTime.Now;
    }

    public string[] Paths { get; }
    public DateTime StartedAt { get; }
}

我的 POST 请求的负载如下所示:

{ "paths": [ "abc", "def" ] }

对我的api/blub 路由执行 POST 请求时出现以下异常:

System.NullReferenceException: Object reference not set to an instance of an object.
   at System.Text.Json.JsonSerializer.HandleStartObject(JsonSerializerOptions options, ReadStack& state)
   at System.Text.Json.JsonSerializer.ReadCore(JsonSerializerOptions options, Utf8JsonReader& reader, ReadStack& readStack)
   at System.Text.Json.JsonSerializer.ReadCore(JsonReaderState& readerState, Boolean isFinalBlock, ReadOnlySpan`1 buffer, JsonSerializerOptions options, ReadStack& readStack)
   at System.Text.Json.JsonSerializer.ReadAsync[TValue](Stream utf8Json, Type returnType, JsonSerializerOptions options, CancellationToken cancellationToken)
   at Microsoft.AspNetCore.Mvc.Formatters.SystemTextJsonInputFormatter.ReadRequestBodyAsync(InputFormatterContext context, Encoding encoding)
   at Microsoft.AspNetCore.Mvc.Formatters.SystemTextJsonInputFormatter.ReadRequestBodyAsync(InputFormatterContext context, Encoding encoding)
   at Microsoft.AspNetCore.Mvc.ModelBinding.Binders.BodyModelBinder.BindModelAsync(ModelBindingContext bindingContext)
   at Microsoft.AspNetCore.Mvc.ModelBinding.ParameterBinder.BindModelAsync(ActionContext actionContext, IModelBinder modelBinder, IValueProvider valueProvider, ParameterDescriptor parameter, ModelMetadata metadata, Object value)
   at Microsoft.AspNetCore.Mvc.Controllers.ControllerBinderDelegateProvider.<>c__DisplayClass0_0.<<CreateBinderDelegate>g__Bind|0>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeInnerFilterAsync>g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   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.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)

无论我的 POST 请求是否包含正确的正文,任何 POST 请求似乎都会触发此异常。 GET 请求可以正常工作。我试图登录到控制台并在我的函数中设置一个断点,但据我所知,即使在调用我的函数之前就抛出了异常。

为什么 JsonFormatter 会在这里抛出异常,我该如何解决?

【问题讨论】:

  • 您在 POST 请求中发送的有效负载是什么?
  • @ChetanRanpariya 我尝试了不同的,没关系,我总是遇到异常。预期的有效负载类似于{ "paths": [ "abc", "def" ] }

标签: c# asp.net-core


【解决方案1】:

您在类型映射中遇到问题,请将方法签名更改为:

[HttpPost]
public ActionResult<Blub> PostBlub([FromBody] MyRequest request)
{
    return new Blub(request.Paths);
}

public class MyRequest
{
    public string[] Paths { get; set; }
}

或者把payload改成:

 [ "abc", "def" ]

【讨论】:

  • 谢谢,解决了这个问题。我将不得不更多地阅读映射,很明显我误解了它。但是我有点困惑它会引发异常,因为文档似乎表明即使参数无法匹配它通常也不会这样做。
  • @MadScientist 同意,当你谈论类时,通常它是这样工作的,但看起来数组是不同的。此外,他们更改了 .NET Core 3 中的 JSON 实现,如果您尝试使用 2.2 中的代码,它将为您提供清晰的异常消息
【解决方案2】:

这仅仅意味着某些引用类型的member/variable 通过使用其实例 non-static 成员取消引用, 这要求这个member/variablenon-null,但实际上它 似乎是null。只需在调试器下执行它,它就会 停止抛出异常的执行。设置一个断点 该行,重新启动应用程序并再次来到这一点。 评估下一行中涉及的所有引用,看看哪个是 null 而它必须不为 null。弄清楚后,修复 代码:要么确保成员/变量正确初始化为 non-null 参考,或检查 null,如果是 null, 做点别的。

使用下面的代码 sn-p:

 [HttpPost]
    public ActionResult<Blub> PostBlub([FromBody] APIRequest request)
    {
        return new Blub(request.Paths);
    }

    public class APIRequest
    {
        public string[] Paths { get; set; }
    }

【讨论】:

    猜你喜欢
    • 2013-04-21
    • 1970-01-01
    • 2021-03-07
    • 2011-10-07
    • 1970-01-01
    • 2012-09-01
    • 2014-08-31
    • 2021-02-03
    相关资源
    最近更新 更多