【问题标题】:Deserialize JSON array with unknown keys inside JSON object to a generic property - C#将 JSON 对象中具有未知键的 JSON 数组反序列化为通用属性 - C#
【发布时间】:2019-11-19 04:27:11
【问题描述】:

为这个问题找到正确的标题有点困难,所以我将在下面尝试更好地解释这个问题。

我正在调用返回以下 JSON 对象的 API:

{{
  "id": "jsonrpc",
  "jsonrpc": "2.0",
  "result": {
    "result": [
      {
        "AccountId": 285929,
        "Flags": [
          "Managed_Obsolete"
        ],
        "PartnerId": 73560,
        "Settings": [
          {
            "AN": "company_1"
          },
          {
            "CD": "1435323320"
          },
          {
            "ED": "2147483647"
          },
          {
            "OS": "Windows Server 2012 R2 Standard Edition (9600), 64-bit"
          },
          {
            "OT": "2"
          },
          {
            "T3": "1085792125772"
          },
          {
            "US": "958222150780"
          },
          {
            "YS": "100"
          }
        ]
      },
      {
        "AccountId": 610474,
        "Flags": null,
        "PartnerId": 249262,
        "Settings": [
          {
            "AN": "company_2"
          },
          {
            "CD": "1522143635"
          },
          {
            "ED": "2147483647"
          },
          {
            "OS": "Windows 7 Professional Service Pack 1 (7601), 64-bit"
          },
          {
            "OT": "2"
          },
          {
            "T3": "598346102236"
          },
          {
            "US": "758149148249"
          },
          {
            "YS": "100"
          }
        ]
      },
    ],
    "totalStatistics": null
  },
}}

在上面的结果中,我只列出了前 2 个帐户(通常总共 80 多个帐户)。 反序列化对象工作正常,我将 JSON 对象字段放在我的 C# 模型(列表)中。 然而问题是我无法在我的模型中正确获得(内部)Settingsarraysettings 数组 keys 未知,我在调用 API 时定义了这些键:

JObject requestObject = new JObject();
    requestObject.Add(new JProperty("id", "jsonrpc"));
    requestObject.Add(new JProperty("jsonrpc", "2.0"));
    requestObject.Add(new JProperty("method", "myMethod"));
    requestObject.Add(new JProperty("visa", someID));
    requestObject.Add(new JProperty("params",
       new JObject(
            new JProperty("query", new JObject(
                new JProperty("PartnerId", partnerId),
                new JProperty("StartRecordNumber", 0),
                new JProperty("RecordsCount", 9999999),
                new JProperty("Columns", new JArray("AR", "AN", "US", "T3", "OT", "OS", "YS"))
            )),
            new JProperty("timeslice", unixDate),
            new JProperty("totalStatistics", "*")
       ))
    );

在上面的调用中,我定义了 Settings 数组的键,但这也可能只是一个或多个键。出于这个原因,我想在我的 C# 模型 generic 中创建我的 Settings 属性(我不想列出所有可能的键名,因为这是超过 100 个键)。

到目前为止我所拥有的:

List<EnumerateAccountHistoryStatisticsResult> resultList = new List<EnumerateAccountHistoryStatisticsResult>();
var result = JsonConvert.DeserializeObject<JObject>(streamreader.ReadToEnd());
dynamic innerResult = result["result"]["result"];

foreach (var obj in innerResult)
{
    resultList.Add(
        new EnumerateAccountHistoryStatisticsResult
        {
            AccountId = obj.AccountId,
            Flags = obj.Flags.ToObject<IEnumerable<string>>(),
            PartnerId = obj.PartnerId,
            Settings = obj.Settings.ToObject<List<ColumnSettingsResult>>(),
        });
}

EnumerateAccountHistoryStatisticsResult 模型:

public class EnumerateAccountHistoryStatisticsResult
{
    public int AccountId { get; set; }
    public IEnumerable<string> Flags { get; set; }
    public int PartnerId { get; set; }
    public List<ColumnSettingsResult> Settings { get; set; }
}

ColumnSettingsResult 模型:

public class ColumnSettingsResult
{
    public string AR { get; set; }
    public string AN { get; set; }
    public string US { get; set; }
    public string T3 { get; set; }
    public string OT { get; set; }
    public string OS { get; set; }
    public string YS { get; set; }
    // and list all other columns...
}

对于上述模型,我需要列出所有可能超过 100 个属性的列,此外 Settings 列表的结果不合逻辑,因为我得到了所有属性值,但对于每个不同的键,我得到空值:

ColumnSettingsResult 模型应该更像:

public class ColumnSettingsResult
{
    public string ColumnName { get; set; }
    public string ColumnValue { get; set; }
}

虽然没有在模型中定义键名,但我无法获取这两个属性中的键和值。 我已经尝试了几件事但没有结果(下面的链接作为参考)。

谁能让我朝着正确的方向前进?

【问题讨论】:

    标签: c# json json.net


    【解决方案1】:

    尝试将Settings 设为Dictionary&lt;string,string&gt;(或List&lt;KeyValuePair&lt;string,string&gt;&gt;,如果Dictionary 没有为您提供所需的内容。

    public class MyJsonObject
    {
        public string id { get; set; }
        public string jsonrpc { get; set; }
        public Result result { get; set; }
    
        public class Result2
        {
            public int AccountId { get; set; }
            public List<string> Flags { get; set; }
            public int PartnerId { get; set; }
            public Dictionary<string,string> Settings { get; set; } //or List<KeyValuePair<string,string>>
        }
    
        public class Result
        {
            public List<Result2> result { get; set; }
            public object totalStatistics { get; set; }
        }
    }
    

    然后JsonConvert.DerserializeObject&lt;MyJsonObject&gt;(jsonString);

    【讨论】:

    • 这将是一个List&lt;T&gt;,其中T 是一个自定义Setting 类或KeyValuePair&lt;string,string&gt;。请参阅此docs page 了解字典格式的外观
    猜你喜欢
    • 1970-01-01
    • 2017-08-27
    • 2021-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多