使用 Newtonsoft.JSON 编写自定义 JSON 转换器



>我有一个类结构如下

    public interface IPerson
    {
        string Name { get; set; }
    }
    public class Person : IPerson
    {
        public string Name { get; set; }
    }
    public interface IPersonResult
    {
        List<IPerson> Persons { get; set; }
    }
    public class PersonResult : IPersonResult
    {        
        public List<IPerson> Persons { get; set; }
    }

当我尝试将我的 json 反序列化为 IPersonResult 时,如下所示,它给出了错误,

  var personList = new PersonResult
  {
      Persons = new List<IPerson> {new Person {Name = "Jack"}, new Person {Name = "John"}}
  };
  var jsonnn = JsonConvert.SerializeObject(personList);
  var des = JsonConvert.DeserializeObject<PersonResult>(jsonnn);

"类型是一个接口或抽象类,不能实例化。">

我使用Newtonsoft库创建了一个自定义JsonConvertor,如下所示,

public class JsonInterfaceConverter<TInterface, TConcrete> :  CustomCreationConverter<TInterface> where TConcrete : TInterface, new()
    {
        public override TInterface Create(Type objectType)
        {
            return new TConcrete();
        }
    }

适用于单个对象,但我需要一个通用转换器,在反序列化时处理接口列表。

不知何故,这就是我想要实现的目标

public class JsonListInterfaceConverter<TInterface, TConcrete> : CustomCreationConverter<IList<TConcrete>> where TConcrete:TInterface 
    {
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            if (reader.TokenType == JsonToken.StartArray)
            {
                reader.Read();
                var value = new List<TConcrete>();
                while (reader.TokenType != JsonToken.EndArray)
                {
                    var item = JObject.Load(reader);
                    value.Add(item.ToObject<TConcrete>());
                    reader.Read();
                }
                return value;
            }
            return serializer.Deserialize(reader);
        }
        public override IList<TConcrete> Create(Type objectType)
        {
            return new List<TConcrete>();
        }
    }

可以用作属性

public class PersonResult : IPersonResult
    {
        [JsonConverter(typeof(JsonListInterfaceConverter<Ilist<IPerson>, List<Person>>))]
        public List<IPerson> Persons { get; set; }
    } 

有什么帮助吗?

如果不将接口绑定到任何类型的接口,则无法创建IPerson列表

为什么你甚至需要PersonResult?只需改用这个:

var des = JsonConvert.DeserializeObject<List<Person>>(jsonnn);

这也应该适用于您的示例(没有自定义类型绑定器的最简单方法(:

var personList = new PersonResult
{
    Persons = new List<IPerson> {new Person {Name = "Jack"}, new Person {Name = "John"}}
};
var serialized = JsonConvert.SerializeObject(personList, Formatting.Indented, new JsonSerializerSettings
{
    TypeNameHandling = TypeNameHandling.Objects,
    TypeNameAssemblyFormat = System.Runtime.Serialization.Formatters.FormatterAssemblyStyle.Simple
});
var deserialized = JsonConvert.DeserializeObject<PersonResult>(serialized, new JsonSerializerSettings
{
    TypeNameHandling = TypeNameHandling.Objects
});
这就是

我所做的

 public class JsonListInterfaceConverter<TInterface, TConcrete> : CustomCreationConverter<IList<TConcrete>> where TConcrete:TInterface 
    {
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            if (reader.TokenType == JsonToken.StartArray)
            {
                reader.Read();
                var value = new List<TConcrete>();
                while (reader.TokenType != JsonToken.EndArray)
                {
                    var item = JObject.Load(reader);
                    value.Add(item.ToObject<TConcrete>());
                    reader.Read();
                }
                return new List<TInterface>(value.Cast<TInterface>()); //This part I was doing wrong
            }
            return serializer.Deserialize(reader);
        }
        public override IList<TConcrete> Create(Type objectType)
        {
            return new List<TConcrete>();
        }
    }

现在我可以将其用作类中 IList 的属性

public interface IPerson
{
    string Name { get; set; }
}    
public interface ITask
{
    string TaskName { get; set; }
}
public class Person : IPerson
{
    public string Name { get; set; }
}
public class Task: ITask
{
    public string TaskName { get; set; }
}
public interface IPersonResult
{
    List<IPerson> Persons { get; set; }
}
public class PersonResult : IPersonResult
    {
        [JsonConverter(typeof(JsonListInterfaceConverter<IPerson, Person>))]
        public List<IPerson> Persons { get; set; }
        [JsonConverter(typeof(JsonListInterfaceConverter<ITask, Task>))]
        public List<ITask> Tasks { get; set; }
    }

现在,当我将其描述为如下所示时,它正好给了我想要的东西

IPersonResult person = JsonConvert.DeserializeObject<PersonResult>(personResultJSON);

最新更新