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

Ale*_*lex 6 c# json json.net deserialization

我有这样的JSON:

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

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

    ]
  }
}
Run Code Online (Sandbox Code Playgroud)

我正在尝试将其反序列化为IEnumerable类似于以下的类:

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

public abstract class ContentSectionItem
{
    public string Culture { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

那可能吗?
我意识到我可能需要为此使用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;
}
Run Code Online (Sandbox Code Playgroud)

Bri*_*ers 6

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

  1. 您正在迭代顶层对象的子节点,期望获得实际位于对象中的数据更低一级.您需要导航到该的的MobileSiteContents财产和迭代的孩子们.
  2. 当你走Children()JObject,可以使用,可以让你施展他们的超负荷JProperty物品; 这将使您更容易提取所需的数据.
  3. 获得cultureName该的JProperty项目
  4. 为了得到urls,得到Value了的JProperty项目,并用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;
}
Run Code Online (Sandbox Code Playgroud)

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

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();
}
Run Code Online (Sandbox Code Playgroud)

演示:

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; }
    }
}
Run Code Online (Sandbox Code Playgroud)

输出:

au/en
  http://www.url1.com
  http://www.url2.com
cn/zh
  http://www.url2643.com
Run Code Online (Sandbox Code Playgroud)