0

I have issues deserializing JSON in my c# code using the JavaScriptSerializer library.

Here is my sample JSON:

{"A":["a","b","c","d"],"B":["a"],"C":[]}

I am using a Dictionary to hold the JSON as follows:

Dictionary<string, List<string>> myObject;

This is how I parse the JSON and cast it to my object:

myObject= (Dictionary<string, List<string>>)jsc.DeserializeObject(json);

However, at runtime, the previous line throws a Casting exception as follows

Unable to cast object of type System.Collections.Generic.Dictionary2[System.String,System.Object] to type System.Collections.Generic.Dictionary2[System.String,System.Collections.Generic.List1[System.String]]

For some reason the JavaScriptSerializer cannot recognize the JSON Array having strings as a List<string>

UPDATE

I populated my Dictionary data structure with some hardcoded strings to see what is the serialized version. It turns out to be exactly what my input JSON string is.

3
  • What happens if you define myObject using var instead of explicitly as a Dictionary? Commented Nov 12, 2015 at 18:34
  • @Necoras That did not work either :( Commented Nov 12, 2015 at 20:28
  • @sjokkogutten has the right answer, but the error message does tell you why an exception is being thrown, the DeserializeObject method is returning a Dictionary<string,object> and you are then trying to cast it to Dictionary<string, List<string>>. Even if the generic types you are closing over can be casted, it doesn't meant he generic type itself can be. For instance, you can't cast IEnumerable<string> to IEnumerable<object>, even though string does inherit from object. Generics don't work that way. Commented Nov 12, 2015 at 21:09

3 Answers 3

2

Instead of using the DeserializeObject method, use the generic Deserialize<T> method and specify Dictionary<string, List<string>> as the type argument. Then it will work correctly:

string json = @"{""A"":[""a"",""b"",""c"",""d""],""B"":[""a""],""C"":[]}";

JavaScriptSerializer serializer = new JavaScriptSerializer();

Dictionary<string, List<string>> myObject = 
    serializer.Deserialize<Dictionary<string, List<string>>>(json);

foreach (KeyValuePair<string, List<string>> kvp in myObject)
{
    Console.WriteLine(kvp.Key + ": " + string.Join(",", kvp.Value));
}

Output:

A: a,b,c,d
B: a
C:
Sign up to request clarification or add additional context in comments.

2 Comments

This works!! Thanks! For some reason, I completely missed that method. I thought this was the same as JavaScriptSerializer.Deserialize Method (String, Type). Stupid me.
No problem; glad to help.
1

The problem is casting to a List<string> If casting to an object is acceptable, you could do it like this:

string json = "{\"A\":[\"a\",\"b\",\"c\",\"d\"],\"B\":[\"a\"],\"C\":[]}";
var serializer = new JavaScriptSerializer();
var deserializedValues = (Dictionary<string, object>)serializer.Deserialize(json, typeof(object));

I would also recommend looking into Json.NET which does a much better job at serializing/deserializing

1 Comment

You can even use the generic Deserialize method and specify the same type as you're looking for. That way you wouldn't have to do any casting in your code.
0

Create a Type based on the JSON structure and then use the Type in the Serialization or DeSerialization like this.

I create the RootObject from the JSON using functionality found in the Web Essentials Visual Studio Extension.

public class JSONSerializer
{
    public void RunIt()
    {
        string json = "{\"A\":[\"a\",\"b\",\"c\",\"d\"],\"B\":[\"a\"],\"C\":[]}";

        JavaScriptSerializer serializer = new System.Web.Script.Serialization.JavaScriptSerializer();

        Rootobject jsonObject = serializer.Deserialize<Rootobject>(json);

        Console.Write(serializer.Serialize(jsonObject));
    }
}

public class Rootobject
{
    public string[] A { get; set; }
    public string[] B { get; set; }
    public object[] C { get; set; }
}

1 Comment

I cannot use this method directly. I do not know the number of key/array pairs that will be present in the RootObject.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.