'Newtonsoft Json Error converting value {null} to type 'System.Int32'

When performing an AJAX request I am getting the following error:

Error converting value {null} to type 'System.Int32'. Path '[5].tabID', line 1, position 331.

The error occurs on the second line of my processRequest (...)

public void ProcessRequest (HttpContext context) { 
    string strJson = new StreamReader(context.Request.InputStream).ReadToEnd();
    List<ElementToUpdate> elements = JsonConvert.DeserializeObject<List<ElementToUpdate>>(strJson);

    // (...)
}

The debugger says that this the content of strJson:

[{
    "bmk": "132M1",
    "state": "off",
    "type": "motor",
    "tabID": 8
}, {
    "bmk": "158M1",
    "state": "off",
    "type": "motor",
    "tabID": 8
}, {
    "bmk": "194M1",
    "state": "off",
    "type": "motor",
    "tabID": 8
}, {
    "bmk": "198M1",
    "state": "on",
    "type": "motor",
    "tabID": 8
}, {
    "bmk": "202M1",
    "state": "off",
    "type": "motor",
    "tabID": 8
}, {
    "bmk": "test-m",
    "state": "on",
    "type": "motor",
    "tabID": null
}, {
    "bmk": "158M1-2",
    "state": "off",
    "type": "motor",
    "tabID": 2
}, {
    "bmk": "100M1",
    "state": "on_right",
    "type": "screwconveyor",
    "tabID": 8
}, {
    "bmk": "152M1",
    "state": "on",
    "type": "screwconveyor",
    "tabID": 8
}, {
    "bmk": "192M1",
    "state": "on_left",
    "type": "screwconveyor",
    "tabID": 8
}, {
    "bmk": "196M1",
    "state": "off",
    "type": "screwconveyor",
    "tabID": 8
}, {
    "bmk": "2000M1",
    "state": "on_left",
    "type": "screwconveyor",
    "tabID": 8
}, {
    "bmk": "74M1",
    "state": "off",
    "type": "screwconveyor",
    "tabID": 8
}, {
    "bmk": "76M1",
    "state": "off",
    "type": "screwconveyor",
    "tabID": 8
}, {
    "bmk": "80M1",
    "state": "off",
    "type": "screwconveyor",
    "tabID": 8
}, {
    "bmk": "82M1",
    "state": "off",
    "type": "screwconveyor",
    "tabID": 8
}, {
    "bmk": "86M1",
    "state": "off",
    "type": "screwconveyor",
    "tabID": 8
}, {
    "bmk": "90M1",
    "state": "off",
    "type": "screwconveyor",
    "tabID": 8
}, {
    "bmk": "94M1",
    "state": "off",
    "type": "screwconveyor",
    "tabID": 8
}, {
    "bmk": "95M1",
    "state": "off",
    "type": "screwconveyor",
    "tabID": 8
}, {
    "bmk": "96M1",
    "state": "off",
    "type": "screwconveyor",
    "tabID": 8
}, {
    "bmk": "102Y1",
    "state": "closed",
    "type": "ventile",
    "tabID": 8
}, {
    "bmk": "104Y1",
    "state": "open",
    "type": "ventile",
    "tabID": 8
}, {
    "bmk": "112Y2",
    "state": "closed",
    "type": "ventile",
    "tabID": 8
}, {
    "bmk": "114Y2",
    "state": "closed",
    "type": "ventile",
    "tabID": 8
}, {
    "bmk": "120Y1",
    "state": "closed",
    "type": "ventile",
    "tabID": 8
}, {
    "bmk": "122Y1",
    "state": "closed",
    "type": "ventile",
    "tabID": 8
}, {
    "bmk": "128Y2",
    "state": "closed",
    "type": "ventile",
    "tabID": 8
}, {
    "bmk": "146Y1_2",
    "state": "closed",
    "type": "ventile",
    "tabID": 8
}, {
    "bmk": "148Y2",
    "state": "closed",
    "type": "ventile",
    "tabID": 8
}, {
    "bmk": "156Y1",
    "state": "closed",
    "type": "ventile",
    "tabID": 8
}, {
    "bmk": "180Y1",
    "state": "open",
    "type": "ventile",
    "tabID": 8
}, {
    "bmk": "182Y1",
    "state": "closed",
    "type": "ventile",
    "tabID": 8
}, {
    "bmk": "184Y1",
    "state": "open",
    "type": "ventile",
    "tabID": 8
}, {
    "bmk": "206Y1",
    "state": "open",
    "type": "ventile",
    "tabID": 8
}, {
    "bmk": "208Y1",
    "state": "closed",
    "type": "ventile",
    "tabID": 8
}, {
    "bmk": "72Y2",
    "state": "closed",
    "type": "ventile",
    "tabID": 8
}, {
    "bmk": "78Y2",
    "state": "open",
    "type": "ventile",
    "tabID": 8
}, {
    "bmk": "84Y2",
    "state": "closed",
    "type": "ventile",
    "tabID": 8
}, {
    "bmk": "88Y2",
    "state": "closed",
    "type": "ventile",
    "tabID": 8
}, {
    "bmk": "92Y2",
    "state": "closed",
    "type": "ventile",
    "tabID": 8
}, {
    "bmk": "95_1Y1",
    "state": "blocked",
    "type": "ventile",
    "tabID": 8
}, {
    "bmk": "17H1",
    "state": "on",
    "type": "lamp",
    "tabID": 8
}, {
    "bmk": "l1",
    "state": "on",
    "type": "lamp",
    "tabID": 8
}, {
    "bmk": "17H1-2",
    "state": "on",
    "type": "lamp",
    "tabID": 2
}, {
    "bmk": "106M1",
    "state": "on",
    "type": "elevator",
    "tabID": 8
}, {
    "bmk": "154M1",
    "state": "off",
    "type": "elevator",
    "tabID": 8
}, {
    "bmk": "164M1",
    "state": "off",
    "type": "rotaryvalve",
    "tabID": 8
}]

The class ElementToUpdate is

public class ElementToUpdate
{
public ElementType type;
public String bmk;
public string state;
public int tabID;

public ElementToUpdate()
{
}

public ElementToUpdate(ElementType type, String bmk, string state, int tabID)
{
    this.type = type;
    this.bmk = bmk;
    this.state = state;
    this.tabID = tabID;
}
}

So my question is: How to resolve this issue? If I understand the error message correctly, then it says that tabID of the 5th json object in the serialized array is null. But as you can see it isn't. Moreover ElementToUpdate.tabID isn't an Int32 but an int. Did I miss something?

The solution

In fact, my JSON string contained an element whose tabID was null. I somehow overlooked this because firstly my JSON string wasn't formatted when I checked and secondly because [5] means "6th element of the array" (which I claimed to know actually).



Solution 1:[1]

Make your tabID nullable:

public int? tabID;

Value null could not be deserialized to integer. That's your 6-th part of json (or 5-th starting with 0):

{\"bmk\":\"test-m\",\"state\":\"on\",\"type\":\"motor\",\"tabID\":null}

You could see, that tabID is null there.

Solution 2:[2]

Depending on your use case, you may also want to consider having the JSON Serializer ignore nulls

Example:

Movie movie = new Movie();
movie.Name = "Bad Boys III";
movie.Description = "It's no Bad Boys";

string included = JsonConvert.SerializeObject(movie,
    Formatting.Indented,
    new JsonSerializerSettings { });

// {
//   "Name": "Bad Boys III",
//   "Description": "It's no Bad Boys",
//   "Classification": null,
//   "Studio": null,
//   "ReleaseDate": null,
//   "ReleaseCountries": null
// }

string ignored = JsonConvert.SerializeObject(movie,
    Formatting.Indented,
    new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });

// {
//   "Name": "Bad Boys III",
//   "Description": "It's no Bad Boys"
// }

Solution 3:[3]

In my case there was problem with constructor definition. I had

public int? tabID { get; }

public Temp(int tabID)
{
   this.tabID = tabID;
}

I had to fix the constructor definition to

public Temp(int? tabID)...

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Mat
Solution 3 pawellipowczan