C# – Deserializing JSON results in object with null properties

Let’s say you have the following JSON:

{ "Name": "Bob", "Pets": 2 }
Code language: JSON / JSON with Comments (json)

When you go to deserialize it, you notice that all or some of its properties are null (or default for value types):

using System.Text.Json; var person = JsonSerializer.Deserialize<Person>(personJson); Console.WriteLine($"{person.Name} has {person.Pets} pet(s)");
Code language: C# (cs)

This outputs the following (because person.Name is null and person.Pets is 0):

has 0 pet(s)
Code language: plaintext (plaintext)

The data is definitely there, so why did it set these properties to null / default? There are a few possibilities:

The public setter requirement is kind of hidden, so it’s common to run into this problem accidently. You might’ve used Quick Actions to generate your properties, which automatically adds internal setters, leading to this null deserialization problem:

VS Quick Actions > Generate property automatically adds internal setters

Go into the class and change these to public setters instead:

public class Person { public string Name { get; set; } public int Pets { get; set; } }
Code language: C# (cs)

Now when you deserialize, it’ll populate the properties as expected and will output:

Bob has 2 pet(s)
Code language: plaintext (plaintext)

When the JSON field is missing

Besides name mismatches preventing the property from getting populated during deserialization, the JSON field could simply be missing.

At this time, there’s nothing in System.Text.Json that’ll help you detect that. However, you can use the [Required] model validation attribute if you’re running into this problem in ASP.NET Core. It’ll detect that the required property is null during model validation and return an error response.

Newtonsoft handles this scenario better. It provides two options: 1) Use MissingMemberHandling.Error and/or 2) Use [JsonRequired] on your properties. I’ll show examples below.

Newtonsoft – Use MissingMemberHandling.Error

When you set MissingMemberHandling.Error in JsonSerializerSettings, it’ll throw an exception during deserialization if a JSON field can’t be matched to a property:

using Newtonsoft.Json; var jsonSettings = new JsonSerializerSettings() { MissingMemberHandling = MissingMemberHandling.Error }; var person = JsonConvert.DeserializeObject<Person>(personJson, jsonSettings);
Code language: C# (cs)

Note: There’s an open issue about adding similar functionality to System.Text.Json. Hopefully this will get added.

This throws exceptions like this:

Newtonsoft.Json.JsonSerializationException: Could not find member ‘Name2’ on object of type ‘Person’.

Newtonsoft – Use [JsonRequired]

Add [JsonRequired] to your properties and it’ll throw an exception during deserialization if the property couldn’t be matched to a JSON field:

using Newtonsoft.Json; public class Person { [JsonRequired] public string Name { get; set; } [JsonRequired] public int Pets { get; set; } }
Code language: C# (cs)

It’ll throw an exception like this:

Newtonsoft.Json.JsonSerializationException: Required property ‘Name’ not found in JSON.

Leave a Comment