使用具有 JSON.Net 的自定义反序列化程序反序列化 JSON
本文关键字:反序列化 JSON 自定义 程序 Net | 更新日期: 2023-09-27 18:35:52
我有看起来像这样的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;
}
你走在正确的轨道上。 以下是您需要进行的更正:
- 您正在迭代顶级对象的子对象,期望获取实际位于更下一级的对象中的数据。 您需要导航到
MobileSiteContents
属性的值并循环访问该属性的子属性。 - 当你
Children()
JObject
时,使用重载,让你把它们投射到JProperty
对象;这将使提取你想要的数据变得更加容易。 - 从
JProperty
项的Name
获取culture
- 要获取
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;
}