2017-08-31 1 views
1

Ich habe Probleme mit der Serialisierung einer Eigenschaft eines Objekts, das eine Eigenschaft eines anderen Objekts selbst ist. Betrachten Sie die folgende Klassenstruktur:Bedingte ignorieren verschachtelte Eigenschaft beim Serialisieren von Objekt

public class Message 
{ 
    public string Content { get; set; } 
    public IEnumerable<Attachment> Attachments { get; set; } 
} 

public class Attachment 
{ 
    public string Base64Content { get; set; } 
    public string FileName { get; set; } 
} 

In einigen Szenarien will ich alles in der Message Klasse serialisiert werden, einschließlich aller Attachment Objekte und deren Eigenschaften. Dies kann mit einem einfachen JsonConvert.SerializeObject() erfolgen. Wenn ich die Eigenschaft Base64Content immer ignorieren wollte, könnte ich einfach ein Attribut '[JsonIgnore]' für diese Eigenschaft hinzufügen. Es gibt jedoch einige Szenarien, in denen ich die Base64Content serialisiert haben möchte, und in anderen nicht.

ich aber über eine benutzerdefinierte ContractResolver erstellen, die die Attachments Eigenschaft des Message Objekt ignoriert. Aber natürlich ignoriert dies die ganze Liste der Attachment Objekte und nicht nur die Base64Content Eigenschaft.

Gibt es eine Möglichkeit, eine ContractResolver Klasse zu schreiben, die ich die Base64Content Eigenschaft ignorieren kann, wenn das Objekt Message serialisiert?

+0

Könnten Sie neue Klassen machen, mit der gleichen Struktur und mit [JsonIgnore] nach Bedarf? Dann serialisieren Sie Ihre vorhandene Klasse, wenn Sie möchten, dass alles serialisiert wird ** oder ** ordnen Sie Ihre neue Klasse an und serialisieren Sie sie, wenn Sie nur einige Felder serialisieren möchten. – mjwills

+0

@mjwills das könnte eine Lösung sein, würde aber eine Menge (fast) doppelte Klassen für etwas, das ich hoffe, auf eine sauberere Weise zu lösen. – Froodooo

+0

Möglicherweise können Sie die Antwort von [Json.NET serialisieren nach Tiefe und Attribut] anpassen (https://stackoverflow.com/q/36159424/3744182). – dbc

Antwort

1

Erstellen Sie einfach einen benutzerdefinierten Contract Resolver, der die Eigenschaften ausschließt, die während der Serialisierung an ihn übergeben wurden, und übergeben Sie die Base64Content-Eigenschaft bedingungslos.

public class CustomPropertiesContractResolver : DefaultContractResolver 
{ 
    private HashSet<string> _propertySet; 

    public CustomPropertiesContractResolver(IEnumerable<string> propertyNames) 
    { 
     if (propertyNames != null) 
     { 
      _propertySet = new HashSet<string>(propertyNames, StringComparer.OrdinalIgnoreCase); 
     } 
    } 

    protected override List<MemberInfo> GetSerializableMembers(Type objectType) 
    { 
     List<MemberInfo> serializableMembers = null; 
     var allMembers = base.GetSerializableMembers(objectType); 

     if (_propertySet != null && _propertySet.Count > 0) 
     { 
      serializableMembers = allMembers.Where(m => !_propertySet.Contains(m.Name)).ToList(); 
     } 
     return serializableMembers != null && serializableMembers.Count > 0 ? serializableMembers : allMembers; 
    } 
} 

verwenden Sie es wie:

IEnumerable<string> properties = null; 
if (condition) 
{ 
    properties = new List<string> { "Base64Content" }; 
} 

var settings = new JsonSerializerSettings() 
{ 
    ContractResolver = new CustomPropertiesContractResolver(properties) 
}; 
var serializedStr = JsonConvert.SerializeObject(messages, settings); 
Verwandte Themen