使用带有JSON.Net的自定义反序列化器反序列化JSON
我有这样的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 Parse(string json) { var jobject = JObject.Parse(json); var result = new List(); 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; }
你走在正确的轨道上。 以下是您需要进行的更正:
- 您正在迭代顶级对象的子级,期望将实际位于对象中的数据进一步降低一级。 您需要导航到
MobileSiteContents
属性的值并迭代其子MobileSiteContents
。 - 当您使用
JObject
的Children()
时,使用允许您将它们转换为JProperty
对象的重载; 这将使您更容易提取所需的数据。 - 从
JProperty
项的Name
中获取culture
- 要获取
urls
,请获取JProperty
项的Value
,并使用ToObject
将其转换为字符串数组。()
这是更正后的代码:
public IEnumerable Parse(string json) { var jObject = JObject.Parse(json); var result = new List (); foreach (var item in jObject["MobileSiteContents"].Children()) { var culture = item.Name; string[] urls = item.Value.ToObject(); result.Add(new MobileSiteContentsContentSectionItem { Culture = culture, Urls = urls }); } return result; }
如果您喜欢简洁的代码,可以将其减少为“单行”:
public IEnumerable Parse(string json) { return JObject.Parse(json)["MobileSiteContents"] .Children() .Select(prop => new MobileSiteContentsContentSectionItem { Culture = prop.Name, Urls = prop.Value.ToObject() }) .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 Parse(string json) { return JObject.Parse(json)["MobileSiteContents"] .Children() .Select(prop => new MobileSiteContentsContentSectionItem() { Culture = prop.Name, Urls = prop.Value.ToObject() }) .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 Parse(string json) { dynamic jobject = Newtonsoft.Json.JsonConvert.DeserializeObject(json); var result = new List (); var urls = new List(); 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; }