Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NullReferenceException from JsonSerializer in POST method

I'm trying to write a simple REST API in #C, but I ran into a problem with a rather unhelpful error message very early when writing a POST handler. I'm using .NET Core 3.0 and the project was created with the ASP.NET Core API template in Visual Studio.

This is a simplified version of my code that still triggers the issue (the classes are in separate Files in the full project):

[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; }
}

The payload of my POST request is something like the following:

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

I'm getting the following Exception when performing a POST request to my api/blub route:

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)

It doesn't matter whether my POST request contains the correct body or not, any POST requests seems to trigger this exception. The GET request works without issues. I tried to log to the console and set a breakpoint in my function, but as far as I can tell the exception is thrown even before my function is called.

Why is the JsonFormatter throwing an exception here, and how can I fix this?

like image 684
Mad Scientist Avatar asked Oct 15 '25 14:10

Mad Scientist


1 Answers

You have an issue in type mapping, either change method signature to:

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

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

Or change the payload to:

 [ "abc", "def" ]
like image 71
Uriil Avatar answered Oct 18 '25 05:10

Uriil