[My original article concerning parsing JSON strings using the .NET JavaScriptSerializer class dealt with JSON objects used in creating a Facebook App. That article was more confusing than helpful. So, I’ve updated this article to focus on creating a JSON parser that parses generic JSON strings using the JavaScriptSerializer class.]
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: http://www.tomasvera.com/JSONExamples.zip
The JSON samples can be downloaded here: http://json.org/example.html
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("\r\n" + 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("\r\n");
}
}
}
else
{
strOutput = o.ToString();
tbOutput.AppendText(strOutput);
}
}
indentLevel--;
return bSuccess;
}
You rock buddy!!!. Crisp n dead clear. Thanks
Thank you very much for taking the time to write this for our benefit.