132

In ASP.NET Core 3.0 Web API project, how do you specify System.Text.Json serialization options to serialize/deserialize Pascal Case properties to Camel Case and vice versa automatically?

Given a model with Pascal Case properties such as:

public class Person
{
    public string Firstname { get; set; }
    public string Lastname { get; set; }
}

And code to use System.Text.Json to deserialize a JSON string to type of Person class:

var json = "{\"firstname\":\"John\",\"lastname\":\"Smith\"}";
var person = JsonSerializer.Deserialize<Person>(json);

Does not successfully deserialize unless JsonPropertyName is used with each property like:

public class Person
{
    [JsonPropertyName("firstname")]
    public string Firstname { get; set; }
    [JsonPropertyName("lastname")]
    public string Lastname { get; set; }
}

I tried the following in startup.cs, but it did not help in terms of still needing JsonPropertyName:

services.AddMvc().AddJsonOptions(options =>
{
    options.JsonSerializerOptions.DictionaryKeyPolicy = JsonNamingPolicy.CamelCase;
    options.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
});

// also the following given it's a Web API project

services.AddControllers().AddJsonOptions(options => {
    options.JsonSerializerOptions.DictionaryKeyPolicy = JsonNamingPolicy.CamelCase;
    options.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
        });

How can you set Camel Case serialize/deserialize in ASP.NET Core 3.0 using the new System.Text.Json namespace?

Thanks!

Ian Kemp
  • 28,293
  • 19
  • 112
  • 138
Alexander Staroselsky
  • 37,209
  • 15
  • 79
  • 91

7 Answers7

145

AddJsonOptions() would config System.Text.Json only for MVC. If you want to use JsonSerializer in your own code you should pass the config to it.

var options = new JsonSerializerOptions
{
    PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
};

var json = "{\"firstname\":\"John\",\"lastname\":\"Smith\"}";
var person = JsonSerializer.Parse<Person>(json, options);
Kahbazi
  • 14,331
  • 3
  • 45
  • 76
  • 9
    There is no way to specify serialization options for the entire project/application with System.Text.Json? This was trivial before System.Text.Json – Alexander Staroselsky Oct 20 '19 at 19:56
  • I don't think so. You need to pass the settings – Kahbazi Oct 20 '19 at 20:03
  • 5
    @AlexanderStaroselsky - no, see [Is There A Way To Globally Set Default Options For System.Text.Json.JsonSerializer?](https://stackoverflow.com/q/58331479/3744182). – dbc Oct 20 '19 at 20:21
  • 1
    [This is possible with Json.Net](https://stackoverflow.com/a/16439024/542251) – Liam Aug 20 '20 at 12:35
  • 1
    JsonSerializer does not contain property called Parse ??? – Sujoy Feb 10 '23 at 15:09
  • See this link if you need something outside the "built in" ones (like JsonNamingPolicy.CamelCase) : https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json/customize-properties?pivots=dotnet-core-3-1#use-a-custom-json-property-naming-policy Note, the JsonNamingPolicy can be applied to the json-ELEMENT-names and/or the json-VALUES. – granadaCoder Feb 17 '23 at 16:06
61

If you want camelCase serialization use this code in Startup.cs: (for example firstName)

services.AddControllers()
        .AddJsonOptions(options =>
        {
            options.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
        });

If you want PascalCase serialization use this code in Startup.cs: (for example FirstName)

services.AddControllers()
        .AddJsonOptions(options =>
        {
            options.JsonSerializerOptions.PropertyNamingPolicy= null;
        );
Piotr Kula
  • 9,597
  • 8
  • 59
  • 85
Ramil Aliyev 007
  • 4,437
  • 2
  • 31
  • 47
  • Setting `PropertyNamingPolicy` to `null` resolved it. I first tried removing the line altogether (it was camelCase before), but that does not work - you need to set it to null =) – Ted Aug 22 '23 at 19:19
54

In startup.cs:

// keeps the casing to that of the model when serializing to json
// (default is converting to camelCase)
services.AddMvc()
    .AddJsonOptions(options => options.JsonSerializerOptions.PropertyNamingPolicy = null); 

This means you don't need to import newtonsoft.json.

The only other option for options.JsonSerializerOptions.PropertyNamingPolicy is JsonNamingPolicy.CamelCase. There do not seem to be any other JsonNamingPolicy naming policy options, such as snake_case or PascalCase.

sutherlandahoy
  • 1,395
  • 1
  • 12
  • 24
  • This worked for me. FTR, I didn't have .AddMvc() in my services before this, only adding it so AddJsonOptions could be added. All my server-client serialisation issues went away..... – Mark Lazarides Mar 05 '20 at 16:03
24

You can use PropertyNameCaseInsensitive. You need to pass it as a parameter to the deserializer.

var json = "{\"firstname\":\"John\",\"lastname\":\"Smith\"}";
var options = new JsonSerializerOptions() { PropertyNameCaseInsensitive = true };
var person = JsonSerializer.Deserialize<Person>(json, options);

which (from the docs):

Gets or sets a value that determines whether a property's name uses a case-insensitive comparison during deserialization. The default value is false

So, it doesn't specify camelCase or PascalCase but it will use case-insensitive comparison.


The below will configure System.Text.Json for Json passed through a controller endpoint:

services.AddControllers()
        .AddJsonOptions(options => {
            options.JsonSerializerOptions.PropertyNameCaseInsensitive = true;
         }); 
haldo
  • 14,512
  • 5
  • 46
  • 52
  • 7
    FYI: `PropertyNameCaseInsensitive` is only for incoming JSON. ` options.JsonSerializerOptions.PropertyNamingPolicy= null;` will serialise outgoing JSON PascalCase – Piotr Kula May 12 '20 at 20:19
  • 2
    What @PiotrKula says is true... PropertyNameCaseInsensitive is only used on incoming JSON payloads, but in addition to PropertyNamingPolicy dictating the rules on outgoing JSON payload creation during serialization, it ALSO expects that incoming payloads will mach the policy on deserialization; if it does not, your deserialization class members will have default values - this where PropertyNameCaseInsensitive fills the gap, it will allow deserialization to succeed regardless the incoming payload casing. – PillowMetal Jul 13 '20 at 21:12
13

You can still set it application wide by installing Microsoft.AspNetCore.Mvc.NewtonsoftJson Nuget Package, which allows you to use the previous Json serializer implementation :

services.AddControllers()
        .AddNewtonsoftJson(options =>
        {
            options.SerializerSettings.ContractResolver = new DefaultContractResolver();
        });

Credits to Poke, answer found here : Where did IMvcBuilder AddJsonOptions go in .Net Core 3.0?

Ramil Aliyev 007
  • 4,437
  • 2
  • 31
  • 47
6

.NET Core 7 Minimal API solution

To prevent pascal case properties from being renamed to camel case during serialization, use the ConfigureHttpJsonOptions method of the builder's service property.

builder.Services.ConfigureHttpJsonOptions(options => options.SerializerOptions.PropertyNamingPolicy = null);

To force conversion to camel case (default behavior), use:

builder.Services.ConfigureHttpJsonOptions(options => options.SerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase);
Dave
  • 2,774
  • 4
  • 36
  • 52
2

Try this!

In StartUp.cs inside the ConfigureServices method write:

 services.AddMvc()
                    .AddJsonOptions(options =>
                    options.JsonSerializerOptions.PropertyNamingPolicy
                     = JsonNamingPolicy.CamelCase);

You need namespaces such as Newtonsoft.Json.Serialization & System.Text.Json

Mazz Ebra
  • 119
  • 1
  • 7