防止 JSON.Net 自定义转换器转换子对象



我正在从一组搜索结果的服务接收JSON。"结果"数组中的每个对象都可以是两种类型的对象之一(猫/狗我的例子)。下面是一些示例 JSON:

{
  "total": 2,
  "results": [
    {
      "type": "cat",
      "id": "1",
      "name": "Kitty"
    },
    {
      "type": "dog",
      "id": "2",
      "name": "Rover",
      "cat": {
        "id": "3",
        "name": "Missy"
      }
    }
  ]
} 

我正在将 JSON 根对象反序列化为"搜索结果"。"结果"中的每个项目都是一个"搜索结果项目"。

以下是我的模型喜欢这些物品的方式:

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 对象并尝试对其进行转换。只有结果对象具有"类型"属性,子 Cat 或 Dog 的任何实例都没有此"类型"属性。缺少此属性会导致空引用异常。

如何将转换器限制为仅"结果"数组中的顶级项目?

可能最简单的方法是覆盖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 的实例时,才会调用转换器。 对于已声明为 DogCat 类型的成员,将不会调用其 ReadJson() 方法。

相关内容

  • 没有找到相关文章

最新更新