【问题标题】:More elegant way to deserialize Json with LINQ?用 LINQ 反序列化 Json 的更优雅的方法?
【发布时间】:2010-10-22 19:35:40
【问题描述】:

我有以下形式的数据:

{
  "sections" : [
    {
      "section" : {
        "Term" : "News",
        "Term ID" : "4,253"
      }
    },
    {
      "section" : {
        "Term" : "Sports",
        "Term ID" : "4,254"
      }
    },
   // ...
  ]
}

我想将其序列化为以下类的集合:

public class Section
{

    public string Name;
    public int Tid;
}

这是我用来执行此操作的代码,使用 JSON.NET:

        // e.Result is the downloaded JSON
        JObject jsonData = JObject.Parse(e.Result);
        var sections = jsonData["sections"].Select(obj => obj["section"]).Select(sectData => new Section()
        {
            Name = HttpUtility.HtmlDecode(sectData["Term"].Value<string>().Replace("\"", "")),
            Tid = int.Parse(sectData["Term ID"].Value<string>().Replace(",", ""))
        });

        foreach (Section s in sections)
        {
            // _sections is an ObservableCollection<Section>
            _sections.Add(s);
        }

感觉有点笨拙。我可以更优雅地做到这一点吗?

特别是 foreach 在末尾循环。我宁愿使用addAllconcat之类的方法。

【问题讨论】:

    标签: c# linq json deserialization


    【解决方案1】:

    类似于...的东西

    JavaScriptSerializer serializer = new JavaScriptSerializer();
    List<Section> sections = serializer.Deserialize<List<Sections>>(e.Result);
    

    另请查看 DataContractJsonSerializer,它在技术上取代了 JavaScriptSerializer,但当我尝试使用它时似乎总是很麻烦。

    【讨论】:

    • .. 或者我没有抓住重点,似乎数据格式是导致您不简单的原因?
    • 数据格式和我的类有轻微的不一致。
    【解决方案2】:

    在解析数字之前,您不必使用Replace 删除千位分隔符,Parse 方法能够处理它们,如果您允许它们并确保它使用实际上有逗号的文化作为千位分隔符:

    Tid = Int32.Parse(sectData["Term ID"].Value<string>(), NumberStyles.AllowThousands, CultureInfo.InvariantCulture)
    

    如果_sections 变量是List&lt;Section&gt;,那么你可以使用它的AddRange 方法一次性添加它们:

    _sections.AddRange(sections);
    

    或者,如果列表只包含这些项目,您可以从结果创建列表,而不是先创建它然后将项目添加到其中:

    _sections = sections.ToList();
    

    【讨论】:

      【解决方案3】:

      我建议你重写Select语句中的匿名委托如下:

      var sections = jsonData["sections"].Select(obj => obj["section"]).Select(sectData =>
          {
              var section = new Section()
              {
                  Name = HttpUtility.HtmlDecode(sectData["Term"].Value<string>().Replace("\"", `enter code here`"")),
                  Tid = int.Parse(sectData["Term ID"].Value<string>().Replace(",", ""))
              };
              _sections.Add(section);
              return section;
          });
      

      请记住,lambda 可以形成闭包,因此 _sections 集合在传递给 Select 的委托中可用。这种方法应该摆脱 foreach 循环。

      【讨论】:

      • 这不起作用。我怀疑这是因为在查询中输入了_sections.Add(section)。查询在迭代之前不会执行,对吧?所以在这种情况下,您仍然需要点击查询中的所有结果才能使其运行。
      猜你喜欢
      • 2013-03-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多