使用Newtonsoft.Json,我怎么反序列化JSON一类含有接口类型一个IEnumerable的财产?接口类型、财产、我怎么、序列化

由网友(正太脸大叔心°)分享简介:我耗费了RESTful Web服务发送JSON,我尝试使用 HttpContent.ReadAsAsync&LT反序列化; T> 。我尝试反序列化的类型声明,它返回一个IEnumerable包含一个接口类型的属性。这code片段演示的那种类型,我尝试反序列化的:I am consuming a RESTful...

我耗费了RESTful Web服务发送JSON,我尝试使用 HttpContent.ReadAsAsync&LT反序列化; T> 。我尝试反序列化的类型声明,它返回一个IEnumerable包含一个接口类型的属性。这code片段演示的那种类型,我尝试反序列化的:

I am consuming a RESTful Web service sending JSON, that I try to deserialize using HttpContent.ReadAsAsync<T>. The type I try to deserialize to declares a property that returns an IEnumerable containing an interface type. This code snippet demonstrates the kind of type I'm trying to deserialize to:

public class Data
{
    public IEnumerable<IChild> Children { get; set; };
}

问题是,Newtonsoft.Json,基本 HttpContent.ReadAsAsync&LT; T&GT; 不知道如何反序列化类型的对象 ICHILD ,后者是一个接口。我怎么可以指定Newtonsoft.Json如何反序列化ICHILD到一个具体类型?

The problem is that Newtonsoft.Json, underlying HttpContent.ReadAsAsync<T> doesn't understand how to deserialize objects of type IChild, the latter being an interface. How can I specify to Newtonsoft.Json how to deserialize IChild to a concrete type?

推荐答案

您可以使用自定义转换来告诉JSON.NET如何反序列化类型的接口。在code以下给出了一个例子。

You can use a custom Converter to tell JSON.NET how to deserialize types of that interface. The code below shows an example.

public class StackOverflow_12197892
{
    public class Data
    {
        public IEnumerable<IChild> Children { get; set; }

        public override string ToString()
        {
            return string.Format("Data{{Children=[{0}]}}",
                string.Join(", ", Children.Select(c => string.Format("{0}/{1}", c.Name, c.IsFemale ? "girl" : "boy"))));
        }
    }
    public interface IChild
    {
        string Name { get; }
        bool IsFemale { get; }
    }
    public class Son : IChild
    {
        public Son(string name)
        {
            this.Name = name;
        }

        public string Name { get; private set; }
        public bool IsFemale { get { return false; } }
    }
    public class Daughter : IChild
    {
        public Daughter(string name)
        {
            this.Name = name;
        }

        public string Name { get; private set; }
        public bool IsFemale { get { return true; } }
    }
    class ChildConverter : Newtonsoft.Json.JsonConverter
    {
        public override bool CanConvert(Type objectType)
        {
            return typeof(IChild).IsAssignableFrom(objectType);
        }

        public override object ReadJson(Newtonsoft.Json.JsonReader reader, Type objectType, object existingValue, Newtonsoft.Json.JsonSerializer serializer)
        {
            JObject obj = serializer.Deserialize<JToken>(reader) as JObject;
            if (obj != null)
            {
                bool isFemale = obj["isFemale"].ToObject<bool>();
                string name = obj["name"].ToObject<string>();
                if (isFemale)
                {
                    return new Daughter(name);
                }
                else
                {
                    return new Son(name);
                }
            }
            else
            {
                return null;
            }
        }

        public override void WriteJson(Newtonsoft.Json.JsonWriter writer, object value, Newtonsoft.Json.JsonSerializer serializer)
        {
            throw new NotImplementedException();
        }
    }
    public static void Test()
    {
        Newtonsoft.Json.JsonSerializer serializer = new Newtonsoft.Json.JsonSerializer();
        serializer.Converters.Add(new ChildConverter());
        string json = "{'Children':[{'name':'John',isFemale:false},{'name':'Mary',isFemale:true}]}".Replace(''', '"');
        var obj = serializer.Deserialize(new StringReader(json), typeof(Data));
        Console.WriteLine(obj);
    }
}
阅读全文

相关推荐

最新文章