2017-02-13 85 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