我正在使用发送JSON的RESTful Web服务,我尝试使用HttpContent.ReadAsAsync<T>
反序列化。我尝试反序列化的类型声明一个返回包含接口类型的IEnumerable的属性。此代码段演示了我尝试反序列化的类型:
public class Data
{
public IEnumerable<IChild> Children { get; set; };
}
问题是,底层HttpContent.ReadAsAsync<T>
的Newtonsoft.Json不了解如何反序列化IChild
类型的对象,后者是一个接口。如何指定Newtonsoft.Json如何将IChild反序列化为具体类型?
答案 0 :(得分: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);
}
}
答案 1 :(得分: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对象初始化程序,这对您很重要。