将动态 json 对象反序列化为 class

deserialize a dynamic json object to a class

我正在使用外部 API 获取一些产品信息,端点 return 静态结构中的一些数据和动态结构中的其他数据,具体取决于我查询的产品。

例如,如果我请求肥皂的数据,我会得到以下 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."
      
    }

如果我询问奶酪,我会得到以下信息 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"
      }

他们提供的每一种产品都如此。我可以毫无问题地反序列化照片数组、产品名称、品牌和 ID 等静态数据,因为它们适用于每个产品,但其他动态属性是我关心的。有没有办法像这样反序列化为 class:

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;}
}

然后将 class 信息的集合添加到我的产品模型中?

一种方法是解析 Json 并查看实际实体:此示例使用 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"]}");

}

输出:

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