2

Unable to cast to int from deserialized json (dictionary object)

Here is the code:

Lets say you have dictionary object.

 Dictionary<string, object> dict = new Dictionary<string, object>();
 dict.Add("key", 1);

Now i serialize & deserialize it.

var serializedData = JsonConvert.SerializeObject(dict);
var deserializedData = JsonConvert.DeserializeObject<Dictionary<string, object>>(serializedData);

And getting error when i do this at runtime

int value = (int)deserializedData["key"];
Mohit Verma
  • 1,620
  • 2
  • 20
  • 30

3 Answers3

3

I believe the error is that JSON.NET assuming the number you mentioned is of type long (int64) not integer (int32) , thus when you do boxing to object you just can't unbox it to int32 directly , thus you need to change your code

 int i = (int)(long) deserializedData["key"];
Coder1409
  • 523
  • 4
  • 12
  • It's not the compiler; it's a run-time exception. The deserializer is creating a long value when it deserializes the number from json. – phoog May 27 '15 at 09:27
  • Yeah I agree with you, Json.NET can't know which type to take so it takes the biggest – Coder1409 May 27 '15 at 09:28
2

Your number is being serialized as a long (Int64). Try this:

int value = (int)(long)deserializedData["key"];

You have to unbox the long first and then convert it to an int after it has been unboxed. This makes more sense if you convert the above to separate statements:

object oValue = deserializedData["key"];
long longValue = (long)oValue;
int value = (int)longValue;
phoog
  • 42,068
  • 6
  • 79
  • 117
1

Because the type of deserializedData["key"] is Int64 (you'll see when you debug). You can't cast Int64 to int (Int32) .

what you can do:

int value = System.Convert.ToInt32(deserializedData["key"]);
stefankmitph
  • 3,236
  • 2
  • 18
  • 22
  • Is it Json.net feature to convert it into Int64. – Mohit Verma May 27 '15 at 09:21
  • according to [this](http://stackoverflow.com/questions/8297541/how-do-i-change-the-default-type-for-numeric-deserialization) answer: _Json.NET by default reads integer values as Int64 because there is no way to know whether the value should be Int32 or Int64, and Int64 is less likely to overflow. For a typed property the deserializer knows to convert the Int64 to a Int32 but because your property is untyped you are getting an Int64. [...] It is just the way Json.NET has to work._ – stefankmitph May 27 '15 at 09:24
  • @stefankmitph `int.Parse(someBoxedLong.ToString())` is just about the most inefficient way to do this. `(int)(long)someBoxedLong` is much better. – phoog May 27 '15 at 09:26
  • @phoog fair enough, mate. but if you don't know the exact type of your object (in that case Int64), you'd better go for int.Parse, don't you? – stefankmitph May 27 '15 at 09:28
  • @stefankmitph no, in that case, you should use the System.Convert class. It will test the runtime type of the boxed object and convert it efficiently, without going through the string representation. – phoog May 27 '15 at 09:31
  • or simply we can cast to long – Mohit Verma May 27 '15 at 09:33
  • @phoog you're right. edited my answer. this is the way to go. – stefankmitph May 27 '15 at 09:34