Parsing a JSON string is straightforward. You create an instance of the JavaScriptSerializer class and then call it’s Deserialize function to operate on the JSON string. You will get back a dictionary object of type Dictionary<string, object>. This dictionary can then be examined and referenced as you would any other dictionary object. But… it’s never as easy as you’d like.
JSON objects often contain arrays of embedded items and being able to access those child objects can take some extra handling. These child objects are often dictionary objects themselves, or possibly, arrays of dictionary objects.
Nonetheless, let’s dive in to parsing these objects (for the rest of the article, I will assume that you have some experience dealing with dictionary objects; if you need more information on working with dictionary objects, start here).
The code samples used below are included in a complete .NET application which you can download here: JSONExamples
The JSON samples can be downloaded here: http://json.org/example.html
Let’s get started
Let’s start with a sample JSON string (line breaks are added for clarity; they are not required for parsing):
{ "glossary": { "title": "example glossary", "GlossDiv": { "title": "S", "GlossList": { "GlossEntry": { "ID": "SGML", "SortAs": "SGML", "GlossTerm": "Standard Generalized Markup Language", "Acronym": "SGML", "Abbrev": "ISO 8879:1986", "GlossDef": { "para": "A meta-markup language, used to create markup languages such as DocBook.", "GlossSeeAlso": ["GML", "XML"] }, "GlossSee": "markup" } } } } }
As you can see, the glossary object contains a “title” and a “GlossDiv”. The “GlossDiv” contains a “title” and a “GlossList”, etc.
In this example, the top-level dictionary contains a single key, “glossary” and it’s corresponding value. Next, we have a dictionary with two keys: “title” and “GlossDiv”. “title” has a value of “example glossary” while “GlossDiv” points to yet another dictionary with one key, “GlossEntry”. And so on…
The first step, is to parse the entire string into the top level dictionary object. This is straightforward. Assume that the JSON string shown above has been assigned to a string variable:
string input = "{glossary:{. . . }}";
We then create an instance of the JavaScriptSerializer and call it’s Deserialize() function.
JavaScriptSerializer ser = new JavaScriptSerializer(); Dictionary dict = ser.Deserialize<Dictionary<string,object>>(input);
At this point, we have a dictionary that we can parse. How? Glad you asked. Below, is a complete function that you can use to parse any dictionary and display its contents to the screen. Since a dictionary can contain other dictionaries, it is designed to be called recursively.
The dictionary returned in the example above contains one key, “glossary”. If you want to get the value of “glossary”, you can simply request the value of “glossary”, like this:
object oValue = dict["glossary"];
In this specific example, the debugger tells us that oValue is of type “Dictionary<string,object>”.
So, if you want to see what’s included here, you can simply pass oValue back into our Parse function shown below.
So far, we’ve done nothing other than create/use a generic JSON parser. But with a little ingenuity, and good ole .NET we can create so much more!
One of the cool things about the JavaScriptSerializer class, is that when we deserialize a JSON string we specify the type of object we want to get back from the Deserialize function. In the example above, we Deserialized the JSON string specifying an expected type of “Dictionary<string, object>” which should work for any valid JSON object.
However, if you know the structure of the JSON string that you will be receiving, you can create a custom class to receive your JSON string directly from the parser.
What am I talking about? Check this out!
Let’s use a different JSON sample from the site referenced above:
{"menu": { "id": "file", "value": "File", "popup": { "menuitem": [ {"value": "New", "onclick": "CreateNewDoc()"}, {"value": "Open", "onclick": "OpenDoc()"}, {"value": "Close", "onclick": "CloseDoc()"} ] } } }
As you can see, this is a simple structure that can be used to create a menu. Let’s create a class to capture this JSON text all at once. Actually, we will use four classes to do this.
Here are the complete definition of these classes:
class jsonmenuwrapper { public jsonmenu menu { get; set; } } class jsonmenu { public string id {get;set;} public string value { get; set; } public jsonpopup popup { get; set; } } class jsonpopup { public jsonmenuitem[] menuitem {get;set;} } class jsonmenuitem { public string value { get; set;} public string onclick{get;set;} }
The entire structure is captured using the “jsonmenuwrapper” class with a single call to our JavaScriptSerializer class.
JavaScriptSerializer ser = new JavaScriptSerializer(); jsonmenuwrapper wrapper = ser.Deserialize<jsonmenuwrapper>(tbInput.Text);
That’s it! JavaScriptSerializer does all the hard work of populating all the objects and child objects specified in the JSON string. You are now free to handle your “jsonmenuwrapper” object using normal programming operations.
As easy as it was, there are some specific things that you should note. The name of the various class objects must match the key values in the JSON string. So the property named “menuitem” in the JSON string is represented by the “menuitem” variable in the jsonpopup class. Similarly, the “value” and “onclick” key values in the JSON string are represented by the “value” and “onclick” variables in the jsonmenuitem class.
So that is a quick-n-dirty on how to parse JSON strings using the JavaScriptSerializer class. As you can see, the process itself is straightforward and the challenge is being able to find the data you want/need in what could be a complex JSON object.
If you know the structure of your JSON objects, you can create custom .NET objects that will receive the output of the Deserialize operation directly (“automagically”). A little bit more work up front, but it will pay off greatly in the end.
I hope this helps give you some insights into parsing JSON objects with .NET JavaScriptSerializer class.
Parse Function
Here is the Parse function that I use to display the values from a Dictionary object:
private bool DisplayDictionary(Dictionary dict) { bool bSuccess = false; indentLevel++; foreach (string strKey in dict.Keys) { string strOutput = "".PadLeft(indentLevel * 8 ) + strKey + ":"; tbOutput.AppendText("rn" + strOutput); object o = dict[strKey]; if (o is Dictionary) { DisplayDictionary((Dictionary)o); } else if (o is ArrayList) { foreach (object oChild in ((ArrayList)o)) { if (oChild is string) { strOutput = ((string) oChild); tbOutput.AppendText(strOutput + ","); } else if (oChild is Dictionary) { DisplayDictionary((Dictionary)oChild); tbOutput.AppendText("rn"); } } } else { strOutput = o.ToString(); tbOutput.AppendText(strOutput); } } indentLevel--; return bSuccess; }
Other things to see here:
Thank you very much for taking the time to write this for our benefit.
You rock buddy!!!. Crisp n dead clear. Thanks
Nice! With custom .Net objects you write receiving output of deserialization, I found a webpage that shows how to use some .Net classes to get Facebook’s JSON-output of wall posts at http://www.virtualsecrets.com/graph-api-json-facebook-handler.html (interesting use of nesting classes within classes)
is there any support for .net 2.0 framework?
It appears that this is only supported in Framework 3.5 and newer. Here’s a link to MSDN:
This is a great explanation and example. Most of the other examples I have seen only show very simple json with a top level object and a few strings. Yours is a real world example with nested obects within arrays.
You have a nice and easy way of explaining things. This has saved me a lot of time.
Thanks.
I am glad that I was able to help!
Hi thank you for your post is really useful.
I was trying to do the same deserialized form my list of custom objects
List ListFilterControl = serializer.Deserialize<List>(jsonResponse);
I have a json generated when I serialize List ListFilterControl
the from my custom objects.
However the deserialize is not working. 🙁
If I deserialized to a dictionary it work properly
Dictionary DictListFilterControl = serializer.Deserialize<Dictionary>(jsonResponse);
Do you have any clue about what I am doing wrong
jsonResponse =
{
“ListFilterControl”: [{
“filterControlObject”: {
“DisplayFieldID”: “20”,
“ControlDisplayName”: “Country”,
“ControlType”: “TextBox”
}
},
{
“filterControlObject”: {
“DisplayFieldID”: “21”,
“ControlDisplayName”: “automobile”,
“ControlType”: “ComboBox”
}
}]
}
and my class is serialized is
public List ListFilterControl = new List();
The serialization is performed by the Web API so maybe there is the issue.
This tripped me up for a few minutes. I will discuss the details of the solution in a blog entry located here: https://www.tomasvera.com/2012/11/a-javascriptserializer-twist/ .
Thanks a lot Tom. I have found the JavaScriptSerializer to be just the ticket for consuming a JSON based API using a .net console application.
One thing I don’t understand is why it takes so many lines of code just to get to the json string. For example:
WebRequest request = WebRequest.Create("http://some/api/?get_some_json")
request.Method = "GET";
WebResponse response = request.GetResponse();
Stream thestream = response.GetResponseStream();
StreamReader thestreamreader = new StreamReader(thestream);
string the_json = thestreamreader.ReadToEnd();
This sure feels like a lot of steps just to get to the text of an HTTP response. Seems like the WebResponse object should have a simple method called “GetContents” or something like that as a shortcut. Oh well.
Thanks again for the JavascriptSerializer tips!
JDM
You are certainly right on that count. I seem to recall that during the first time using the HttpWebResponse object, I had the same thoughts. At this point, I don’t event think about it. Which is odd because I suspect that the response stream doesn’t support “seeking” so you would think that the “GetContents()” functionality would be a natural function to add.
Oh well, I suppose one could just write a wrapper class or library to provide the “GetContents()” functionality. Hmm… I think I hear opportunity knocking! 😉
Hi, If possible,
Can u Deserialize the below string:
{“alerts”:[{“id”:001,”description”:”Test description 1″},{“id”:002,”description”:”Test Description 2″}]}
Thanks
R@gun@th.S
Take a look at this update.
The number format is invalid. You cannot specify a number with leading zeros unless it is a single numeral before the decimal point in a floating-point number.
Try this instead:
{"alerts":[{"id":1,"description":"Test description 1"},{"id":2,"description":"Test Description 2"}]}
Good catch!! The JSON specification at the JSON website has the complete specification for JSON as well the original examples from which I built my code.
I think this is among the most vital information for
me. And i’m glad reading your article. But should remark on
some general things, The site style is great, the articles is really excellent : D.
Good job, cheers
Dear Tom,
Could you please help me to Deserialize this string:
“columns”: “code,name,created,updated,del_flag”
“data”:[
[“0000″,”111″,”aa”],
[“0000″,”111″,”aa”,”bb”],
[“0000″,”111″,”aa”,”bb”,”c”…],
….
]
Thanks
The text you provided is incorrect (there is a comma missing after the first line).
Regardless, it may help to think of the “data” as a collection within a collection. So your class could be as simple as a string (to hold the columns information), and an array of a collection of strings to hold your data.
Hi Tom,
Great post. It was really helpful. One thing to be added to this though is that the ability of the property variables which are created to handle nulls.
Although JSON String structure is mostly standard on the strings that I am handling, there are times when the a parent key does not have any value. This would mean that the data associated with nested class would not have its key or value present, in other words null. Typically this would not be a problem unless you have a property whose base value is not an object by default. For example, Keys with values of String data type would do just fine, since a String is an object which allows null by default. However, in case of integer, the private variable and the property has to be coded to allow null value; i.e.
Dim i as Integer?
instead ofDim i as Integer
.Thanks for this great tip!! It’s always good to get additional insight into possible “gotchas”.
Nice and easy to understand post..!!
Good job 🙂
That’s wonderful explanation, Thanks!!
Thanks for posting this. I have a reasonably complex JSON structure with arrays and nested elements. This method made quick work of deserializing it.
Great tutorial, immensely helpful!
I have a question though:
I have a field with the name “protected”. This is also a keyword in c#. How can i serialize this using this method?
Marcel, Thanks for stopping by.
Keywords are reserved. They should never be used as variable names.
However, there is a work-around.
Take a look at this article on the MSDN site that details how to deal with your situation. I think this is what you were looking for.
C# Keywords
-tomas
Thanks!
Unfortunately i cannot change the JSON i receive, but i worked around it now 🙂 Thanks again
It’s nice ,
But how to store result in array gets from nested json