0

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?

Nenad
  • 24,809
  • 11
  • 75
  • 93
TBowman
  • 615
  • 4
  • 15
  • 1
    How is `Entry` class defined? – Renat May 20 '21 at 20:03
  • 2
    Also, maybe it's pasting mistake, but your `[JsonProperty(...)]` should be before the property it relates to, not after. You have one "hanging" at the end. – Nenad May 20 '21 at 20:15
  • @Nenad correct, IMHO user should use `JsonSerializerSettings` along with the `NullValueHandling = NullValueHandling.Ignore` and get rid of the `[JsonProperty...]` altogether. – Trevor May 20 '21 at 20:17
  • 1
    The fact that `[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]` isn't working seems to be related to the fact that your `Entry` class has a **parameterized constructor**. Adding a default constructor solves the problem, see https://dotnetfiddle.net/AwIn0U. Kind of odd, and feels like a bug with Json.NET. – dbc May 20 '21 at 20:20

1 Answers1

2

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?.

Nenad
  • 24,809
  • 11
  • 75
  • 93
  • I will try that. Never saw that before on any answers or posts regarding null entries. Thanks! – TBowman May 20 '21 at 20:10
  • @TBowman - "convert your value type to nullable" is the accepted answer to [Newtonsoft Json Error converting value {null} to type 'System.Int32'](https://stackoverflow.com/q/41873274/3744182). What makes your question different is that `NullValueHandling = NullValueHandling.Ignore`, which is given as the alternate answer to the same question, is not working in your case. – dbc May 20 '21 at 20:26
  • @dbc Yes, I see that answer now. Strange how it did not come up in the long list of suggestions when I was framing my question. I actually had the title and my partially written question open for a good 30 minutes while I searched all of the suggested links that had the right keywords. That question and answer would have been a smart suggestion to give me. – TBowman May 20 '21 at 20:55