【问题标题】:How to safely deserialize keys/data format JSON response如何安全地反序列化密钥/数据格式 JSON 响应
【发布时间】:2018-04-28 02:16:34
【问题描述】:

我从第三方 Web 服务获得了这个“优化”的 JSON 响应,如下所示,我根据键中提供的信息构建了类型,但我面临的困难是数据不是在对象中表示,而是在数组,有没有办法自动化我的对象列表的构建和值映射?

{
    "reports": {
        "query": {
            "keys": [{
                "name": "Date",
                "type": "date"
            }, {
                "name": "NetSales",
                "type": "price"
            }, {
                "name": "GrossCash",
                "type": "price"
            }, {
                "name": "GrossCard",
                "type": "price"
            }, {
                "name": "GrossDelivery",
                "type": "price"
            }, {
                "name": "NetFood",
                "type": "price"
            }, {
                "name": "NetDrink",
                "type": "price"
            }, {
                "name": "NetRetail",
                "type": "price"
            }, {
                "name": "Baskets",
                "type": "int"
            }],
            "data": [
                [1523577600000, 51924, 11300, 27200, 9900, null, null, null, 8],
                [1523404800000, 7434, 2600, 3900, null, null, null, null, 6],
                [1523491200000, 18101, 4000, 10100, null, null, null, null, 5],
                [1523664000000, 13243, 7400, 6500, null, null, null, null, 3],
                [1523750400000, 11718, 7300, null, 5000, null, null, null, 2],
                [1523836800000, 16576, 7700, 4800, 4900, null, null, null, 4],
                [1524096000000, 20293, 9100, 6000, null, null, null, null, 4]
            ]
        }
    },
    "api": {
        "message": {
            "success": {
                "202": {
                    "id": 202,
                    "title": "Token is valid",
                    "details": "Token is validated and found valid."
                }
            }
        },
        "codeBaseVersion": 1,
        "executionTime_milliSeconds": 43
    }
}

我最终得到了这段代码,但对它不满意:

JObject myOpject = JObject.Parse(responseString);

List<JToken> setOfObjects = myOpject["reports"]["query"]["data"].Children().ToList();
var listOfData = new List<Data2>();
foreach (var token in setOfObjects)
{
    var myObject = new Data2
    {
        NetSales = decimal.Parse(token[1].ToString()),
        //etc.

    };

    listOfData.Add(myObject);
}

【问题讨论】:

  • 键的动态性如何?这里有两个营地。创建一个可以解释数据的自定义 DynamicObject 或创建一个与键匹配的强类型模型,然后使用反射将属性与键匹配并构建对象。
  • @Nkosi 它们是稳定的,但正如您所说,我需要映射到强类型模型并映射到它。您能否提供一个示例代码来说明您所说的内容?
  • 这是一个想法,使用相同的 JToken 思想,使用键转换数据以创建对象模型,然后将其反序列化为所需的强类型。

标签: c# arrays json web-services json.net


【解决方案1】:

使用相同的 JToken 思想,使用键转换数据以创建新的对象模型,然后将其反序列化为所需的强类型。

例如,获取一些记录,您可以将键和数据转换为

[
  {
    "Date": 1523577600000,
    "NetSales": 51924,
    ...
  },
  {
    "Date": 1523404800000,
    "NetSales": 7434,
    ...
  },
  ...
]

以下代码尝试使用与数据数组中项的索引匹配的键索引来构建它

JObject myOpject = JObject.Parse(responseString);
List<JToken> keys = myOpject["reports"]["query"]["keys"].Children().ToList();
List<JToken> data = myOpject["reports"]["query"]["data"].Children().ToList();

var array = new JArray();
foreach (var token in data) {
    var record = new JObject();
    for (var i = 0; i < keys.Count; i++) {
        var propertyName = keys[i]["name"].Value<string>();
        var propertyValue = token[i];
        record[propertyName] = propertyValue;                    
    }
    array.Add(record);                
}

var listOfData = array.ToObject<List<Data2>>(); // or Data2[], etc

假设Data2 是具有匹配属性的强类型模型。

【讨论】:

  • Gotcha..基本上你正在将其转换为熟悉的 JSON,然后转换
  • @HichemSeeSharp 是的,就是这个想法。
  • 您知道如何将提供的整数转换为日期时间吗?我忽略了它来自什么标准。使用 Ticks 给了我错误的日期。
  • @HichemSeeSharp 它来自什么标准?这是一个unix日期吗?
  • @HichemSeeSharp 查看我如何转换它的示例dotnetfiddle.net/HQ1InQ
猜你喜欢
  • 1970-01-01
  • 2020-11-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-25
  • 1970-01-01
  • 1970-01-01
  • 2018-08-21
相关资源
最近更新 更多