2017-04-19 15 views
1

私の目標は、特定のカスタム属性を持つ属性とプロパティを持たないプロパティをシリアル化することです。Json.Netのカスタム属性処理

次のクラスについては

public class Msg 
{ 
    public long Id { get; set; } 

    [CustomAttributeA] 
    public string Text { get; set; } 

    [CustomAttributeB] 
    public string Status { get; set; } 
} 

私はメソッドSerialize(object, CustomAttributeA)を呼び出すと、私は次のような出力を持つようにしたい:

{ 
    "Id" : someId, 
    "Text" : "some text" 
} 

そして、私はSerialize(object, CustomAttributeB)を呼び出すときに、私は次のことをしたいです:

{ 
    "Id" : someId, 
    "Status" : "some status" 
} 

私は、これはカスタムContractResolverを作成することによって行いますが、この場合、2つの別個の契約リゾルバを作成する必要がありますか?

答えて

3

目的を達成するために2つの別々のリゾルバは必要ありません。カスタムContractResolver genericを作成します。ここで、typeパラメーターは、シリアル化するときに探している属性を表します。例えば

public class CustomResolver<T> : DefaultContractResolver where T : Attribute 
{ 
    protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization) 
    { 
     IList<JsonProperty> list = base.CreateProperties(type, memberSerialization); 

     foreach (JsonProperty prop in list) 
     { 
      PropertyInfo pi = type.GetProperty(prop.UnderlyingName); 
      if (pi != null) 
      { 
       // if the property has any attribute other than 
       // the specific one we are seeking, don't serialize it 
       if (pi.GetCustomAttributes().Any() && 
        pi.GetCustomAttribute<T>() == null) 
       { 
        prop.ShouldSerialize = obj => false; 
       } 
      } 
     } 

     return list; 
    } 
} 

その後、あなたはリゾルバを作成し、オブジェクトをシリアル化するためのヘルパーメソッドを行うことができます。

public static string Serialize<T>(object obj) where T : Attribute 
{ 
    JsonSerializerSettings settings = new JsonSerializerSettings 
    { 
     ContractResolver = new CustomResolver<T>(), 
     Formatting = Formatting.Indented 
    }; 
    return JsonConvert.SerializeObject(obj, settings); 
} 

あなたがシリアライズしたい場合は、次のようにヘルパーを呼び出します。

string json = Serialize<CustomAttributeA>(msg); 

デモフィドル:https://dotnetfiddle.net/bRHbLy

+0

また、この一般的なIMOをちょっとした 'Serialize (obj)'と 'Serialize (obj);' – Jamiec

+0

@Jamiecの良い提案にすることもできます。私は私の答えを更新します。 –

+0

偉大な答えはこちら – Jamiec