c# deserialize - Eine Eigenschaft deserialisieren, aber nicht mit json.net serialisieren




4 Answers

Es gibt tatsächlich einige ziemlich einfache Ansätze, die Sie verwenden können, um das gewünschte Ergebnis zu erzielen.

Nehmen wir zum Beispiel an, dass Ihre Klassen momentan wie folgt definiert sind:

class Config
{
    public Fizz ObsoleteSetting { get; set; }
    public Bang ReplacementSetting { get; set; }
}

enum Fizz { Alpha, Beta, Gamma }

class Bang
{
    public string Value { get; set; }
}

Und du willst das machen:

string json = @"{ ""ObsoleteSetting"" : ""Gamma"" }";

// deserialize
Config config = JsonConvert.DeserializeObject<Config>(json);

// migrate
config.ReplacementSetting = 
    new Bang { Value = config.ObsoleteSetting.ToString() };

// serialize
json = JsonConvert.SerializeObject(config);
Console.WriteLine(json);

Um das zu bekommen:

{"ReplacementSetting":{"Value":"Gamma"}}

Methode 1: Fügen Sie eine ShouldSerialize-Methode hinzu

Json.NET verfügt über die Möglichkeit, Eigenschaften seriell zu ShouldSerialize indem nach entsprechenden ShouldSerialize Methoden in der Klasse gesucht wird.

Um diese Funktion zu verwenden, fügen ShouldSerializeBlah() Ihrer Klasse eine boolesche Methode ShouldSerializeBlah() , wobei Blah durch den Namen der Eigenschaft ersetzt wird, die Sie nicht serialisieren möchten. Lassen Sie die Implementierung dieser Methode immer false .

class Config
{
    public Fizz ObsoleteSetting { get; set; }

    public Bang ReplacementSetting { get; set; }

    public bool ShouldSerializeObsoleteSetting()
    {
        return false;
    }
}

Hinweis: Wenn Ihnen dieser Ansatz gefällt, Sie jedoch die öffentliche Schnittstelle Ihrer Klasse nicht durch Einführung einer ShouldSerialize Methode ShouldSerialize , können Sie einen IContractResolver , um dasselbe programmatisch IContractResolver . Siehe Serialisierung von bedingten Eigenschaften in der Dokumentation.

Ansatz 2: Manipulieren Sie den JSON mit JObjects

Anstatt JsonConvert.SerializeObject für die Serialisierung zu verwenden, laden Sie das Konfigurationsobjekt in ein JObject , und entfernen Sie dann die unerwünschte Eigenschaft einfach aus dem JSON, bevor Sie sie JObject . Es sind nur ein paar zusätzliche Codezeilen.

JObject jo = JObject.FromObject(config);

// remove the "ObsoleteSetting" JProperty from its parent
jo["ObsoleteSetting"].Parent.Remove();

json = jo.ToString();

Ansatz 3: Kluge (ab) Verwendung von Attributen

  1. Wenden Sie ein [JsonIgnore] -Attribut auf die Eigenschaft an, die nicht serialisiert werden soll.
  2. Fügen Sie der Klasse einen alternativen privaten Eigenschaften-Setter mit demselben Typ wie der ursprünglichen Eigenschaft hinzu. Setzen Sie die Implementierung dieser Eigenschaft auf die ursprüngliche Eigenschaft.
  3. Wenden Sie ein [JsonProperty] -Attribut auf den alternativen Setter an und geben Sie ihm den gleichen JSON-Namen wie die ursprüngliche Eigenschaft.

Hier ist die überarbeitete Config Klasse:

class Config
{
    [JsonIgnore]
    public Fizz ObsoleteSetting { get; set; }

    [JsonProperty("ObsoleteSetting")]
    private Fizz ObsoleteSettingAlternateSetter
    {
        // get is intentionally omitted here
        set { ObsoleteSetting = value; }
    }

    public Bang ReplacementSetting { get; set; }
}
jsonconverter serializeobject

Wir haben einige Konfigurationsdateien, die durch das Serialisieren von C # -Objekten mit Json.net generiert wurden.

Wir möchten eine Eigenschaft der serialisierten Klasse von einer einfachen enum-Eigenschaft in eine Klasseneigenschaft migrieren.

Ein einfacher Weg, dies zu tun, wäre, die alte enum-Eigenschaft der Klasse zu belassen und dafür zu sorgen, dass Json.net diese Eigenschaft liest, wenn wir die Konfiguration laden, aber nicht, um sie beim nächsten Serialisieren des Objekts erneut zu speichern. Wir werden uns darum kümmern, die neue Klasse aus dem alten Enum separat zu generieren.

Gibt es eine einfache Möglichkeit, eine Eigenschaft eines C # -Objekts zu markieren (zB mit Attributen), so dass Json.net es NUR bei der Serialisierung ignoriert, aber beim Deserialisieren darauf achtet?




Setze Setzereigenschaft:

[JsonProperty(nameof(IgnoreOnSerializing))]
public string IgnoreOnSerializingSetter { set { _ignoreOnSerializing = value; } }

[JsonIgnore]
private string _ignoreOnSerializing;

[JsonIgnore]
public string IgnoreOnSerializing
{
    get { return this._ignoreOnSerializing; }
    set { this._ignoreOnSerializing = value; }
}

Ich hoffe das hilft.




Für jede Situation, in der es akzeptabel ist, dass Ihre Deserialisierungseigenschaft intern markiert ist, gibt es eine bemerkenswert einfache Lösung, die überhaupt nicht von Attributen abhängt. Markieren Sie die Eigenschaft einfach als internal get, aber public set:

public class JsonTest {

    public string SomeProperty { internal get; set; }

}

Dies führt zu einer korrekten Deserialisierung unter Verwendung von Standardeinstellungen / Resolvern / etc. Die Eigenschaft wird jedoch von der serialisierten Ausgabe entfernt.




Um auf Tho Ho's Antwort aufzubauen, kann dies auch für Felder verwendet werden.

[JsonProperty(nameof(IgnoreOnSerializing))]
public string IgnoreOnSerializingSetter { set { IgnoreOnSerializing = value; } }

[JsonIgnore]
public string IgnoreOnSerializing;



Related

c# json.net

Tags

c#   json.net