如何实现自定义JsonConverter在JSON.NET反序列化基类对象的列表? [英] How to implement custom JsonConverter in JSON.NET to deserialize a List of base class objects?

查看:1260
本文介绍了如何实现自定义JsonConverter在JSON.NET反序列化基类对象的列表?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想扩展这里给出的例子JSON.net
<一href=\"http://james.newtonking.com/projects/json/help/CustomCreationConverter.html\">http://james.newtonking.com/projects/json/help/CustomCreationConverter.html

I am trying to extend the JSON.net example given here http://james.newtonking.com/projects/json/help/CustomCreationConverter.html

我还有一个子类从基类派生/接口

I have another sub class deriving from base class/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回到列表&LT;人>

How do I deserialize following Json back to List< 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执行处理这个问题。解决这个问题的文档和例子是pretty在网络上稀疏。我似乎无法获得JsonConverter权被覆盖ReadJson()方法实现。

I don't want to use TypeNameHandling JsonSerializerSettings. I am specifically looking for custom JsonConverter implementation to handle this. The documentation and examples around this are pretty sparse on the net. I can't seem to get the the overridden ReadJson() method implementation in JsonConverter right.

推荐答案

使用标准 CustomCreationConverter ,我努力工作如何生成正确的类型(员工),因为为了确定这一点,你需要分析JSON并且在办法做到这一点没有内置使用创建方法。

Using the standard CustomCreationConverter, I was struggling to work how to generate the correct type (Person or Employee), because in order to determine this you need to analyse the JSON and there is no built in way to do this using the Create method.

我发现有关类型转换的讨论线程,它变成了提供答案。这里是一个链接:类型转换

I found a discussion thread pertaining to type conversion and it turned out to provide the answer. Here is a link: Type converting.

我们需要的是子类 JsonConverter ,覆盖 ReadJson 方法并创建一个新的抽象创建一个acceps 方法的 JObject

What's required is to subclass JsonConverter, overriding the ReadJson method and creating a new abstract Create method which acceps a JObject.

该JObject类提供了加载一个JSON对象的一种手段,
  提供此对象中对数据的访问。

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

该重写 ReadJson 方法创建一个 JObject 并调用创建方法(由我们派生转换器类实现),通过在 JObject 实例。

The overridden ReadJson method creates a JObject and invokes the Create method (implemented by our derived converter class), passing in the JObject instance.

JObject 实例然后可以分析检查某些领域的所有脑干,以确定正确的类型。

This JObject instance can then be analysed to determine the correct type by checking existance of certain fields.

示例

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 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;
    }

    public override void WriteJson(JsonWriter writer, 
                                   object value,
                                   JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

这篇关于如何实现自定义JsonConverter在JSON.NET反序列化基类对象的列表?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆