我从服务中接收JSON,这是一组搜索结果。 “结果”数组中的每个对象可以是两种类型的对象之一(我的例子是cat / dog)。以下是JSON的一些示例:
{
"total": 2,
"results": [
{
"type": "cat",
"id": "1",
"name": "Kitty"
},
{
"type": "dog",
"id": "2",
"name": "Rover",
"cat": {
"id": "3",
"name": "Missy"
}
}
]
}
我将JSON根对象反序列化为“SearchResult”。 "结果"中的每个项目是一个“SearchResultItem”。
这是我的模特喜欢的项目:
public class Cat : SearchResultItem
{
public string id {get; set;}
public string name {get; set;}
}
public class Dog : SearchResultItem
{
public string id {get; set;}
public string name {get; set;}
public Cat {get; set;}
}
我已经创建了一个自定义转换器,可以为每个对象转换为正确的类型:
public class SearchResultConverter : Newtonsoft.Json.Converters.CustomCreationConverter<SearchResultItem>
{
public override SearchResultItem Create(Type objectType)
{
throw new NotImplementedException();
}
public SearchResultItem Create(Type objectType, JObject jObject)
{
var type = (string)jObject.Property("type");
switch (type)
{
case "cat":
return new Cat();
case "dog":
return new Dog();
}
return null;
//throw new ApplicationException(String.Format("The given vehicle type {0} is not supported!", type));
}
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
var target = Create(objectType, jObject);
// Populate the object properties
serializer.Populate(jObject.CreateReader(), target);
return target;
}
}
我遇到的问题是,狗碰巧有一个猫项目。我的转换器捕获此Cat对象并尝试转换它。只有结果对象具有“type”属性,子Cat或Dog的任何实例都不具有此“type”属性。缺少此属性会导致Null引用异常。
如何将转换器仅限制为“results”数组中的顶级项目?
答案 0 :(得分:1)
执行此操作最简单的方法可能是覆盖JsonConverter.CanConvert
并在typeof(SearchResultItem) == objectType
时返回true,而不是从 objectType
分配时:
public class SearchResultConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(SearchResultItem);
}
public override bool CanWrite
{
get { return false; }
}
public SearchResultItem Create(Type objectType, JObject jObject)
{
// As before
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
// As before
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotSupportedException("SearchResultConverter should only be used while deserializing.");
}
}
现在只有在尝试反序列化SearchResultItem
的实例时才会调用转换器。对于已声明属于Dog
或Cat
类型的成员,其ReadJson()
方法将不会被调用。