【问题标题】:Generate a list of custom objects from Json object using LINQ使用 LINQ 从 Json 对象生成自定义对象列表
【发布时间】:2017-04-13 13:53:56
【问题描述】:

目前我面临一个创建 LINQ 语句的问题,该语句将生成我想要的对象列表。以下部分是我要处理的 LINQ 对象的示例。

{
  "successful": "true",
  "result": [
    [
      {
        "Param1": "A1",
        "Param2": "A2",
        "Param3": "A3",
        "Param4": "A4",
        "Param5": "1",
        "Param6": "A5",
      },
      {
        "Param1": "B1",
        "Param2": "B2",
        "Param3": "B3",
        "Param4": "B4",
        "Param5": "2",
        "Param6": "B5",
      },
      {
        "Param1": "C1",
        "Param2": "C2",
        "Param3": "C3",
        "Param4": "C4",
        "Param5": "2",
        "Param6": "C5",
      }
    ]
  ]
}

我有一个自定义对象类如下,

public class CContainer
{
    public string param1{ get; set; }

    public string param2{ get; set; }

    public string param3{ get; set; }
}

我的最终目标是创建一个 CContainer 对象列表,其中仅包含“结果”类别下每个项目的前 3 个参数(Param1、Param2 和 Param3)。另外,我想只选择 Param5 == "2" 的项目。我目前无法使用 LINQ 做到这一点,请指教。

以下 sn-p 不起作用(即使我删除了 'Where' 子句)。

    List<CContainer> testList = new List<CContainer>();
    string responseRet = await response.Content.ReadAsStringAsync();
    JObject o = JObject.Parse(responseRet);

    testList =
     (from item in o["result"]
      where item["Param5"].Value<string>() == "2"
      select new CCOntainer
      {
          param1 = item["Param1"].Value<string>(),
          param2 = item["Param2"].Value<string>(),
          param3 = item["Param3"].Value<string>(),
      }).ToList();

【问题讨论】:

  • 为什么不使用property属性和JsonConvert.Deserialize()方法?
  • 我不确定如何使用反序列化方法在特定条件下仅提取 Param1、Param2、Param3。
  • 您是否知道您的 results 属性是一个包含单个元素的数组...而该单个元素本身就是您的 CContainer 对象的数组?这是一个错误还是故意的?
  • 我刚刚意识到它是一个包含单个元素的数组。我对JSON不熟悉,我认为这种格式是故意的,我不能改变它。感谢您指出。

标签: c# json linq


【解决方案1】:

您的 json 示例中的"result" 是一个包含一个数组的数组,该数组包含您的对象。

因此,要么更改 json,使 "result" 成为一维数组,要么类似于以下内容:

testList =
 (from item in o["result"].FirstOrDefault()
// etc.

【讨论】:

  • 谢谢,提取第一个元素后,我可以把它处理成我想要的列表,我猜是JSON对象的设计。
【解决方案2】:

你正试图同时做两件不同的事情。

  1. 您正在尝试将 JSON 反序列化为对象。
  2. 您正在尝试过滤返回的结果。

我建议您将它们视为单独的操作以简化您的代码。

要使用JsonConvert.DeserializeObject&lt;T&gt;() 反序列化所有对象,请按如下方式设置您的类:

[JsonObject(MemberSerialization.OptIn)]
public class Result
{
    [JsonProperty("success")]
    public bool Success{ get; set; }

    [JsonProperty("result")]
    public List<List<JsonCContainer>> Items{ get; set; }

}

[JsonObject(MemberSerialization.OptIn)]
public class JsonCContainer
{
    [JsonProperty("Param1")]
    public string param1{ get; set; }

    [JsonProperty("Param2")]
    public string param2{ get; set; }

    [JsonProperty("Param3")]
    public string param3{ get; set; }

    [JsonProperty("Param5")]
    public string param5{ get; set; }

}

public class CContainer
{
    public string param1{ get; set; }
    public string param2{ get; set; }
    public string param3{ get; set; }
}

您将使用以下代码获得您的 Result 对象:

string responseRet = await response.Content.ReadAsStringAsync();
Result resultObj = JsonConvert.DeserializeObject<Result>(responseRet);

获得Result 类对象后,进行过滤:

return resultObj.Items.SelectMany(x => x)
                .Where(x => x.param5 == "2")
                .Select(y => new CContainer()
                                 {
                                   param1 = y.param1, 
                                   param2 = y.param2, 
                                   param3 = y.param3
                                 }).ToList();

【讨论】:

  • 一些非常好的代码,但 json 结构是问题。
  • 更新处理多维数组。
猜你喜欢
  • 1970-01-01
  • 2020-08-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-05
相关资源
最近更新 更多