Search code examples
c#.netasp.net-corejson-deserialization

deserialize a dynamic json object to a class


I'm working with an external API to get some product information, the end points return some data in a static structure and others in dynamic depending on the product I'm inquiring.

For example if I'm requesting data for a soap I get the following JSON:

    { "id": 4623,
      "brand": "Fa",
      "category": "Cleansing/Washing/Soap – Body",
      "photos": {
        "name": "Photos",
        "value": [        "https//test.com/1jpg"
        ]
      },
      "productname": {
        "name": "Product Name",
        "value": "Fa Shower Cream Yoghurt Vanilla Honey"
      },
      "warningstatement": {
        "name": "Warning Statement",
        "value": "Avoid contact with eyes."
      },
      "consumerusageinstructions": {
        "name": "Consumer Usage Instructions",
        "value": "Apply directly on skin."
      
    }

and if I'm inquiring about a cheese I get the following JSON:

     {
      "id": 10838,
      "brand": "Domty",
      "category": "Cheese",
      
      "photos": {
        "name": "Photos",
        "value": [ "https://test.com/2.jpg"
        ]
      },
      "productname": {
        "name": "Product Name",
        "value": "Domty White Low Salt Cheese"
      },
      "description": {
        "name": "1312",
        "value": "Highest premium quality"
      },
      "netcontent": {
        "name": "Net Content",
        "value": "900 gm"
      }

and it goes on for every product they offer. I've no problem deserializing the static data like photos array, product name, brand, and id since they are applicable to every product, but the other dynamic properties are the ones I'm concerned about. Is there a way to deserialize to a class like this:

public class Info {
    property string key { get; set;} // to hold description, consumerusageinstructions or what every key
    property string name { get; set;}
    property string value { get; set;}
}

and then add a collection of the class info to my product model?


Solution

  • One way is just to parse the Json and look at the actual entities: this example uses Json.Net:

    var parsed = JObject.Parse(json);
    var properties = parsed.Children().Cast<JProperty>();
    foreach (var property in properties) {
        
        // an alternative here would be to just have a list of names to ignore
        if (!(property.Value is JObject jObject)) {
            // skip the simple property/value pairs
            continue;
        }
    
        if (property.Name == "productname") {
            // skip product name
            continue;
        }
    
        if (property.Value["value"] is JArray) {
            // skip photos
            continue;
        }
    
        // Add to ProductModel instance
        Console.WriteLine($"{property.Name} => {property.Value["name"]} = {property.Value["value"]}");
    
    }
    

    Outputs:

    warningstatement => Warning Statement = Avoid contact with eyes.
    consumerusageinstructions => Consumer Usage Instructions = Apply directly on skin.

    description => 1312 = Highest premium quality
    netcontent => Net Content = 900 gm