2012-08-31 33 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}); 
相關問題