2012-08-31 57 views
1

我的问题是,我需要反序列化JSON到一个类型,该类型又包含接口类型对象,因此需要指示Json.NET如何转换该接口类型,但我不直接控制Newtonsoft.Json.Deserializer。反序列化由框架代码间接处理,即由HttpContent.ReadAsAsync<T>处理。如何指示Json.NET将接口类型转换为具体类型而无需访问序列化程序?

如何指定从接口类型到具体类型的转换,但无法直接向JsonSerializer.Converters添加转换器?如果我在接口定义上使用[JsonConverter]属性,转换器也会被调用以实现接口(即,我要转换的具体类型)。

在下面的代码示出了尝试将反序列化相同的JSON首先将Parent2类,然后将Parent1类,指示Json.NET经由JsonConverterAttributeIChild1接口类型转换为Child1具体类型C#控制台程序。由于我将ChildConverter直接添加到serializer.Converters,而反序列化到Parent1会导致堆栈溢出异常,因为即使对Child1类型也调用ChildConverter.Deserialize,因此将其反序列化为Parent2

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using Newtonsoft.Json; 
using System.IO; 

namespace TestConsole 
{ 
    [JsonConverter(typeof(ChildConverter))] 
    interface IChild1 
    { 
     string Name { get; set; } 
    } 

    class Child1 : IChild1 
    { 
     public string Name { get; set; } 
    } 

    class Parent1 
    { 
     public IEnumerable<IChild1> Children { get; set; } 
    } 

    interface IChild2 
    { 
     string Name { get; set; } 
    } 

    class Child2 : IChild2 
    { 
     public string Name { get; set; } 
    } 

    class Parent2 
    { 
     public IEnumerable<IChild2> Children { get; set; } 
    } 

    class ChildConverter : JsonConverter 
    { 
     public override bool CanConvert(Type objectType) 
     { 
      return objectType == typeof(IChild1) || objectType == typeof(IChild2); 
     } 

     public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
     { 
      if (objectType == typeof(IChild1)) 
       return serializer.Deserialize<Child1>(reader); 
      return serializer.Deserialize<Child2>(reader); 
     } 

     public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
     { 
      throw new NotImplementedException(); 
     } 
    } 

    class Program 
    { 
     static void Main(string[] args) 
     { 
      var json = "{'Children': [{'Name': 'Child1'}, {'Name': 'Child2'}]}"; 

      var serializer = new JsonSerializer(); 

      serializer.Converters.Add(new ChildConverter()); 
      var obj = serializer.Deserialize(new StringReader(json), typeof(Parent2)); 

      serializer = new JsonSerializer(); 
      obj = serializer.Deserialize(new StringReader(json), typeof(Parent1)); 
     } 
    } 
} 

回答

1

我找到了解决我的具体问题,是叫HttpContent.ReadAsAsync<T>并具有反序列化JSON响应。尽管我的解决方案不能解决配置Json.NET类型转换而不访问序列化程序的一般问题,但它确实解决了我的特殊问题。我发现HttpContent.ReadAsync<T>接受​​,用于反序列化响应。这里可以通过一个JsonMediaTypeFormatter,它已经用您的JsonConverter(在我的示例中为ChildConverter)进行了配置。

var formatter = new JsonMediaTypeFormatter(); 
formatter.SerializerSettings.Converters.Add(new ChildConverter()); 
var obj = await resp.Content.ReadAsAsync<T>(new MediaTypeFormatter[] {formatter}); 
相关问题