2015-05-05 62 views
0

我想序列化只使用json.net類的繼承屬性。我知道[JsonIgnore]屬性,但我只想在某些場合忽略它們,所以我使用了一個自定義的JsonConverter。如何序列化只使用JsonConverter的類的繼承屬性

這裏是我的類:

public class EverythingButBaseJsonConverter : JsonConverter 
{ 
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
    { 
     // Find properties of inherited class 
     var classType = value.GetType(); 
     var classProps = classType.GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).ToList(); 

     // Remove the overrided properties 
     classProps.RemoveAll(t => 
     { 
      var getMethod = t.GetGetMethod(false); 
      return (getMethod.GetBaseDefinition() != getMethod); 
     }); 

     // Get json data 
     var o = (JObject)JToken.FromObject(value); 

     // Write only properties from inhertied class 
     foreach (var p in o.Properties().Where(p => classProps.Select(t => t.Name).Contains(p.Name))) 
      p.WriteTo(writer); 
    } 

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
    { 
     throw new NotImplementedException(""); 
    } 

    public override bool CanRead 
    { 
     get { return false; } 
    } 

    public override bool CanConvert(Type objectType) 
    { 
     return true; 
    } 
} 

如果做一個簡單的o.WriteTo(作家);它給出了與不使用轉換器相同的結果。當遍歷屬性並在屬性上使用WriteTo時,它對基本類型(int,string等)工作正常,但我遇到了集合問題。

預計:

{ 
    "Type": 128, 
    "Time": [ 
    1, 
    2, 
    ], 
    "Pattern": 1, 
    "Description": "" 
} 

了:

"Type": 128, 
    "Time": [ 
    1, 
    2, 
    ]"Pattern": 1, 
    "Description": "" 

正如你所看到的,收集丟失的 「」 和底線部分。我也錯過了整個對象的全局{}。

我正在做事情的正確方法?有沒有更簡單的方法來獲得我想要的結果?

回答

2

不知道爲什麼你的代碼不起作用(也許是一個Json.NET錯誤?)。相反,你可以刪除你不從JObject所需的屬性,寫了整個事情的一個電話:

public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
    { 
     // Find properties of inherited class 
     var classType = value.GetType(); 
     var classProps = classType.GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).ToList(); 

     // Remove the overrided properties 
     classProps.RemoveAll(t => 
     { 
      var getMethod = t.GetGetMethod(false); 
      return (getMethod.GetBaseDefinition() != getMethod); 
     }); 

     // Get json data 
     var o = (JObject)JToken.FromObject(value); 

     // Remove all base properties 
     foreach (var p in o.Properties().Where(p => !classProps.Select(t => t.Name).Contains(p.Name)).ToList()) 
      p.Remove(); 

     o.WriteTo(writer); 
    } 

或者,你可以創建自己的contract resolver並篩選出基本屬性和成員:

public class EverythingButBaseContractResolver : DefaultContractResolver 
{ 
    protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization) 
    { 
     if (member.ReflectedType != member.DeclaringType) 
      return null; 
     if (member is PropertyInfo) 
     { 
      var getMethod = ((PropertyInfo)member).GetGetMethod(false); 
      if (getMethod.GetBaseDefinition() != getMethod) 
       return null; 
     } 
     var property = base.CreateProperty(member, memberSerialization); 
     return property; 
    } 
} 

,然後用它喜歡:

 var settings = new JsonSerializerSettings { ContractResolver = new EverythingButBaseContractResolver() }; 
     var json = JsonConvert.SerializeObject(rootObject, Formatting.Indented, settings); 
相關問題