How to configure JSON deserialization options in .NET minimal API project
Asked Answered
C

4

5

I have a .NET minimal API project, as described here. One of the endpoints accepts JSON in the request body, and this is deserialized automatically. The code looks something like this:

app.MapPost("/myendpoint", async (MyInputFromBody input) => { ... });

This works in general, but I would like to specify options for deserialization. For instance, the JSON has some date fields such as "myDate": "2021-04-01T06:00:00", which can be converted to a DateTime, but an empty date value "myDate": "" throws an exception (System.FormatException: The JSON value is not in a supported DateTime format.).

I found a suggestion to write my own DateTime converter and use this:

builder.Services.AddControllers()
    .AddJsonOptions(options => options.JsonSerializerOptions.Converters.Add(new JsonDateTimeConverter()));

but this doesn't seem to do anything. A breakpoint in my converter is never hit, and I get the same exception as before.

Is there a way to specify JSON options, or should I use a string parameter, as in [FromBody] string body, and parse that myself?

Cockloft answered 15/9, 2023 at 7:51 Comment(0)
T
6

AddControllers().AddJsonOptions is configuring for your controllers, To configure for Minimal api all you have to do is:

builder.Services.Configure<JsonOptions>(options => options.SerializerOptions.Converters.Add(new JsonDateTimeConverter()));

Tutorial on this

ASP.NET Core supports two approaches to creating APIs: a controller-based approach and minimal APIs. Controllers in an API project are classes that derive from ControllerBase. Minimal APIs define endpoints with logical handlers in lambdas or methods. This article points out differences between the two approaches.

Difference

Tena answered 15/9, 2023 at 9:12 Comment(0)
J
4

From documentation

By default, minimal API apps use Web defaults options during JSON serialization and deserialization.

You can find how to ajust this configuration using ConfigureHttpJsonOptions

You can use also :

builder.Services.Configure<Microsoft.AspNetCore.Http.Json.JsonOptions>(options =>
{
    options.SerializerOptions
});

Note that

  • JsonOptions should come from Microsoft.AspNetCore.Http.Json and not from Mvc... otherwise not for minimal API
  • Microsoft.AspNetCore.Http.Json uses System.Text.Json
  • AddJsonOptions for IMvcBuilder using System.Text.Json not for minimal API
  • AddNewtonsoftJson for IMvcBuilder using Newtonsoft.Json not for minimal API
  • AddControllers returns IMvcBuilder.
Johan answered 5/7, 2024 at 15:14 Comment(0)
T
1

I put these in my Program.cs ignore the actual configs they may not be for you.

Minimal APIs .net 8 - do not use AddNewtonsoftJson

builder.Services.Configure<JsonOptions>(options =>
    {
        //options.SerializerOptions.Converters.Add(new TimeSpanConverter());
        //options.SerializerOptions.Converters.Add(new JsonDateTimeConverter());
        options.SerializerOptions.ReferenceHandler = ReferenceHandler.Preserve;
        options.SerializerOptions.MaxDepth = 1000;
    });

NewtonsoftJson Options non Minimal APIs

builder.Services.AddControllersWithViews().AddNewtonsoftJson(options =>
        {
            options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
        }   
    );

MicrosoftJson Options non Minimal API

builder.Services.AddControllers().AddJsonOptions(options =>
    {
            options.JsonSerializerOptions.ReferenceHandler = ReferenceHandler.IgnoreCycles;
            options.JsonSerializerOptions.MaxDepth = 100;
            options.JsonSerializerOptions.IgnoreNullValues = true;
            options.JsonSerializerOptions.Converters.Add(new TimeSpanConverter());
        }
    );
Thoron answered 18/4, 2024 at 10:24 Comment(0)
C
0

In my .NET 8 minimal API, JsonOptions wasn't installed by default, so I couldn't call services.Configure<JsonOptions>(x => ...).

For anyone else having this problem, installing Microsoft.AspNetCore.Http.Extensions resolved it for me. I could then call services.Configure<JsonOptions>(x => ...) in the normal way, as described above.

Cutting answered 18/8, 2024 at 12:54 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.