Search code examples
c#.netjsonrestjavascriptserializer

Deserialize JSON Web Response in C#


I am working with a REST API and getting an HTTP response in JSON format. The JSON string contains an object as the first and only "top-level" or "root-level" key with an array of objects as its value.

Ultimately, I need to pass each of the objects in the array to a SQL query, which I intend to do by creating a List and iterating over the List with a foreach loop.

Here's a sample of the JSON response:

{
    "blueplates": [
        {
            "Appetizer": 26,
            "Salad": 21,
            "Soup": "SheCrab",
            "Entree": 6434,
            "Side": 2303093,
            "Desert": 0,
            "Beverage": "Sweet Tea + SoCo"
        },
        {
            "Appetizer": 27,
            "Salad": 21,
            "Soup": "Tomato Bisque",
            "Entree": 6434,
            "Side": 2303093,
            "Desert": 0,
            "Beverage": "Lemonade + Rum"
        },
        {
            "Appetizer": 28,
            "Salad": 21,
            "Soup": "Peanut",
            "Entree": 6434,
            "Side": 2303093,
            "Desert": 0,
            "Beverage": "Ginger Ale + Whiskey"
        }
    ]
}

The approach that I am taking is to create two classes (consistent with the result that I've gotten from http://json2csharp.com/) - a RootObject class and a Blueplate class.

The classes are structured like so:

public class Blueplate
{
    public int Appetizer { get; set; }
    public int Salad { get; set; }
    public string Soup { get; set; }
    public int Entree { get; set; }
    public int Side { get; set; }
    public int Desert { get; set; }
    public string Beverage { get; set; }
}

public class RootObject
{
    public List<Blueplate> blueplates { get; set; }              
}

I am using the JavaScriptSerializer class from the System.Web namespace. I've tried to manually re-format the JSON in order to validate my basic usage of JavaScriptSerializer, so the following code compiles and writes the value of the "Appetizer" key to the console, awaiting keyboard input after each value is displayed:

 var response = "[{\"Appetizer\":26,\"Salad\":21,\"Soup\":\"SheCrab\",\"Entree\":6434,\"Side\":2303093,\"Desert\":0,\"Beverage\":\"Sweet Tea + SoCO\"}, {\"Appetizer\":27,\"Salad\":21,\"Soup\":\"Tomato Bisque\",\"Entree\":6434,\"Side\":2303093,\"Desert\":0,\"Beverage\":\"Lemonade + Rum\"}, {\"Appetizer\":28,\"Salad\":21,\"Soup\":\"Peanut\",\"Entree\":6434,\"Side\":2303093,\"Desert\":0,\"Beverage\":\"Ginger Ale + Whiskey\"}]";

        JavaScriptSerializer deSerializedResponse = new JavaScriptSerializer();
        List<Blueplate> blueplates = (List<Blueplate>)deSerializedResponse.Deserialize(response, typeof(List<Blueplate>));

            for (int i = 0; i < blueplates.Count; i++)
            {
                Console.WriteLine(blueplates[i].Appetizer);
                Console.ReadLine();

            }

The problem that I am having is dealing with the root tag and making use of the RootObject class.

I've tried using variations of statements like the following, along with variations of for and foreach loops:

RootObject rootObject = (RootObject) deSerializedResponse.Deserialize(response, typeof(RootObject));

Apparently, I am confused on several points:

  • Mapping the root JSON object to the C# RootObject class
  • Mapping the objects in the root JSON object's array value to the C# Blueplate class, OR
  • Mapping the objects in the root JSON object's array value to the blueplates property of the RootObject class
  • Enumerating and looping over the blueplates property of the RootObject class
  • Casting or converting the object type returned by the Deserialize method as a List of Blueplate objects

Finally, please note that I wish to use native Microsoft assemblies, rather than third-party packages like JSON.NET. I understand that JSON.NET may perform better, and I've read a number of posts that emphasize JSON.NET's ease of use. If you would insist on JSON.NET, please enlighten on me how JSON.NET is handling the root object.

Still, the accepted answer will address a native solution. The question is: how can I use the native Microsoft class JavaScriptSerializer to deserialize a JSON response with a root object that has an array of objects as its value, where the target values are the objects in the array, to pass a List to a SQL query?


Solution

  • The first Json does work with my test:

    Edit: changed to foreach.

        var response = "{blueplates :[{\"Appetizer\":26,\"Salad\":21,\"Soup\":\"SheCrab\",\"Entree\":6434,\"Side\":2303093,\"Desert\":0,\"Beverage\":\"Sweet Tea + SoCO\"}, {\"Appetizer\":27,\"Salad\":21,\"Soup\":\"Tomato Bisque\",\"Entree\":6434,\"Side\":2303093,\"Desert\":0,\"Beverage\":\"Lemonade + Rum\"}, {\"Appetizer\":28,\"Salad\":21,\"Soup\":\"Peanut\",\"Entree\":6434,\"Side\":2303093,\"Desert\":0,\"Beverage\":\"Ginger Ale + Whiskey\"}]}";
    
        JavaScriptSerializer deSerializedResponse = new JavaScriptSerializer();
        RootObject root = (RootObject)deSerializedResponse.Deserialize(response, typeof(RootObject));
    
        foreach (Blueplate plate in root.blueplates)
        {
            Console.WriteLine(plate.Appetizer);
            Console.ReadLine();
        }