dotnet / dotnet/aspnetcore

Consider adding a mechanism for copying `JsonSerializerOptions` settings to the `JsonOptions` classes

Open
#49,758 13 comments 0 reactions 0 assignees View on GitHub
api-suggestion area-mvc
Dominant language
C#
Stars
38.4k
Forks
10.9k
Avg merge
2d 10h
Merged PRs (30d)
281

Description

### Background and motivation

Today when I am working with Asp.Net and maybe other libraries/classes that work use JsonSerialization and I want to make sure, that the same options are applied everywhere I have to go through a lot of code.

For example here is how this look like in my AspNet project:

```cs
var builder = WebApplication.CreateBuilder(args);

builder.Services.ConfigureHttpJsonOptions(options =>
{
options.SerializerOptions.PropertyNameCaseInsensitive = true;
options.SerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
options.SerializerOptions.DictionaryKeyPolicy = JsonNamingPolicy.CamelCase;
options.SerializerOptions.Converters = {
new JsonStringEnumConverter(JsonNamingPolicy.CamelCase),
new MyCustomConverter()
}
options.SerializerOptions.NumberHandling = JsonNumberHandling.AllowReadingFromString;
options.SerializerOptions.UnmappedMemberHandling = JsonUnmappedMemberHandling.Skip;
});

builder.Services
.AddControllers()
.AddJsonOptions(options =>
{
options.JsonSerializerOptions.PropertyNameCaseInsensitive = true;
options.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
options.JsonSerializerOptions.DictionaryKeyPolicy = JsonNamingPolicy.CamelCase;
options.JsonSerializerOptions.Converters = {
new JsonStringEnumConverter(JsonNamingPolicy.CamelCase),
new MyCustomConverter()
}
options.JsonSerializerOptions.NumberHandling = JsonNumberHandling.AllowReadingFromString;
options.JsonSerializerOptions.UnmappedMemberHandling = JsonUnmappedMemberHandling.Skip;
});

builder.Service.AddSingleton(sp =>
{
var serializerOptions = new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true;
PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
DictionaryKeyPolicy = JsonNamingPolicy.CamelCase;
Converters = {
new JsonStringEnumConverter(JsonNamingPolicy.CamelCase),
new MyCustomConverter()
}
NumberHandling = JsonNumberHandling.AllowReadingFromString;
UnmappedMemberHandling = JsonUnmappedMemberHandling.Skip;
};

return new CosmosClientBuilder(cosmosDbEndpoint, credential).WithCustomSerializer(
new CosmosSystemTextJsonSerializer(serializerOptions)
).Build();
});
```

As you can see, this can be very cumbersome and it is error-prone. If one changes, I need to make sure, that all of them change, so they stay the same everywhere. Even if you just have the two AspNet Configurations.

### API Proposal

I suggest to add a Merge Method to JsonSerializerOptions that mutates the options.

```csharp
namespace System.Text.Json;

public sealed partial class JsonSerializerOptions
{
public void Merge(JsonSerializerOptions optionsToMerge);
}
```

### API Usage

looking at the example above, I would than be able to do:
```cs
var builder = WebApplication.CreateBuilder(args);
var serializerOptions = new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true;
PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
DictionaryKeyPolicy = JsonNamingPolicy.CamelCase;
Converters = {
new JsonStringEnumConverter(JsonNamingPolicy.CamelCase),
new MyCustomConverter()
}
NumberHandling = JsonNumberHandling.AllowReadingFromString;
UnmappedMemberHandling = JsonUnmappedMemberHandling.Skip;
};

builder.Services.ConfigureHttpJsonOptions(options =>
{
options.SerializerOptions.Merge(serializerOptions);
});

builder.Services
.AddControllers()
.AddJsonOptions(options =>
{
options.JsonSerializerOptions.Merge(serializerOptions);
});

builder.Service.AddSingleton(
sp => new CosmosClientBuilder(cosmosDbEndpoint, credential)
.WithCustomSerializer(new CosmosSystemTextJsonSerializer(serializerOptions))
.Build());
```

### Alternative Designs

Alternatively names for Merge could be `SetFromProperties`, `Update`, I don't care much about the name, it is only important, that it mutates the options, because in the AspNet Configuration Apis, the options are not setable.

### Risks

I don't see any Risk with this, but there are others here, that have much better understanding of this all.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.