Json.NET Custom JsonConverter with data types(具有数据类型的Json.NET自定义JsonConverter)
本文介绍了具有数据类型的Json.NET自定义JsonConverter的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我无意中发现了一个以以下格式输出JSON的服务:
{
"Author": "me",
"Version": "1.0.0",
"data.Type1": {
"Children": [
{
"data.Type1": {
"Children": [
{
"data.Type2": {
"name": "John",
"surname": "Doe"
}
}
]
}
},
{
"data.Type3": {
"dob": "1990-01-01"
}
}
]
}
}
数据类型名称保留为属性名称,它们的值是实际的对象。它们都以data.
前缀开头。
事后我想得到的是这样的:
{ // Root
"Author": "me",
"Version": "1.0.0",
"Children": [ // Type1
{
"Children": [ // Type1
{ // Type2
"Name": "John",
"Surname": "Doe"
}
]
},
{ // Type3
"DoB": "1990-01-01"
}
]
}
包含以下类:
class Type1 {
ICollection<object> Children { get; set; }
}
class Type2 {
public string Name { get; set; }
public string Surname { get; set; }
}
class Type3 {
public DateTime DoB { get; set; }
}
class Root
{
public string Author { get; set; }
public string Version { get; set; }
public Type1 Children { get; set; }
}
问题
如何将其反序列化为添加的C#类,同时考虑数据类型并将其从树中删除?
我已尝试使用自定义JsonConverter
,但正在努力解决如何动态选择转换器的问题,因为最简单的方法是将属性放在属性上,但不支持该属性。
一个小示例就足够了。
json
虽然此推荐答案格式有些不寻常,并且由于动态属性名称而拒绝使用属性,但仍然可以通过一个小更改将其反序列化为您的首选类结构:我建议您将Root
类中的Children
属性更改为ICollection<object>
,以镜像Type1
类中的Children
属性现在,它与所需输出的结构不匹配(其中Children
显示为数组,而不是对象),否则将需要转换器中的其他代码才能正确处理。
class Root
{
public string Author { get; set; }
public string Version { get; set; }
public ICollection<object> Children { get; set; }
}
以下是我为转换器设计的内容(假设进行了上述更改):
class CustomConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return (objectType == typeof(Root));
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
JObject obj = JObject.Load(reader);
Root root = new Root();
root.Author = (string)obj["Author"];
root.Version = (string)obj["Version"];
root.Children = ((Type1)DeserializeTypeX(obj, serializer)).Children;
return root;
}
private object DeserializeTypeX(JObject obj, JsonSerializer serializer)
{
JProperty prop = obj.Properties().Where(p => p.Name.StartsWith("data.")).First();
JObject child = (JObject)prop.Value;
if (prop.Name == "data.Type1")
{
List<object> children = new List<object>();
foreach (JObject jo in child["Children"].Children<JObject>())
{
children.Add(DeserializeTypeX(jo, serializer));
}
return new Type1 { Children = children };
}
else if (prop.Name == "data.Type2")
{
return child.ToObject<Type2>(serializer);
}
else if (prop.Name == "data.Type3")
{
return child.ToObject<Type3>(serializer);
}
throw new JsonSerializationException("Unrecognized type: " + prop.Name);
}
public override bool CanWrite
{
get { return false; }
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
使用此转换器,您可以反序列化为您的类,如下所示:
Root root = JsonConvert.DeserializeObject<Root>(json, new CustomConverter());
然后可以序列化到新格式,如下所示:
JsonSerializerSettings settings = new JsonSerializerSettings
{
DateFormatString = "yyyy-MM-dd",
Formatting = Formatting.Indented
};
Console.WriteLine(JsonConvert.SerializeObject(root, settings));
小提琴:https://dotnetfiddle.net/ESNMLE
这篇关于具有数据类型的Json.NET自定义JsonConverter的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
沃梦达教程
本文标题为:具有数据类型的Json.NET自定义JsonConverter


猜你喜欢
- 输入按键事件处理程序 2022-01-01
- MoreLinq maxBy vs LINQ max + where 2022-01-01
- 带有服务/守护程序应用程序的 Microsoft Graph CSharp SDK 和 OneDrive for Business - 配额方面返回 null 2022-01-01
- WebMatrix WebSecurity PasswordSalt 2022-01-01
- 在哪里可以找到使用中的C#/XML文档注释的好例子? 2022-01-01
- C#MongoDB使用Builders查找派生对象 2022-09-04
- C# 中多线程网络服务器的模式 2022-01-01
- 如何用自己压缩一个 IEnumerable 2022-01-01
- Web Api 中的 Swagger .netcore 3.1,使用 swagger UI 设置日期时间格式 2022-01-01
- 良好实践:如何重用 .csproj 和 .sln 文件来为 CI 创建 2022-01-01