JSON反序列化器继承了泛型类型

时间:2015-09-21 11:49:09

标签: c# json generics serialization json.net

我将一些JSON字符串反序列化为c#对象时遇到问题。

我们假设我有以下代码:

public class A
{
    public string Name { get; set; }
}

public class B : A
{
    public int Age { get; set; }
}

public class C
{
    public ObservableCollection<A> As
    {
        get;
        set;
    }
}

我序列化了以下对象_c

C _c = new C();
_c.As.Add(new B() { Name = "Max", Age = 4 });

这很有效。

但是我无法反序列化创建的JSON字符串并创建B的实例,因为ObservableCollection声明为A作为泛型类型。有没有办法告诉Newtonsoft.Json使用B代替A

非常感谢。

2 个答案:

答案 0 :(得分:1)

解决了编写自定义JsonConverter的问题:

public class BCJsonConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return true;
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        var currentType = (existingValue as System.Collections.ObjectModel.ObservableCollection<A>);

        currentType.Clear();

        var des = serializer.Deserialize<IList<B>>(reader);

        foreach (var toAdd in des)
        {
            currentType.Add(toAdd);
        }

        return currentType;
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        serializer.Serialize(writer, value);
    }
}

public class C
{
    public virtual ObservableCollection<A> As
    {
        get;
        set;
    }
}

public class D : C
{
    [Newtonsoft.Json.JsonConverter(typeof(BCJsonConverter))]
    public override ObservableCollection<A> As
    {
        get;
        set;
    }
}

答案 1 :(得分:1)

似乎你解决了它,但你可以通过更改类public class C<T> where T : A { private ObservableCollection<T> _as = new ObservableCollection<T>(); public ObservableCollection<T> As { get { return _as; } set { _as = value; } } } 约束来实现相同的功能,而无需使用任何自定义JSON转换器。见下文:

var _c = new C<B>();
_c.As.Add(new B() { Name = "Max", Age = 4 });

var serialized = JsonConvert.SerializeObject(_c);
var deserialized = JsonConvert.DeserializeObject<C<B>>(serialized); // B

然后de / serialize like

string from = test@test.com;
string to = test123@testing.com;
string to1 =test1234@testing.com;

mail.From = new System.Net.Mail.MailAddress(from);
mail.To.Add(new System.Net.Mail.MailAddress(to));
mail.To.Add(new System.Net.Mail.MailAddress(to1));