ASP.NET Core – Configure JSON serializer options

ASP.NET Core uses System.Text.Json as the default JSON serializer. To configure the JSON serializer options, call AddJsonOptions() in the initialization code:

using System.Text.Json.Serialization;

//rest of adding services

builder.Services.AddControllers().AddJsonOptions(options =>
{
    options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
});

//rest of init code
Code language: C# (cs)

Calling AddJsonOptions() gives you access to the global JsonSerializerOptions object. This is used for all requests / responses. You can configure the options and add converters (including your own custom JSON converters).

ASP.NET Core’s default JSON options

By default, ASP.NET Core uses JsonSerializerDefaults.Web with JsonSerializerOptions. This is equivalent to using these settings:

PropertyNameCaseInsensitive = true,
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
NumberHandling = JsonNumberHandling.AllowReadingFromString
Code language: C# (cs)

You can configure this however you want in AddJsonOptions().

Return JsonResult with JsonSerializerOptions

Using AddJsonOptions() configures JSON options for all requests / responses. If you want to configure the JSON options for a single response, use JsonResult. You can return JsonResult with a JsonSerializerOptions configured how you like. Here’s an example:

using System.Text.Json;
using System.Text.Json.Serialization;
using System.Net;

[HttpGet("{symbol}")]
public async Task<IActionResult> Get(string symbol)
{
	var stock = await GetStockFromRepo(symbol);

	var options = new JsonSerializerOptions(JsonSerializerDefaults.Web);
	options.Converters.Add(new JsonStringEnumConverter());

	return new JsonResult(stock, options)
	{
		StatusCode = (int)HttpStatusCode.OK
	};
}
Code language: C# (cs)

Note: Notice it’s passing in JsonSerializerDefaults.Web into the constructor. This is to make sure it’s using the defaults that ASP.NET Core normally uses.

It uses the JsonSerializerOptions you passed in to serialize the model in the response. This endpoint outputs the following JSON:

{
    "symbol": "AMZN",
    "price": 101.1,
    "quoteTime": "2021-07-23T15:13:16.3911373-04:00",
    "fundType": "Stock"
}
Code language: JSON / JSON with Comments (json)

Performance tradeoff

This approach is simple but it has a performance tradeoff. You get optimal performance by reusing JsonSerializerOptions objects. The performance hit may be miniscule when compared to the overall response time, so it probably won’t make a big difference.

Change Newtonsoft settings

System.Text.Json is the default JSON serializer in ASP.NET Core. Let’s say you want to use Newtonsoft instead, and you want to change the settings. To do this, call AddNewtonsoftJson() in the initialization code, like this:

using Newtonsoft.Json.Serialization;

//rest of adding services

builder.Services.AddControllers().AddNewtonsoftJson(options =>
{
    //customize settings here. For example, change the naming strategy

    options.SerializerSettings.ContractResolver = new DefaultContractResolver()
    {
        NamingStrategy = new SnakeCaseNamingStrategy()
    };
});

//rest of init code
Code language: C# (cs)

Note: Install the Microsoft.AspNetCore.Mvc.NewtonsoftJson package if necessary.

To see this work, send a request:

GET https://localhost:12345/booksCode language: plaintext (plaintext)

It returns the following JSON with snake-cased property names, showing that it’s using Newtonsoft as configured above:

{
    "title": "Code",
    "subtitle": "The Hidden Language of Computer Hardware and Software",
    "author_name": "Charles Petzold",
    "date_first_published": "2000-10-11T00:00:00"
}Code language: JSON / JSON with Comments (json)

Comments are closed.