JSON Introduction
Creating Dynamic JSON Objects
Dynamic Parsing
Serialization
Deserialization
JSON is a human-readable text format that is used primarily to transfer data over the Web. Since JSON is mainly used with web technologies, the topic of working with JSON is not usually included in typical beginner C# programming guides. However, JSON has become a very competitive alternative to XML for platform-independent data transfer. The goal of this chapter is to raise your awareness of JSON as an alternative and to serve as a reference in case you pursue some form of JSON development with C#.
JSON stands for JavaScript Object Notation, but this notation is not actually a subset of JavaScript. The JSON format is composed of name-value pairs, where the name is an identifying string and the value can be a numeric value, a string, a Boolean, an array, or a JSON object. JSON arrays are enclosed with square brackets. JSON objects are enclosed with curly braces (see Figure 21-1).
Figure 21-1 JSON sample
NOTE
JSON is not allowed to have comments, by design.
The library this book uses to manage JSON is Json.NET, which is one of the more popular C# libraries for this purpose. Json.NET is a third-party library that helps to automate JSON creation, parsing, and conversion to and from C# data objects.
Example 21-1 Adding a Json.NET Reference to Your Project
To include Json.NET in your project, you can download and install it from Visual Studio with the NuGet Package Manager. NuGet is a common interface for including third-party libraries in your .NET projects. To do this, select Tools | NuGet Package Manager | Manage NuGet Packages For Solution. Then, expand the Online node on the left of the dialog that appears (see Figure 21-2). In the search box on the right, enter Json.Net and press ENTER. Then, highlight the Json.Net listing and click the Install button. On completing these steps, a Newtonsoft.Json listing will appear in the References directory of your project. To use this library with the reference in your project, you will need to include the Newtonsoft.Json namespace in your code files.
Figure 21-2 NuGet Package Manager
With Json.NET, you can create JSON objects on-the-fly with the JObject class. The JObject class is flexible, because it allows you to create and query a JSON object without having to undergo the tedious process of converting an entire JSON container to a .NET type.
When creating JObject instances, use the dynamic type for your object so that you can modify the JSON object structure with flexibility while not having to worry about converting it to a .NET type. The dynamic type tells the compiler that the object’s type is not known until run time. Using a dynamic type with JSON objects gives you freedom to append properties or arrays to your object whenever you need to.
TIP
Since your JSON objects are created with string data, your Jobject instances in Visual Studio will not offer as much IntelliSense support for auto-complete or error checking as other .NET types. Because of this, you will need to be extra careful to spell your property names correctly when working with JSON objects.
Here is a sample dynamic JSON object declaration:
dynamic registrant = new JObject();
To create and add properties to the object, the Add() method receives the property name and value pair as a parameter:
registrant.Add(“FirstName”, “Ben”);
registrant.Add(“LastName”, “Wu”);
The JSON data generated from these instructions is
{ “FirstName”: “Ben”,
“LastName”: “Wu” }
If you prefer, instead of using the Add() method you can just make up property names and assign values to them without having to formally declare the property before:
dynamic registrant = new JObject();
registrant.FirstName = “Ben”;
registrant.LastName = “Wu”;
Arrays of similarly typed JSON objects can be created with help from the JArray class. This instruction declares an array named camps:
dynamic camps = new JArray();
Once the array is declared, objects can be created, initialized, and appended to the array with the Add() method of the JArray() class:
Then, the array can be attached to a parent JObject instance with a simple assignment. In this case, a Camps property is made up on-the-fly and the camps array reference is assigned to it:
registrant.Camps = camps;
After the array has been assigned to the parent object property, it is still possible to add a new object to the array with a reference to the parent object and the Add() method of the array property:
The JSON array that is generated with the previous series of instructions is referenced with the property name Camps:
Example 21-2 Creating a Complex JSON Object
This example creates a JSON object for storing summer camp details in a structure that is identical to the one displayed in Figure 21-1. The structure contains registrant properties at the parent level and a Camps array that stores multiple sets of Day and Lunch option properties.
This exercise gives you practice working with JObject and JArray classes.
1. Create the following structure with dynamic objects:
2. Output your JSON to verify your results.
Sometimes it is too time consuming to map JSON to .NET types, especially if you are working with a large JSON stream and you only need a small subset of data from it. A dynamic type allows you to store the JSON as an object that you can query without the overhead of a major conversion. A dynamic object can be initialized with a JSON string as a parameter in the JObject.Parse() method of the Newtonsoft.Json.Linq namespace:
dynamic jsonObject = JObject.Parse(strJson);
With a dynamic type, you can access the name properties of the JSON object by name:
string FirstName = jsonObject.FirstName;
To simplify parsing, you can also extract nested arrays from a much larger JSON object. Here, the Camps array is being extracted from a larger JSON structure into a separate dynamic object:
dynamic camps = jsonObject.Camps;
After isolating the array data, you can iterate through each object of the array with a foreach loop:
As you might expect, arrays are given a Count property and JSON objects and their properties within the array can also be referenced with a numeric index:
Example 21-3 Dynamic JSON Parsing
This example shows a complete view of how to create a dynamic JSON object and how to parse it without converting it to other .NET types. Using the summer camp JSON structure from Figure 21-1, we reference the FirstName and LastName at the parent level. The Camps array is extracted and parsed separately.
The output is
Name: Ben Wu
Aug. 2 Lunch: True
*null* Lunch: True
Serialization is the conversion of a C# data object to JSON. Conversion is really easy with Json.NET. Given the definition
and instantiation of an object such as Person,
we can pass this Person object to the JsonConvert.SerializeObject() method as a parameter to transform the data to JSON:
var json = JsonConvert.SerializeObject(person);
When we display the contents of the JSON that is generated, we get
{”FirstName”:”Ben”,”LastName”:”Wu”}
Example 21-4 Serializing JSON
This example shows how conversion to JSON can be done with a slightly more complex C# data object. In this case, a Registrant object stores data about a person in a children’s summer camp. The Registrant class stores information about the child’s name, age, and paid status. This class also contains a List of Camp objects that store days and lunch order status. When the C# classes are defined, all of the data within the registrant object is transformed to JSON with the JsonConvert.SerializeObject() method:
var json= JsonConvert.SerializeObject(registrant);
Here is the program:
Running this program generates the output shown earlier in Figure 21-1.
This exercise provides an opportunity to convert a C# data object to JSON through serialization.
1. Create a console application and include the following class declaration:
2. Create an object of this ShipLine class and assign values to the Name and Expertise properties.
3. Covert this object to JSON.
4. Display your JSON contents in the console window.
When generating JSON from a .NET object, you may wish to customize property names during serialization. You can do this by placing a JsonProperty attribute tag above the C# property to be customized. The attribute receives a PropertyName parameter that is the name used by the newly created JSON structure.
With this custom attribute name in place, the following code:
enables us to generate a JSON structure that uses the custom name instead of FirstName:
{”first_name”:”Ben”}
Deserialization of JSON is the conversion of JSON to a C# data object. With Json.NET this is done with the JsonConvert.DeserializeObject() method. This method receives the JSON object as a parameter and uses the parent type as the generic type:
Registrant r = JsonConvert.DeserializeObject<Registrant>(json);
Example 21-5 Deserializing JSON
To see how transforming JSON to a C# data object is done, start with Example 21-4 and replace Main() with the code that follows. This code takes a JSON string and converts it to a Registrant object with just one instruction.
Results from the query appear as follows:
Registrant: Ben Wu
Days Confirmed:
Day - Aug. 2 Lunch - True
As shown previously, you may map JSON properties to different C# property names during deserialization. You can do this with the help of the JsonProperty attribute and its PropertyName parameter. If a C# property declaration has a JsonProperty attribute as shown here:
A JSON property name that is the same as the PropertyName parameter will be mapped to the corresponding C# property:
The following questions are intended to help reinforce your comprehension of the concepts covered in this chapter. The answers can be found in the accompanying online Appendix B, “Answers to the Self Tests.”
1. For each of the JSON strings, indicate if the Prices property references an object or an array:
A. ”Prices”: {”Tall”: 2.95,”Grande”: 3.65,”Venti”: 4.15}
B. {”Prices”:[{”Price”:1.95},{”Price”:2.95},{”Price”:3.95}]}
A. Build the following JSON structure with the JObject and JArray classes without creating C# types:
B. Output your JSON data in its entirety to verify the correctness of your structure.
C. Output the data using properties of the JSON structure so the output appears exactly as
Coffee Prices
Tall: $1.95 Grande: $2.55 Venti: $2.95
Frappucino Prices
Tall: $2.95 Grande: $3.65 Venti: $4.15
D. Create a representation of the JSON structure in C#. Use the JsonConvert .DeserializeObject() method to convert the JSON string into a C# object. To use the DeserializeObject() method, you will need to first convert your JSON to a string. Then use the string as a parameter in the DeserializeObject() method. Your instructions could look like the following:
string json = JsonConvert.SerializeObject(beverages);
Menu drinks = JsonConvert.DeserializeObject<Menu>(json);
3. Design the C# classes needed to create the structure that is represented in question 1B. Populate your parent object with the same data and show it.