0

I receive the following JSON string. It is part of the specifications of products. The data represents the Header ("General") and the items within in Key value pairs.

I dont want to hard code any properties such as general, Display Features and should be able to

  1. Retrieve the Header
  2. Iterate on the key value pair.

So Far I have the following code

foreach (var SpecList in objAPIProduct.categorySpecificInfoV1.specificationList)
{     
    foreach(dynamic  SpecItem in SpecList.General)
    {
        Console.WriteLine(SpecItem.key);
        Console.WriteLine(SpecItem.value[0]);
    }    
}

I want to get rid of the "General" Property that I have hardcoded in the inner foreach loop and make the loop generic for all properties. Here is the Json that I have

{
    "General": [{
        "key": "Sales Package",
        "value": ["Laptop, Power Adapter, Warranty Document"]
    },
    {
        "key": "Model Number",
        "value": ["3558"]
    },
    {
        "key": "Part Number",
        "value": ["Z565103UIN9"]
    },
    {
        "key": "Model Name",
        "value": ["Inspiron 15"]
    },
    {
        "key": "Series",
        "value": ["Inspiron"]
    },
    {
        "key": "Color",
        "value": ["Black"]
    },
    {
        "key": "Type",
        "value": ["Notebook"]
    },
    {
        "key": "Suitable For",
        "value": ["Everyday Use"]
    },
    {
        "key": "Battery Backup",
        "value": ["Upto 3.5 hours"]
    },
    {
        "key": "Battery Cell",
        "value": ["4 cell"]
    }]
},
{
    "Processor and Memory Features": [{
        "key": "Processor Brand",
        "value": ["Intel"]
    },
    {
        "key": "Processor Name",
        "value": ["Core i3"]
    },
    {
        "key": "Graphic Processor",
        "value": ["Intel HD Graphics 5500"]
    },
    {
        "key": "SSD",
        "value": ["No"]
    },
    {
        "key": "RAM",
        "value": ["4 GB"]
    },
    {
        "key": "RAM Type",
        "value": ["DDR3"]
    },
    {
        "key": "HDD Capacity",
        "value": ["500 GB"]
    },
    {
        "key": "Processor Variant",
        "value": ["5005U"]
    },
    {
        "key": "Clock Speed",
        "value": ["2 GHz"]
    },
    {
        "key": "Memory Slots",
        "value": ["1 Slot"]
    },
    {
        "key": "Expandable Memory",
        "value": ["Upto 4 GB"]
    },
    {
        "key": "RAM Frequency",
        "value": ["1600 MHz"]
    },
    {
        "key": "Cache",
        "value": ["3 MB"]
    },
    {
        "key": "RPM",
        "value": ["5400"]
    }]
}
BWA
  • 5,672
  • 7
  • 34
  • 45
John
  • 1
  • 1
  • 4

3 Answers3

1

On site json2csharp.com you can generate classes for your JSON.

public class General
{
    public string key { get; set; }
    public List<string> value { get; set; }
}

public class RootObject
{
    public List<General> General { get; set; }
}

And deserialize JSON to it using JSON.NET:

RootObject ro = JsonConvert.DeserializeObject<RootObject>(json);

And:

foreach(General g in ro.General)
{
    string k = g.key;
}
BWA
  • 5,672
  • 7
  • 34
  • 45
  • The Json has been deserialised using JavascriptSerializer. Here is that part of code - var serializer = new JavaScriptSerializer(); serializer.RegisterConverters(new[] { new DynamicJsonConverter() }); model = serializer.Deserialize(json, typeof(object)); In my code in the original post, it is working - But I have kind of "hard coded" the property "General" -- which I do not want to. As the property names would keep changing as per the product data. – John Sep 28 '16 at 11:14
  • In the inner loop - foreach(dynamic SpecItem in SpecList.General) I want to get rid of the .General here – John Sep 28 '16 at 11:16
  • @John JSON.NET is better, even Microsoft use JSON.NET in MVC. If you can change JavascriptSerializer to JSON.NET – BWA Sep 28 '16 at 11:17
  • Well, I agree. But this one is working just fine.And honestly, I dont really want to tinker with existing code. I have just to deal with that part of getting the product specifications and to make sure that I do not hard code anything. The property in the json is what is the pain area. Please bear in mind, that the json I say is already deserialise. – John Sep 28 '16 at 11:21
  • @John I see your point. Then you must look at https://msdn.microsoft.com/en-us/library/system.dynamic.dynamicobject.trygetindex.aspx and implement own logic. – BWA Sep 28 '16 at 11:41
  • Yes, I have been playing around with the TrySetIndex - no luck so far. – John Sep 28 '16 at 13:08
0

Rewrite your SpecList class like this

public class SpecList : Dictionary<string, List<SpecItem>>
{
}

From then you will be able to access your general property like this

foreach (var SpecList in    objAPIProduct.categorySpecificInfoV1.specificationList)
{
    foreach(var key in SpecList.Keys)
    {
        foreach(var SpecItem in SpecList[key])
        {
            Console.WriteLine(SpecItem.key);
            Console.WriteLine(SpecItem.value[0]);
        }    
    }
}

Hope it helps.

CodingNagger
  • 1,178
  • 1
  • 11
  • 26
  • I don't want to use the word "General", instead can I somehow get it using the index. Maybe something like [code] var general = SpecList[0] [/code] However this does not work – John Sep 28 '16 at 11:23
  • It gives a NULL error on SpecList.Keys in the second foreach - even when SpecList in the immediate window shows - {General:[key:"Model Number",value:["E484"]},key:"Model Name",value:["Canvas 6 Pro"]},key:"Color",value:["Black"]},key:"Browse Type",value:["Smartphones"]},key:"SIM Type",value:["Dual Sim"]},key:"Operating System",value:["Android"]},key:"Operating System Version Name",value:["Lollipop"]},key:"Operating System Version Number",value:["5.1"]},key:"Internal Storage",value:["16 GB"]},key:"RAM",value:["4 GB"]},key:" .... – John Sep 28 '16 at 12:30
  • What if you replace SpecList directly with Dictionary> in your code/mapping ? – CodingNagger Sep 28 '16 at 13:41
  • tried it - Cannot convert type 'System.Dynamic.DynamicObject' to 'System.Collections.Generic.Dictionary>' - didnt work :( – John Sep 28 '16 at 14:06
  • Use var instead of dynamic – CodingNagger Sep 28 '16 at 14:11
  • Nopes, I wasnt able to get it to work even with var, dynamic - I am still getting the same message. I am now looking at string manipulation... – John Sep 29 '16 at 15:51
0

After trying out a lot of options, I found that it is not possible to get the "Name" of the property when we use Json.Net or JavascriptSerialiser.

Finally, I used the help of this thread -

Deserialize JSON into C# dynamic object?

wherein the person has suggested using System.Web.Helpers and it works perfect in my case.

Here is my final code: dynamic objAPIProduct= Json.Decode(json);

List<ProductSpecification> objProductSpecificationList = new List<ProductSpecification>();
            ProductSpecification objProductSpecification;

            foreach (var SpecListCategoryList in objAPIProduct.categorySpecificInfoV1.specificationList)
            {
               foreach (var SpecCategory in SpecListCategoryList)
                {

                    DynamicJsonArray objListitems = SpecCategory.Value;

                    for  (int  i = 0; i < objListitems.Length; i++)
                     {
                    objProductSpecification = new ProductSpecification();
                    objProductSpecification.SpecificationHead = SpecCategory.Key;
                    objProductSpecification.SpecificationKey = objListitems[i].key;
                    objProductSpecification.SpecificationValue = objListitems[i].value[0];
                    objProductSpecificationList.Add(objProductSpecification);
                     }
                }

            }
Community
  • 1
  • 1
John
  • 1
  • 1
  • 4