CathalMF
CathalMF

Reputation: 10055

JSON.NET Case Insensitive Deserialization not working

I need to deserialize some JSON into my object where the casing of the JSON is unknown/inconsistent. JSON.NET is supposed to be case insensitive but it not working for me.

My class definition:

public class MyRootNode
{
    public string Action {get;set;}
    public MyData Data {get;set;}
}

public class MyData
{
    public string Name {get;set;}
}

The JSON I receive has Action & Data in lowercase and has the correct casing for MyRootNode.

I'm using this to deserialize:

MyRootNode ResponseObject = JsonConvert.DeserializeObject<MyRootnode>(JsonString);

It returns to be an initialised MyRootNode but the Action and Data properties are null.

Any ideas?

EDIT: Added JSON

{
   "MyRootNode":{
      "action":"PACT",
      "myData":{
         "name":"jimmy"
      }
   }
}

Upvotes: 20

Views: 38921

Answers (3)

Ziaullah Khan
Ziaullah Khan

Reputation: 2244

This is the .NET Core built-in JSON library.

I found another way of doing it.. just in case, somebody is still looking for a cleaner way of doing it. Assume there exists a Movie class

    using System.Text.Json;

. . .

    var movies = await JsonSerializer.DeserializeAsync
        <IEnumerable<Movie>>(responseStream,
        new JsonSerializerOptions
        {
            PropertyNameCaseInsensitive = true
        });

Startup Options:

You can also configure at the time of application startup using the below extension method.

    public void ConfigureServices(IServiceCollection services)
    {

        services.AddControllers()
            .AddJsonOptions(
                x =>
                {
                    x.JsonSerializerOptions.PropertyNameCaseInsensitive = true;
                });
    }

Upvotes: 35

mjwills
mjwills

Reputation: 23975

You need to add an additional class:

public class MyRootNodeWrapper
{
    public MyRootNode MyRootNode {get;set;}
}

and then use:

MyRootNodeWrapperResponseObject = JsonConvert.DeserializeObject<MyRootNodeWrapper>(JsonString);

https://stackoverflow.com/a/45384366/34092 may be worth a read. It is basically the same scenario.

Also, change:

public MyData Data {get;set;}

to:

public MyData MyData {get;set;}

as per advice from @demo and @Guy .

Upvotes: 3

demo
demo

Reputation: 6235

Simply add JsonProperty attribute and set jsonProperty name

public class MyRootNode
{
    [JsonProperty(PropertyName = "action")]
    public string Action {get;set;}
    [JsonProperty(PropertyName = "myData")]
    public MyData Data {get;set;}
}

public class MyData
{
    [JsonProperty(PropertyName = "name")]
    public string Name {get;set;}
}

UPD: and yes, add some base type as @mjwills suggest

Upvotes: 5

Related Questions