用Newtonsoft JSON反序列化IList对象

本文关键字:IList 对象 反序列化 JSON Newtonsoft | 更新日期: 2023-09-27 18:04:00

我使用一个ConcreteCollectionTypeConverter来反序列化类型为IList的对象。我可能做得很错,因为我一直得到异常"Cannot convert List to IList"

我的对象接口看起来像这样:

[JsonObject(MemberSerialization.OptIn)]
public IMyInterface {
    [JsonProperty("associatedContact")]
    [JsonConverter(typeof(ConcreteCollectionTypeConverter<IList<ISomeOtherInterface>, List<SomeOtherInterface>>))]
    IList<ISomeOtherInterface> MyObject { get; set; }
}

我的对象实现是这样的:

public MyImplementation : IMyInterface {
    public List<SomeOtherImplementation> MyObject { get; set; }
    public MyImplementations () {
        MyObject = new List<SomeOtherImplementation>();          
    }
}

我的Json转换器是这样的:

class ConcreteCollectionTypeConverter<TInterface, TImplementation> : JsonConverter where TImplementation : TInterface
{
    public override bool CanConvert(Type objectType)
    {
        return true;
    }
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        serializer.Serialize(writer, value);
    }
    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        return serializer.Deserialize<TImplementation>(reader);
    }
}

我在项目的其他地方像这样调用反序列化方法:

var myDeserializedObject = JsonConvert.DeserializeObject<MyImplementation>(jsonObject.ToString());

上面提到的jsonObject被正确解析了。

我知道这是可能的,因为我在这里看到一个用户在SO上的评论,他说他已经这样做了(在JSON中强制转换反序列化接口)。. NET -被接受的答案的第一个注释)。

此方法适用于非集合项(即使用JsonConverer(typeof(ConcreteTypeCOnverter))对接口类型IIterface MyObject的对象进行反序列化)。

如果我只使用列表而不是列表,我甚至不需要类型转换器,但我的要求是确保使用iccollections,因为可能存在非标准实现。

用Newtonsoft JSON反序列化IList对象

我相信这会满足你的需要:

public class ConcreteListTypeConverter<TInterface, TImplementation> : JsonConverter where TImplementation : TInterface 
{
    public override bool CanConvert(Type objectType)
    {
        return true;
    }
    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        var res = serializer.Deserialize<List<TImplementation>>(reader);
        return res.ConvertAll(x => (TInterface) x);
    }
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        serializer.Serialize(writer, value);
    }
}