使用JsonConvert.DeserializeObject反序列化派生对象的列表 [英] Using JsonConvert.DeserializeObject to deserialize a list of derived objects

查看:119
本文介绍了使用JsonConvert.DeserializeObject反序列化派生对象的列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这个对象

public class ConversationAPI
{
    [JsonProperty(PropertyName = "lU")]
    public DateTime LastUpdated { get; set; }

    [JsonProperty(PropertyName = "m", TypeNameHandling = TypeNameHandling.All)]
    public List<Message> Messages { get; set; }
}

我从API作为json发送,然后在客户端应用程序中反序列化.

Which I send from the API as a json and I deserialize in my Client Application.

The List<Message> Messages property contains either 

 [Serializable]
    public class Message
    {
        [JsonProperty(PropertyName = "t")]
        public string Text { get; set; }

        [JsonProperty(PropertyName = "ty")]
        public MessageType Type { get; set; }
    }

[Serializable]
    public class DerivedMessage : Message
    {
        [JsonProperty(PropertyName = "sos")]
        public string SomeOtherStuff{ get; set; }
    }

我似乎无法反序列化派生类型的数组. 我已经尝试过

I can't seem to be able to deserialize the Array of derived types. I've tried this

var settings = new JsonSerializerSettings
                    {
                        TypeNameHandling = TypeNameHandling.All,
                        TypeNameAssemblyFormat = System.Runtime.Serialization.Formatters.FormatterAssemblyStyle.Full
                    };
var conversation = JsonConvert.DeserializeObject<ConversationResponse>(response.Content, settings);

我希望列表消息同时具有 Message DerivedMessage 对象.

I would like the List Messages to have both Message and DerivedMessage objects.

有什么想法吗? 谢谢

推荐答案

找到了解决方案.我使用了自定义转换器

Found the solution. I used a custom converter

public class MessageConverter : JsonCreationConverter<ConversationAPI.Message>
{
    private const string SomeOtherStuffField = "sos";

    protected override ConversationAPI.Message Create(Type objectType, JObject jObject)
    {
        if (FieldExists(SomeOtherStuffField , jObject))
        {
            return new ConversationAPI.DerivedMessage ();
        }

        return new ConversationAPI.Message();
    }

    private bool FieldExists(string fieldName, JObject jObject)
    {
        return jObject[fieldName] != null;
    }
}

public abstract class JsonCreationConverter<T> : JsonConverter
{
    /// <summary>
    /// Create an instance of objectType, based properties in the JSON object
    /// </summary>
    /// <param name="objectType">type of object expected</param>
    /// <param name="jObject">contents of JSON object that will be deserialized</param>
    /// <returns></returns>
    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)
    {
        // Load JObject from stream
        JObject jObject = JObject.Load(reader);

        // Create target object based on JObject
        T target = Create(objectType, jObject);

        // Populate the object properties
        serializer.Populate(jObject.CreateReader(), target);

        return target;
    }

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

您将这样使用:

var jsonText = "{a string of json to convert}"
JsonConverter[] conv = new JsonConverter[] { new MessageConverter() };
var jsonResponse = JsonConvert.DeserializeObject<ConversationAPI>(jsonText, conv);

这篇关于使用JsonConvert.DeserializeObject反序列化派生对象的列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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