【问题标题】:Deserializing JSON using custom deserializer with JSON.Net使用带有 JSON.Net 的自定义反序列化器反序列化 JSON
【发布时间】:2013-10-17 16:28:00
【问题描述】:

我的 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; }
}

这可能吗?
我意识到我可能需要为此使用自定义 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;
}

【问题讨论】:

    标签: c# json json.net deserialization


    【解决方案1】:

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

    1. 您正在迭代顶级对象的子对象,期望获得实际上位于更下一层对象中的数据。您需要导航到 MobileSiteContents 属性的 并遍历其子级。
    2. 当您采用Children()JObject 时,使用允许您将它们转换为JProperty 对象的重载;这将使提取所需数据变得更加容易。
    3. JProperty 项目的Name 中获取culture
    4. 要获取urls,请获取JProperty 项的Value,然后使用ToObject&lt;string[]&gt;() 将其转换为字符串数组。

    以下是更正后的代码:

    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
    

    【讨论】:

      【解决方案2】:

      我使用 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;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-11-22
        • 2017-03-19
        • 2017-06-30
        • 2014-09-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多