繁体   English   中英

使用带有JSON.Net的自定义反序列化器反序列化JSON

[英]Deserializing JSON using custom deserializer with JSON.Net

我有这样的JSON:

{
  "MobileSiteContents": {
    "au/en": [
      "http://www.url1.com",
      "http://www.url2.com",

    ],
    "cn/zh": [
      "http://www.url2643.com",

    ]
  }
}

我正在尝试将其反序列化为IEnumerable类,如下所示:

public class MobileSiteContentsContentSectionItem : ContentSectionItem
{
    public string[] Urls { get; set; }
}

public abstract class ContentSectionItem
{
    public string Culture { get; set; }
}

那可能吗?
我意识到我可能需要为此使用Custom JsonConverter,但找不到任何示例。

我开始编写一个使用JObject.Parse进行转换的方法,但不确定这是否是正确/最有效的路径:

public IEnumerable<MobileSiteContentsContentSectionItem> Parse(string json)
{
    var jobject = JObject.Parse(json);

    var result = new List<MobileSiteContentsContentSectionItem>();

    foreach (var item in jobject.Children())
    {
        var culture = item.Path;
        string[] urls = new[] { "" }; //= this is the part I'm having troble with here...

        result.Add(new MobileSiteContentsContentSectionItem { Culture = culture, Urls = urls });
    }

    return result;
}

你走在正确的轨道上。 以下是您需要进行的更正:

  1. 您正在迭代顶级对象的子级,期望将实际位于对象中的数据进一步降低一级。 您需要导航到MobileSiteContents属性的并迭代它的子项。
  2. 当您使用JObjectChildren()时,使用允许您将它们转换为JProperty对象的重载; 这将使您更容易提取所需的数据。
  3. JProperty项目的Name获取culture
  4. 要获取urls ,请获取JProperty项的Value ,并使用ToObject<string[]>()将其转换为字符串数组。

这是更正后的代码:

public IEnumerable<MobileSiteContentsContentSectionItem> Parse(string json)
{
    var jObject = JObject.Parse(json);

    var result = new List<MobileSiteContentsContentSectionItem>();

    foreach (var item in jObject["MobileSiteContents"].Children<JProperty>())
    {
        var culture = item.Name;
        string[] urls = item.Value.ToObject<string[]>();

        result.Add(new MobileSiteContentsContentSectionItem { Culture = culture, Urls = urls });
    }

    return result;
}

如果您喜欢简洁的代码,可以将其减少为“单行”:

public IEnumerable<MobileSiteContentsContentSectionItem> Parse(string json)
{
    return JObject.Parse(json)["MobileSiteContents"]
        .Children<JProperty>()
        .Select(prop => new MobileSiteContentsContentSectionItem
        {
            Culture = prop.Name,
            Urls = prop.Value.ToObject<string[]>()
        })
        .ToList();
}

演示:

class Program
{
    static void Main(string[] args)
    {
        string json = @"
        {
            ""MobileSiteContents"": {
                ""au/en"": [
                    ""http://www.url1.com"",
                    ""http://www.url2.com"",
                ],
                ""cn/zh"": [
                    ""http://www.url2643.com"",
                ]
            }
        }";

        foreach (MobileSiteContentsContentSectionItem item in Parse(json))
        {
            Console.WriteLine(item.Culture);
            foreach (string url in item.Urls)
            {
                Console.WriteLine("  " + url);
            }
        }
    }

    public static IEnumerable<MobileSiteContentsContentSectionItem> Parse(string json)
    {
        return JObject.Parse(json)["MobileSiteContents"]
            .Children<JProperty>()
            .Select(prop => new MobileSiteContentsContentSectionItem()
            {
                Culture = prop.Name,
                Urls = prop.Value.ToObject<string[]>()
            })
            .ToList();
    }

    public class MobileSiteContentsContentSectionItem : ContentSectionItem
    {
        public string[] Urls { get; set; }
    }

    public abstract class ContentSectionItem
    {
        public string Culture { get; set; }
    }
}

输出:

au/en
  http://www.url1.com
  http://www.url2.com
cn/zh
  http://www.url2643.com

我尝试使用Json.Net并且工作正常。

public IEnumerable<MobileSiteContentsContentSectionItem> Parse(string json)
{
     dynamic jobject = Newtonsoft.Json.JsonConvert.DeserializeObject(json);

     var result = new List<MobileSiteContentsContentSectionItem>();

     var urls = new List<string>();
     foreach (var item in jobject.MobileSiteContents)
     {
         var culture = item.Name;
         foreach(var url in item.Value)
            urls.Add(url.Value);

         result.Add(new MobileSiteContentsContentSectionItem { Culture = culture, Urls = urls.ToArray() });
     }

     return result;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM