Search code examples
c#json.net

C# JsonConvert.DeserializeObject giving Null Value Exception even though I have NullValueHandling set to Ignore


My data looks like this, except there are 1000s of entities, not just 2.

{
    "1": {
        "id": 1,
        "name": "James",
        "last_updated": "2021-04-26",
        "incomplete": true,
        "valid": true,
        "start_date": "2007-03-20",
        "items": 51,
        "current": 1,
        "hitpoints": 52
    }
    "2": {
        "id": 2,
        "name": "Peter",
        "last_updated": "2021-04-25",
        "incomplete": true,
        "members": true,
        "start_date": "2009-06-13",
        "items": 51,
        "current": 1,
        "hitpoints": 52
    }
}

My code is like this:

try
{
    var settings = new JsonSerializerSettings
    {
        NullValueHandling = NullValueHandling.Ignore,
        MissingMemberHandling = MissingMemberHandling.Ignore
    };
    var dict = JsonConvert.DeserializeObject<Dictionary<string, Entry>>(json, settings);
}
catch (Exception e)
{
    Console.WriteLine(e.ToString()); 
}

This is the error I am getting:

Newtonsoft.Json.JsonSerializationException: Error converting value {null} to type 'System.Int32'. Path '455.hitpoints', line 1, position 1597602. ---> System.InvalidCastException: Null object cannot be converted to a value type. at System.Convert.ChangeType(Object value, Type conversionType, IFormatProvider provider) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.EnsureType(JsonReader reader, Object value, CultureInfo culture, JsonContract contract, Type targetType)

I have tried many different ways of doing this. Even put this above hitpoints in the declaration of the Entry class:

[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]

Here is the class:

public class Entry
{
    public Entry(int id_p, string name_p, string last_updated_p, bool incomplete_p, bool valid_p, string start_date_p, int items_p, int size_p, int hitpoints_p)
    {
        id = id_p;
        name = name_p;
        last_updated = last_updated_p;
        incomplete = incomplete_p;
        valid = valid_p;
        start_date = start_date_p;
        items = items_p;
        size = size_p;
        hitpoints = hitpoints_p;
    }
    
    public int  id                      { get; set; }
    public string   name                { get; set; }
    [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
    public string   last_updated        { get; set; }
    [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
    public bool     incomplete          { get; set; }
    public bool     valid               { get; set; }
    [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
    public string   start_date          { get; set; }
    [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
    public int  items                   { get; set; }
    [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
    public int  current                 { get; set; }
    [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
    public int  hitpoints               { get; set; }
    [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
}

Still doing the same thing. Any ideas?


Solution

  • Even though you did not provide class Entry, error says that your Hitpoint property is int, meaning, you cannot assign null value to it. You have to define Hitpoint as int?.

    class Entry
    {
        //...
        public int? Hitpoint {get; set; }
    
    }
    

    Update:

    Only string is already Nullable type in the Entry class you provided. For all bool and int properties that you want to be "optional", you should change type definition to bool? and int?.