JSonConverter如何进行通用反序列化

时间:2017-06-16 12:27:28

标签: c# json asp.net-core json.net deserialization

我已经能够做一个转换为接口列表的自定义转换器。

这是我的自定义转换器:

public class InvoiceDetailConverter : JsonConverter {
    public override bool CanConvert(Type objectType) {
        //assume we can convert to anything for now
        return true;
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) {
        List<InvoiceDetail> data = serializer.Deserialize<List<InvoiceDetail>>(reader);

        // now loop to make the proper list
        List<IInvoiceDetail> result = new List<IInvoiceDetail>();
        foreach (IInvoiceDetail d in data) {
            result.Add(d);
        }

        return result;
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) {
        //use the default serialization - it works fine
        serializer.Serialize(writer, value);
    }
}

我想要的是使这个通用像

public class InvoiceDetailConverter <TConcrete, TInterface> : JsonConverter {
    public override bool CanConvert(Type objectType) {
        //assume we can convert to anything for now
        return true;
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) {
        List<TConcrete> data = serializer.Deserialize<List<TConcrete>>(reader);

        // now loop to make the proper list
        List<TInterface> result = new List<TInterface>();
        foreach (TInterface d in data) {
            result.Add(d);
        }
        return result;
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) {
        //use the default serialization - it works fine
        serializer.Serialize(writer, value);
    }
}

在我的对象的结尾,它将像这样使用:

public class test{
    [JsonConverter(typeof(InvoiceDetailConverter<InvoiceDetail, IInvoiceDetail>))]
    public List<IInvoiceDetail> InvoiceDetail { get; set; }
}

是否可以像这样转换,因为上面的代码不会编译。我使用的是.NET Core。

1 个答案:

答案 0 :(得分:3)

我相信你几乎就在那里,只需指定TConcreteTInterface之间的依赖关系:

public class InvoiceDetailConverter<TConcrete, TInterface> : JsonConverter
    where TConcrete : TInterface    // <------------------------------------------ add this
{
    // ..........
}

Here您可以使用通用转换器类为以下对象找到成功反序列化的演示:

public class test
{
    [JsonConverter(typeof(InvoiceDetailConverter<InvoiceDetail, IInvoiceDetail>))]
    public List<IInvoiceDetail> InvoiceDetail { get; set; }

    [JsonConverter(typeof(InvoiceDetailConverter<VatDetail, IVatDetail>))]
    public List<IVatDetail> VatDetail { get; set; }
}