Deserialize JSON into an object (VB.NET)

13,804

Solution 1

I'd recommend JSON.net, as SBlackler did. I wrote up a test in C# based on your objects and the JSON object you posted and was able to build everything fine. Here's my code.

        List<items> Results = new List<items>();
        foreach (JToken Item in (JArray)JObject.Parse(json)["items"])
        {
            Results.Add(new items()
            {
                kind = Item["kind"].ToString(),
                product = new product()
                {
                    inventories = new inventories()
                    {
                        price = Convert.ToDouble(Item["product"]["inventories"][0]["price"].ToString())
                    }
                }
            });
        }
        Response.Write(Results[0].product.inventories.price);

I'm a bit unsure of the structure of the json object, but inventories appears to be an array. Within the example you posted, it appeared that you were trying to get the "price" value of the first object inside that array, and my code does that. If there are multiple objects in the inventories array, you may want to adjust your objects and the code that populates them accordingly.

Here are my objects:

class items
{
    public product product { get; set; }
    public string kind { get; set; }
}

class product
{
    public inventories inventories { get; set; }
}

class inventories
{
    public double price { get; set; }
}

The above code assumes there will ALWAYS be at least one object in the inventories array and will only pull from the first one. Following is how you might want to reconstruct the code should there be multiple objects in the inventories array.

    List<item> Results = new List<item>();
    foreach (JToken Item in (JArray)JObject.Parse(json)["items"])
    {
        item CurrentItem = new item()
        {
            kind = Item["kind"].ToString(),
            product = new product()
        };
        foreach (JToken inventory in (JArray)Item["product"]["inventories"])
        {
            CurrentItem.product.inventories.Add(new inventory()
            {
                price = Convert.ToDouble(inventory["price"].ToString())
            });
        }
        Results.Add(CurrentItem);
    }
    Response.Write(Results[0].product.inventories[0].price);

And the revised objects

class item
{
    public product product { get; set; }
    public string kind { get; set; }
}

class product
{
    public List<inventory> inventories { get; set; }

    public product()
    {
        inventories = new List<inventory>();
    }
}

class inventory
{
    public double price { get; set; }
}

I hope this solves what you were looking for. Good luck!

Solution 2

Have you taken a look at JSON.net?

It's a very fast serialization/deserialization framework. Once placed into your project you can do:

Dim myObj as <Enter object type> _
= JsonConvert.DeserializeObject(Of <Enter object type>)("my json string here")

Homepage is: http://james.newtonking.com/pages/json-net.aspx

NB: My example might be slightly off, not checked the syntax of it :)

Share:
13,804
Standage
Author by

Standage

An educated fool with money on my mind!

Updated on June 04, 2022

Comments

  • Standage
    Standage about 2 years

    I'm having an issue with getting some of the values from with this json string:

    {
     "kind": "shopping#products",
     "etag": "\"YZWJaKE3MHROIW8rCIlu9mAACLM/6qxBB-GwuSPy5L3_zVS6sS2NYFI\"",
     "id": "tag:google.com,2010:shopping/products",
     "selfLink": "https://www.googleapis.com/shopping/search/v1/public/products?country=US&q=Bauerfeind+MalleoTrain+Ankle+Support,+Circumference+in+inches+6+3/4+-+7+1/2+,+Left,+Color+Titanium+&rankBy=price:descending&maxResults=1&startIndex=1",
     "nextLink": "https://www.googleapis.com/shopping/search/v1/public/products?country=US&q=Bauerfeind+MalleoTrain+Ankle+Support,+Circumference+in+inches+6+3/4+-+7+1/2+,+Left,+Color+Titanium+&rankBy=price:descending&maxResults=1&startIndex=2",
     "totalItems": 46,
     "startIndex": 1,
     "itemsPerPage": 1,
     "currentItemCount": 1,
     "items": [
      {
       "kind": "shopping#product",
       "id": "tag:google.com,2010:shopping/products/5944931/17136892246969389705",
       "selfLink": "https://www.googleapis.com/shopping/search/v1/public/products/5944931/gid/17136892246969389705",
       "product": {
            "googleId": "17136892246969389705",
            "author": {"name": "Superemployee.com","accountId": "5944931"},
            "creationTime": "2011-08-28T07:46:29.000Z",
            "modificationTime": "2011-09-11T06:02:54.000Z",
            "country": "US",
            "language": "en",
            "title": "Bauerfeind MalleoTrain Ankle Support Circumference in inches 6 3/4 - 7 1/2 Left Color Black",
            "description": "Bauerfeind MalleoTrain Ankle Support Circumference in inches 6 3/4 - 7 1/2 Left Color Black : Bauerfeind MalleoTrain Ankle Support, Circumference in inches 6 3/4 - 7 1/2 , Left, Color Black MalleoTrain relieves ankle pain and swelling during sports and everyday activities. Product Features: Knitted ankle support incorporating an anatomically contoured silicone insert behind each ankle bone . Silicone inserts leave ankle bones pressure-free and provide intermittent compression to the soft tissue of the joint, leading to increased circulation, thus aiding in the reduction of swelling and edema . Promotes proprioception , thus heightening sensory awareness in the ankle for increased joint stabilization . Anatomical knit carries controlled compression graduated at the edges to prevent constriction of circulation . Lightweight, breathable knit will not retain heat and is completely machine washable . Can be used to treat: Ankle swelling and soreness . Ankle sprains . Ligamental weakness and slight ligamentous tears . Degenerative joint disease (osteoarthritis) . Synovitis . ? Bursitis . Arthritis, osteoarthritis . Post cast . Product photo may not exactly match the product offered for sale. Please refer to the product description.",
            "link": "http://superemployee-com.amazonwebstore.com/Bauerfeind-MalleoTrain-Ankle-Support-Circumference-in/M/B001D0PFRY.htm?traffic_src=froogle&utm_medium=CSE&utm_source=froogle",
            "brand": "Bauerfeind",
            "condition": "new",
            "inventories": [{"channel": "online", "availability": "inStock","price": 90.0,"currency": "USD"} ],
            "images": [{"link": "http://ecx.images-amazon.com/images/I/31xD5bPI4sL.jpg?gdapi"}
        ]
       }
      }
     ]
    

    I have tried using and creating classes but can't get data to return apart from at the top two levels, for example I'm trying to retrieve the price but can't figure out how to extract this data?

    This is the code I'm using and it returns nothing:

    <DataContract(Namespace:="")> _
        Public Class items
    
            <DataMember(Name:="product")>
            Public Property product As product
    
        End Class
    
        <DataContract(Name:="product", Namespace:="")> _
        Public Class product
            <DataMember(Name:="inventories")>
            Public Property inventories As inventories
    
        End Class
    
        <DataContract(Name:="inventories", Namespace:="")> _
        Public Class inventories
            <DataMember(Name:="price")>
            Public Property price As Double
    
        End Class
    

    Thanks for any help

    Using JSON.net framework I changed my Classes to the following but still don't get anything back for the price?

       Public Class items
            Public Property product As product()
            Public Property kind As String
        End Class
    
        Public Class product
            Public Property inventories As inventories()
        End Class
    
        Public Class inventories
            Public Property price As Double
        End Class