如何从JSON创建具有不同对象类型的列表 [英] How to create a list with different object type from json

查看:499
本文介绍了如何从JSON创建具有不同对象类型的列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想从json创建不同对象类型的列表(具有相同的父对象).

I would like to create a list of different object types (with the same parent) from a json.

我有一些型号

public class Quote
{
    public virtual ICollection<QuoteLine> QuoteLines { get; set; }
}

public class QuoteLine
{
    public int Order { get; set; }
}

public class A : QuoteLine
{
    public string PropertyA { get; set; }
}

public class B : QuoteLine
{
    public string PropertyB { get; set; }
}

引号包含引号行的集合,可以使用A或B键入

A quote have a collection of QuoteLines which can be A or B typed

我可以做这样的事情

Quote quote = new Quote{
    QuoteLines = new List<QuoteLine>{
        new A { Order = 1, PropertyA = "propA"},
        new B { Order = 2, PropertyB = "propB"},
    }
}

我想换一种方式 我有一个这样的Json(从HttpClient.GetAsync()返回)

I want to do this in the other way I have a Json like this (return from a HttpClient.GetAsync())

{"quoteLines":[
    {"order":1,"propertyA":"propA"},
    {"order":2,"propertyB":"propB"}
]}

当我将其反序列化为Quote时,我失去了children属性. 我知道这是因为我有一个类型为QuoteLine的集合,所以不会反序列化children属性.但是我正在寻找一种保留所有信息的方法.

when I deserialize it into Quote, I loose the children properties. I understand it's because I have a collection typed QuoteLine so the children properties aren't deserialized. But I'm looking for a way to keep all informations.

我正在打的电话:

    public async Task<Quote> GetById(int id)
    {
        Quote quote = null;

        HttpResponseMessage response = await httpClient.GetAsync(new StringBuilder(controllerName).Append("/").Append(id).ToString());
        if (response.IsSuccessStatusCode)
        {
            quote = await response.Content.ReadAsAsync<Quote>();
        }

        return quote;
    }

感谢您的帮助.

推荐答案

我找到了一个更好的解决方案,它不会在json中公开名称空间和应用程序组装.

I found a better solution which doesn't expose namespace and app assembly in the json.

仅在客户端应用中. 我添加了一个自定义的JsonConverter:

only in the client app. I added a custom JsonConverter:

public abstract class JsonCreationConverter<T> : JsonConverter
    where T : class
{
    public override bool CanWrite
    {
        get
        {
            return false;
        }
    }

    protected abstract T Create(Type objectType, JObject jObject);

    public override bool CanConvert(Type objectType)
    {
        return typeof(T).IsAssignableFrom(objectType);
    }


    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        if (reader == null) throw new ArgumentNullException("reader");
        if (serializer == null) throw new ArgumentNullException("serializer");
        if (reader.TokenType == JsonToken.Null)
            return null;

        JObject jObject = JObject.Load(reader);
        T target = Create(objectType, jObject);
        serializer.Populate(jObject.CreateReader(), target);
        return target;
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }

对于每个派生的实体:

public class QuoteLineJsonConverter : JsonCreationConverter<QuoteLine>
{
    protected override QuoteLine Create(Type objectType, JObject jObject)
    {
        if (jObject == null) throw new ArgumentNullException("jObject");
        string discriminator = jObject.GetValue("Discriminator", StringComparison.OrdinalIgnoreCase)?.Value<string>();
        if (discriminator != null)
        {

            switch (discriminator)
            {
                case "A":
                    return new A();
                case "B":
                    return new B();
                default:
                    return new QuoteLine();
            }
        }
        else
        {
            return new QuoteLine();
        }
    }
}

我只需要向模型添加数据属性即可触发自定义转换器

And I only need to add a data attribute to my model to fire the custom converter

[JsonConverter(typeof(QuoteLineJsonConverter))]
public class QuoteLine
{
    public int Order { get; set; }
}

对jquery ajax请求非常重视,您需要将数据作为Json发送以调用自定义JsonConverter.

Be carreful with jquery ajax request, you need to send the data as Json to call the custom JsonConverter.

        $.ajax({
            url: "myUrl",
            type: "post",
            cache: false,
            data: JSON.stringify(data),
            dataType: "json",
            contentType: "application/json; charset=utf-8"
        });

这篇关于如何从JSON创建具有不同对象类型的列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆