2017-04-19 1 views
1

Mein Ziel ist es, Eigenschaften zu serialisieren, die keine Attribute und Eigenschaften haben, die ein bestimmtes benutzerdefiniertes Attribut haben.Benutzerdefinierte Attributbehandlung in Json.Net

Für die folgende Klasse:

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

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

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

Wenn ich eine Methode Serialize(object, CustomAttributeA) nennen, möchte ich die folgende Ausgabe haben:

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

Und wenn ich Serialize(object, CustomAttributeB) nennen, möchte ich folgendes haben:

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

Ich habe gelesen, dass es möglich ist, zu erreichen dies durch Erstellen einer benutzerdefinierten ContractResolver, aber in diesem Fall muss ich zwei separate Vertragsresolver erstellen?

Antwort

3

Sie benötigen keine zwei separaten Resolver, um Ihr Ziel zu erreichen. Machen Sie einfach die benutzerdefinierte ContractResolver generische, wo der Typ Parameter das Attribut darstellt, nach dem Sie beim Serialisieren suchen.

Zum Beispiel:

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; 
    } 
} 

Dann können Sie eine Hilfsmethode machen den Resolver und serialisiert Ihr Objekt zu erstellen:

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); 
} 

Wenn Sie serialisieren möchten, rufen Sie die Helfer wie folgt aus:

string json = Serialize<CustomAttributeA>(msg); 

Demo Geige: https://dotnetfiddle.net/bRHbLy

+0

Sie könnten auch diese generische - IMO ein wenig schöner 'Serialize (Obj)' und 'Serialize (Obj);' – Jamiec

+0

@Jamiec Gute Vorschlag. Ich werde meine Antwort aktualisieren. –

+0

Große Antwort BTW! – Jamiec

Verwandte Themen