Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Why is deserializing this JSON resulting in `null`?

I have the following JSON:

{
    "countries": [
        {
            "name": "Afghanistan",
            "alternative_names": [],
            "formal_name": "Islamic Republic of Afghanistan",
            "the_prefix": false,
            "in_un": true
        }
    ]
}

The following classes:

[Serializable]
    public class CountriesData
    {
        public List<CountryData> countries;
    }

[Serializable]
    public class CountryData
    {
        /// <summary>
        /// The informal name of the country.
        /// <example>
        /// E.g. China
        /// </example>
        /// </summary>
        public string name;

        /// <summary>
        /// A <c>List<string></c> containing other informal names for the country.
        /// <example>
        /// E.g. for Myanmar, an alternative name is Burma.
        /// </example>
        /// </summary>

        public List<string> alternative_names;
        /// <summary>
        /// The formal name of the country.
        /// <example>
        /// E.g. People's Republic of China
        /// </example>
        /// </summary>
        public string formal_name;

        /// <summary>
        /// Should the word "the" come before this country's informal name?
        /// <example>
        /// E.g. for China, Spain, France, no. For (the) Gambia, (the) United Kingdom, (the) United States of America, yes.
        /// </example>
        /// </summary>
        public bool the_prefix;

        /// <summary>
        /// Is this country a UN member state?
        /// <example>
        /// E.g. for China, Spain, France, yes. For Kosovo, no.
        /// </example>
        /// </summary>
        public bool in_un;
    }

and I am running the line of code:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

CountriesData data = JsonSerializer.Deserialize<CountriesData>(jsonString);

This is resulting in null. I have tested and the string jsonString does correctly contain above JSON as a string. No matter what I have tried, this always returns null.

I am getting the warning Warning CS8601 Possible null reference assignment. on this line of code.

Why is this not deserializing properly?

>Solution :

I’ll explain using the code from this Fiddle:

Your model classes contain public fields. Fields are by default ignored in serialization/deserialization.


By default, fields are ignored.

Citation from Serialization behavior

Instead, use properties (easiest method) as shown in the code below. You can force serialization of fields, though if you so absolutely want.

A second factor is naming:

The recommended naming in json and C# differ. There are different ways to mitigate that. One of those is shown in below code: you can specify a name that is used in json that is supposed to be mapped to a specific property.

using System;
using System.Collections.Generic;
using System.Text.Json;
using System.Text.Json.Serialization;
                    
public class Program
{
    public static void Main()
    {
        var jsonString = @"
        {
    ""countries"": [
        {
            ""name"": ""NonControversialNationName"",
            ""alternative_names"": [],
            ""formal_name"": ""NonControversial Republic of NonControversistan"",
            ""the_prefix"": false,
            ""in_un"": true
        }
    ]
}
        ";
        
        var obj = JsonSerializer.Deserialize<CountriesData>(jsonString);
        obj.Dump();
    }
}

public class CountriesData
{
    [JsonPropertyName("countries")]
    public List<CountryData> Countries {get; set;}
}

public class CountryData
{
    [JsonPropertyName("name")]
    public string Name {get; set;}
    [JsonPropertyName("alternative_names")]
    public List<string> AlternativeNames {get; set;}
    [JsonPropertyName("formal_name")]
    public string FormalName {get; set;}
    [JsonPropertyName("the_prefix")]
    public bool Prefix {get; set;}
    [JsonPropertyName("in_un")]
    public bool IsUnMember {get; set;}
}

Output:

Dumping object(CountriesData)
 Countries  : [
             {
             AlternativeNames  : []
             FormalName        : NonControversial Republic of NonControversistan
             IsUnMember        : True
             Name              : NonControversialNationName
             Prefix            : False
   }
]

About that CS8601 Warning: That depends if you are in a Nullable enabled environment.

You probably might need to use CountriesData? data = JsonSerializer.Deserialize<CountriesData>(jsonString); (mind the "?")

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading