使用抽象属性JSON反序列化类

使用抽象属性JSON反序列化类,json,json.net,json-deserialization,Json,Json.net,Json Deserialization,我已经有一个JSON转换器根据Type属性的值反序列化这些对象 public abstract class Person { public string FirstName { get; set; } public string LastName { get; set; } [JsonProperty(Required = Required.Always)] public string Type { get; set; }

我已经有一个JSON转换器根据Type属性的值反序列化这些对象

public abstract class Person
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        [JsonProperty(Required = Required.Always)]
        public string Type { 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; }
    }
如何为这个City类编写一个可以使用PersonConverter初始化Persons属性的转换器?我最初的想法是将Persons部分提取为JObject,然后在其ReadJson方法中使用PersonConverter对其调用反序列化,类似于下面的示例

public class City
    {
        public string Name { get; set; }
        public int Population { get; set; }
        public Person[] Persons { get; set; }
    }
方法#1

这件事是我自己解决的

  • 在反序列化过程中标记要忽略的Persons属性

    [JsonIgnore] 公众人物[]人{get;set;}

  • 在Create方法中,实例化City对象并使用PersonConverter初始化Persons属性

    受保护的覆盖城市创建(类型objectType,JObject JObject) { if(jObject[“Persons”]==null) { 抛出新ArgumentException(); }

    var p=jObject[“Persons”].ToString();
    List persons=JsonConvert.DeserializeObject(p,new PersonConverter());
    var city=新城();
    city.Persons=Persons.ToArray();
    回归城市;
    }
    
  • ReadJson方法将像往常一样填充剩余的城市属性


    还有其他方法吗?

    我认为这是最合适的方法

    在ReadJson中,当数组被传递时,它基本上崩溃了,因为Jarray不是JBObject。因此,我更新了ReadJson,如下所示,它成功了

             var p = jObject["Persons"].ToString();
    
             List<Person> persons = JsonConvert.DeserializeObject<List<Person>>(p, new PersonConverter());
             var city = new City();
             city.Persons = persons.ToArray();
             return city;
         }
    
    public override object ReadJson(JsonReader reader,类型objectType,对象existingValue,JsonSerializer序列化程序)
    {
    if(reader.TokenType==JsonToken.StartArray)
    {
    JArray jObject=JArray.Load(读卡器);
    列表=新列表();
    对于(int i=0;i

    是的,我不需要城市转换者。添加人员转换器就足够了。

    我认为这是最合适的方式

    在ReadJson中,当数组被传递时,它基本上崩溃了,因为Jarray不是JBObject。因此,我更新了ReadJson,如下所示,它成功了

             var p = jObject["Persons"].ToString();
    
             List<Person> persons = JsonConvert.DeserializeObject<List<Person>>(p, new PersonConverter());
             var city = new City();
             city.Persons = persons.ToArray();
             return city;
         }
    
    public override object ReadJson(JsonReader reader,类型objectType,对象existingValue,JsonSerializer序列化程序)
    {
    if(reader.TokenType==JsonToken.StartArray)
    {
    JArray jObject=JArray.Load(读卡器);
    列表=新列表();
    对于(int i=0;i

    是的,我不需要城市转换者。添加PersonConverter就足够了。

    为什么需要为城市编写转换器?使用
    个人
    的转换器不需要这样做,您的
    个人转换器
    应该会自动使用。为什么需要为
    城市
    编写转换器?使用
    个人
    的转换器不需要这样做,您的
    个人转换器
    应该会自动使用。
    string Cityjson = "{\"Name\": \"London\" , \"Population\": \"1000\" , \"Persons\": [{\"Department\": \"Department1\",\"JobTitle\": \"JobTitle1\",\"FirstName\": \"FirstName1\",\"LastName\": \"LastName1\",\"Type\": \"Employee\"},{\"Skill\": \"Drawer\",\"FirstName\": \"FirstName1\",\"LastName\": \"LastName1\",\"Type\": \"Artist\"}]}";
    
             var p = jObject["Persons"].ToString();
    
             List<Person> persons = JsonConvert.DeserializeObject<List<Person>>(p, new PersonConverter());
             var city = new City();
             city.Persons = persons.ToArray();
             return city;
         }
    
    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
            {
                if (reader.TokenType == JsonToken.StartArray)
                {
                    JArray jObject = JArray.Load(reader);
                    List<T> list = new List<T>();
                    for (int i = 0; i < jObject.Count(); i++)
                    {
                        var p = jObject[i];
                        JObject ob = p as JObject;
                        T value = Create(objectType, ob);
                        serializer.Populate(ob.CreateReader(), value);
                        list.Add(value);
                    }
    
                    return list.ToArray();
                }
                else
                {
                    JObject jObject = JObject.Load(reader);
                    T target = Create(objectType, jObject);
                    serializer.Populate(jObject.CreateReader(), target);
                    return target;
                }
            }