2016-04-07 22 views
0

Es gibt Tonnen von Informationen über das Überspringen von Eigenschaften basierend auf Bedingungen, aber ich möchte das gesamte Objekt basierend auf Bedingungen innerhalb der Objektklasse überspringen. Ich hätte gerne eine Lösung, die möglichst in der Klasse des Objekts enthalten ist. Denken Sie daran, dies ist eine Sammlung von myObj, die ich serialisieren.Bedingte serialisieren eines Objekts in einer Sammlung mit Json.net

public class myObj 
{ 
    bool conditional; 
    ShouldSerialize() 
    { 
     return conditional; 
    } 
} 

Oder

public class myObj 
{ 
    [JsonCondition] 
    public bool conditional{get;} 
} 

Oder sogar

[JsonCondition(typeof(MyConditionChecker))] 
public class myObj 
{ 
    public bool conditional{get;} 
} 

class MyConditionChecker: JsonCondition 
{ 
    public override bool CanConvert(object sourceObj) 
    { 
     return (sourceObj as myObj).conditional; 
    } 
} 
+0

Beachten Sie, dass die Verwendung öffentlicher Felder eine schlechte Übung ist. –

+0

@ErikPhilips ist nur ein Modell, nicht repräsentativ für meinen tatsächlichen Code. – Wobbles

Antwort

1

Was ich von Ihren Kommentaren bekommen habe, wäre es am besten, wenn Sie Ihren eigenen Wrapper um Json erstellen, der die Filterung anwendet.

Sie können die Schnittstelle auch durch einen Reflexionsansatz ersetzen, beachten Sie jedoch den Leistungsverlust.

public interface IConiditionChecker 
{ 
    bool ShouldBeSerialized(object instance); 
} 

public class ConditionAttribute : Attribute 
{ 
    public Type ConditionChecker { get; set; } 
} 

public static class FilteredSerializer 
{ 
    public static string SerializeConditional(IEnumerable<object> input) 
    { 
     var matches = (from entry in input 
         let att = entry.GetType().GetCustomAttribute<ConditionAttribute>() 
         let hasChecker = att != null && att.ConditionChecker != null 
         let checker = hasChecker ? (IConiditionChecker)Activator.CreateInstance(att.ConditionChecker) : null 
         where checker.ShouldBeSerialized(entry) 
         select entry); 
     return JsonConvert.SerializeObject(matches); 
    } 
} 

[Condition(ConditionChecker = typeof(SomeChecker))] 
public class Demo 
{ 
} 

Edit: Basierend auf Ihren Kommentar, den Sie dies tun könnte. Nur muss entscheiden, ob Opt-In oder Opt-Out in der where -Statement verwendet werden soll. Es muss casted != null && casted.ShouldBeSerialized sein oder was es gerade sagt.

public interface IShouldBeSerialized 
{ 
    bool ShouldBeSerialized(); 
} 

public static class FilteredSerializer 
{ 
    public static string SerializeConditional(IEnumerable<object> input) 
    { 
     var matches = (from entry in input 
         let casted = entry as IShouldBeSerialized 
         where casted == null || casted.ShouldBeSerialized() 
         select entry); 
     return JsonConvert.SerializeObject(matches); 
    } 
} 

public class Demo : IShouldBeSerialized 
{ 
    public bool ShouldBeSerialized() 
    { 
     return false; 
    } 
} 
+0

Der zweite Ansatz ist faszinierend, ich würde es wahrscheinlich vereinfachen, indem ich eine Schnittstelle 'IShouldSerialize' direkt auf die Klasse anwende. Dann überprüfe einfach die Objekttypen und überprüfe die Eigenschaft, wenn sie meine Schnittstelle implementiert. Dadurch bleibt es in meiner gesamten Anwendung wiederverwendbar, was ich mag. – Wobbles

+0

Aktualisierte die Antwort. – Toxantron

-1

Wenn Sie in der Lage, die JSON.NET Serializer zu verwenden, in Bezug auf die nicht bestimmte Elemente innerhalb einer Sammlung Serialisierung, könnten Sie Machen Sie die Hauptsammlung nicht serialisierbar und fügen Sie dann eine weitere gefilterte Sammlung hinzu, die serialisiert.

public class Manager 
{ 
    [JsonIgnore] 
    public Employee[] Employees { get; set; } 

    [JsonProperty("Employees")] 
    public Employee[] SerializableEmployees 
    { 
     get { return Employees.Where(e => e.Name != "Bob").ToArray(); } 
     set { Employees = value; } 
    } 
} 

Alternativ können Sie Ihre Klasse mit dem [JsonConverter] Attribut markieren und einen benutzerdefinierten Konverter Ihren Zustand zu überprüfen. Ein ähnlicher Ansatz, der ignores a class entirely is detailed here.

+0

Es geht um die Serialisierung von Eigenschaften, die ich in meinem allerersten mir bekannten Satz sage. Ich versuche, das gesamte "myObj" in einer Sammlung von "myObj" zu überspringen, die nicht in einem anderen Objekt eingeschlossen oder enthalten ist. – Wobbles

+0

Und warum nicht LinQ oder schreiben Sie Ihre eigene Erweiterung? – Toxantron

+0

@Toxantron Linq ist, was ich jetzt tue, hatte gehofft, eine Klassenobjekt JSon native Funktion zu finden, die ich dazu nutzen könnte, dies zu tun. Json hat alles andere, was ich mir vorstellen konnte, nur ein bisschen überrascht, etwas nicht zu sehen, das ich einbauen konnte. – Wobbles

Verwandte Themen