2017-08-11 2 views
2

Ich habe eine Klasse, die ich nicht ändern kann:Wie auch immer, um JsonConvert.SerializeObject zu erhalten, um das JsonConverter-Attribut für eine Eigenschaft zu ignorieren?

public enum MyEnum { 
    Item1 = 0, 
    Item2 = 1 
} 
public class foo { 
    [JsonConverter(typeof(StringEnumConverter))] 
    public MyEnum EnumTypes {get; set; } 
} 

irgendwo auf der ganzen Linie JsonConvert.SerializeObject serialisiert das Objekt und wegen der JsonConverter Attribut, spuckt es für den foo.EnumTypes Namen des ENUM-Wert, anstatt die Anzahl.

Gibt es trotzdem JsonConvert.SerializeObject, um das Attribut auf der EnumTypes Eigenschaft zu ignorieren?

+0

Ich denke, es hängt davon ab, wie Sie die Foo-Klasse verwenden, wenn Sie sind buchstäblich nur eine Instanz von foo selbst Serialisierung dann könnten Sie implementieren eine Version der Klasse, die den StringEnumConverter im EnumTypes-Feld nicht verwendet und die Feldwerte vor der Serialisierung kopiert. Könnten Sie mehr Informationen bereitstellen, um der Frage mehr Kontext zu geben? – Kodaloid

Antwort

3

Dies ist möglich, aber der Prozess ist ein bisschen beteiligt.

Die Grundidee besteht darin, eine benutzerdefinierte ContractResolver zu erstellen und ihre CreateProperty-Methode zu überschreiben. So etwas wie so:

internal sealed class MyContractResolver : DefaultContractResolver 
{ 
    protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization) 
    { 
     var property = base.CreateProperty(member, memberSerialization); 

     if(member.DeclaringType == typeof(foo) && property.PropertyType == typeof(MyEnum)) 
     { 
      property.Converter = null; 
     } 

     return property; 
    } 
} 

Sie werden auch tatsächlich benötigen, um diese Klasse zu instanziiert und in Ihre Serializer/Deserializer passieren. Wie das aussieht, hängt davon ab, wie genau Sie die Serialisierung durchführen. Daher kann ich kein relevantes Anwendungsbeispiel garantieren.

Wenn Sie nur die statische SerializeObject Methode:

JsonConvert.SerializeObject(valueToSerialize, new SerializerSettings { ContractResolver = new MyContractResolver() }); 
+0

Das sieht vielversprechend aus. Wie übertrage ich es in den Serializer? Hast du ein Beispiel? – AngryHacker

+0

@AngryHacker Wie ich schon sagte, hängt es genau davon ab, wie Sie die Serialisierung machen. Es gibt verschiedene Möglichkeiten, dies zu tun. Die Dokumentation, mit der ich für 'ContractResolver' verlinkt habe, zeigt ein Beispiel für eine mögliche Vorgehensweise, aber es ist nicht die einzige Möglichkeit. Ich werde die Antwort mit einem Beispiel bearbeiten, aber ich kann nicht versprechen, dass es für Sie funktioniert. – Kyle

+0

Ich fand es heraus, 5 Sekunden nachdem ich den Kommentar gepostet habe. Es macht genau das, wofür ich es brauche. Perfekt. – AngryHacker

1

Ich glaube nicht, dass Sie können, wie es Teil der Definition ist. Sie werden das Attribut zu entfernen, und den Konverter an den Serializer Einstellungen hinzufügen:

var serializerSettings = new JsonSerializerSettings 
{ 
    NullValueHandling = NullValueHandling.Ignore, 
    DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate, 

    Converters = new List<JsonConverter> { new StringEnumConverter() }, 

    ContractResolver = new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver() 
}; 

In diesem Fall können Sie es weglassen können, wenn Sie es nicht verwenden möchten. Es gibt eine Sache, die ich vergaß zu erwähnen, hat der Wandler den Typ in CanConvert zu überprüfen:

public class StringEnumConverter: JsonConverter 
{ 
    public override bool CanConvert(Type objectType) 
    { 
     return typeof(MyEnum); 
    } 
} 

ich den Code testen nicht, aber Sie bekommen die Idee.

Verwandte Themen