gpt4 book ai didi

c# - 如何在 JSON.NET 中实现自定义 JsonConverter?

转载 作者:bug小助手 更新时间:2023-10-28 01:26:02 24 4
gpt4 key购买 nike

我正在尝试扩展此处给出的 JSON.net 示例 http://james.newtonking.com/projects/json/help/CustomCreationConverter.html

我有另一个从基类/接口(interface)派生的子类

public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
}

public class Employee : Person
{
public string Department { get; set; }
public string JobTitle { get; set; }
}

public class Artist : Person
{
public string Skill { get; set; }
}

List<Person> people = new List<Person>
{
new Employee(),
new Employee(),
new Artist(),
};

我如何将跟随 Json 反序列化回列表< Person >

[
{
"Department": "Department1",
"JobTitle": "JobTitle1",
"FirstName": "FirstName1",
"LastName": "LastName1"
},
{
"Department": "Department2",
"JobTitle": "JobTitle2",
"FirstName": "FirstName2",
"LastName": "LastName2"
},
{
"Skill": "Painter",
"FirstName": "FirstName3",
"LastName": "LastName3"
}
]

我不想使用 TypeNameHandling JsonSerializerSettings。我正在专门寻找自定义 JsonConverter 实现来处理这个问题。这方面的文档和示例在网上非常稀少。我似乎无法在 JsonConverter 中正确实现重写的 ReadJson() 方法。

最佳答案

使用标准 CustomCreationConverter,我一直在努力研究如何生成正确的类型(PersonEmployee),因为为了确定这一点,您需要分析 JSON,并且没有使用 Create 方法执行此操作的内置方法。

我找到了一个关于类型转换的讨论帖,结果证明它提供了答案。这是一个链接:Type converting (archived link) .

所需的是将 JsonConverter 子类化,覆盖 ReadJson 方法并创建一个新的抽象 Create 方法,该方法接受 JObject

The JObject class provides a means to load a JSON object andprovides access to the data within this object.

重写的 ReadJson 方法创建一个 JObject 并调用 Create 方法(由我们的派生转换器类实现),传入 JObject 实例。

然后可以分析这个 JObject 实例,通过检查某些字段的存在来确定正确的类型。

示例

string json = "[{
\"Department\": \"Department1\",
\"JobTitle\": \"JobTitle1\",
\"FirstName\": \"FirstName1\",
\"LastName\": \"LastName1\"
},{
\"Department\": \"Department2\",
\"JobTitle\": \"JobTitle2\",
\"FirstName\": \"FirstName2\",
\"LastName\": \"LastName2\"
},
{\"Skill\": \"Painter\",
\"FirstName\": \"FirstName3\",
\"LastName\": \"LastName3\"
}]";

List<Person> persons =
JsonConvert.DeserializeObject<List<Person>>(json, new PersonConverter());

...

public class PersonConverter : JsonCreationConverter<Person>
{
protected override Person Create(Type objectType, JObject jObject)
{
if (FieldExists("Skill", jObject))
{
return new Artist();
}
else if (FieldExists("Department", jObject))
{
return new Employee();
}
else
{
return new Person();
}
}

private bool FieldExists(string fieldName, JObject jObject)
{
return jObject[fieldName] != null;
}
}

public abstract class JsonCreationConverter<T> : JsonConverter
{
/// <summary>
/// Create an instance of objectType, based properties in the JSON object
/// </summary>
/// <param name="objectType">type of object expected</param>
/// <param name="jObject">
/// contents of JSON object that will be deserialized
/// </param>
/// <returns></returns>
protected abstract T Create(Type objectType, JObject jObject);

public override bool CanConvert(Type objectType)
{
return typeof(T).IsAssignableFrom(objectType);
}

public override bool CanWrite
{
get { return false; }
}

public override object ReadJson(JsonReader reader,
Type objectType,
object existingValue,
JsonSerializer serializer)
{
// Load JObject from stream
JObject jObject = JObject.Load(reader);

// Create target object based on JObject
T target = Create(objectType, jObject);

// Populate the object properties
serializer.Populate(jObject.CreateReader(), target);

return target;
}
}

关于c# - 如何在 JSON.NET 中实现自定义 JsonConverter?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8030538/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com