2017-02-13 97 views
0

我想弄清楚如何使用自定義JsonConverter作爲屬性。問題是我無法弄清楚如何在轉換器中獲取FOO對象。自定義JsonConverter屬性

[Newtonsoft.Json.JsonConverter(typeof(FOOConverter))] 
public interface IFOO 
{ 
    ... 
} 


public class FOOConverter : Newtonsoft.Json.JsonConverter 
{ 
    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
    { 
     var jobj = serializer.Deserialize<JObject>(reader); 
     ... 
     var foo = jobj.ToObject<IFOO>() // Calls the converter again? 
    } 
} 

的.ToObject()將再次運行轉換器,並導致堆棧溢出,這是有道理的,因爲它看起來的屬性,但我怎麼能得到IFoo的對象呢?編輯:WriteJson將是simular,但與JObject.FromObject(值);

使用需要靈活,例如:某些屬性可能在序列化過程中被加密/加密,其他時候,可能存在需要緩存的屬性值。想想幾個用例。

回答

0

JSON類:

[KnownType(typeof(B))] 
public class A 
{ 
    public string Name { get; set; } 
} 

public class B : A 
{ 
    public string LastName { get; set; } 
} 

轉換代碼:

public class KnownTypeConverter : JsonConverter 
    { 
     public override bool CanConvert(Type objectType) 
     { 
      return System.Attribute.GetCustomAttributes(objectType).Any(v => v is KnownTypeAttribute); 
     } 

     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 
      System.Attribute[] attrs = System.Attribute.GetCustomAttributes(objectType); // Reflection. 

       // Displaying output. 
      foreach (System.Attribute attr in attrs) 
      { 
       if (attr is KnownTypeAttribute) 
       { 
        KnownTypeAttribute k = (KnownTypeAttribute) attr; 
        var props = k.Type.GetProperties(); 
        bool found = true; 
        foreach (var f in jObject) 
        { 
         if (!props.Any(z => z.Name == f.Key)) 
         { 
          found = false; 
          break; 
         } 
        } 

        if (found) 
        { 
         var target = Activator.CreateInstance(k.Type); 
         serializer.Populate(jObject.CreateReader(),target); 
         return target; 
        } 
       } 
      } 
      throw new ObjectNotFoundException(); 


      // Populate the object properties 

     } 

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

用法:

var ret = JsonConvert.DeserializeObject<A>(json, new KnownTypeConverter()); 
+0

感謝您的想法,與Activator.CreateInstance的問題是,WriteJson我也內需要使用JObject.FromObject來轉換的IFoo對象。 FromObject與ToObject相同 – user1714341