2

JSON を送信する RESTful Web サービスを使用してHttpContent.ReadAsAsync<T>います。逆シリアル化しようとしている型は、インターフェイス型を含む IEnumerable を返すプロパティを宣言しています。このコード スニペットは、逆シリアル化しようとしている型の種類を示しています。

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

問題は、基になる Newtonsoft.JsonHttpContent.ReadAsAsync<T>が type のオブジェクトを逆シリアル化する方法を理解していないことIChildです。後者はインターフェイスです。IChild を具象型に逆シリアル化する方法を Newtonsoft.Json に指定するにはどうすればよいですか?

4

2 に答える 2

4

カスタムを使用してConverter、そのインターフェースのタイプを逆シリアル化する方法をJSON.NETに指示できます。以下のコードは例を示しています。

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);
    }
}
于 2012-08-30T13:39:30.940 に答える
0

これは非常にシンプルで、json.net によって提供されるすぐに使えるサポートです。シリアライズおよびデシリアライズ中に次の JsonSettings を使用するだけです。

JsonConvert.SerializeObject(graph,Formatting.None, new JsonSerializerSettings()
                                                                                               {
                                                                                                 TypeNameHandling = TypeNameHandling.Objects,
                                                                                               TypeNameAssemblyFormat = System.Runtime.Serialization.Formatters.FormatterAssemblyStyle.Simple
                                                                                           });

Deserialzing には、以下のコードを使用します。

JsonConvert.DeserializeObject(Encoding.UTF8.GetString(bData),type,
                                                       new JsonSerializerSettings()
                                                           {TypeNameHandling = TypeNameHandling.Objects});

JsonSerializerSettings オブジェクトの初期化子に注意してください。これはあなたにとって重要です。

于 2014-01-14T09:52:53.223 に答える