Wie kann ich Eigenschaftsnamen bei der Serialisierung mit Json.net ändern?

434

Ich habe einige Daten in einem C # DataSet-Objekt. Ich kann es jetzt mit einem Json.net-Konverter wie diesem serialisieren

DataSet data = new DataSet();
// do some work here to populate 'data'
string output = JsonConvert.SerializeObject(data);

Hierbei werden jedoch die Eigenschaftsnamen verwendet, die databeim Drucken in die JSON-Datei verwendet werden. Ich möchte die Eigenschaftsnamen in etwas anderes ändern (z. B. 'foo' in 'bar' ändern).

In der Json.net-Dokumentation steht unter "Serialisieren und Deserialisieren von JSON" → "Serialisierungsattribute" "JsonPropertyAttribute ... ermöglicht das Anpassen des Namens". Aber es gibt kein Beispiel. Weiß jemand, wie man ein JsonPropertyAttribute verwendet, um den Eigenschaftsnamen in etwas anderes zu ändern?

( Direkter Link zur Dokumentation )

Die Dokumentation von Json.net scheint spärlich zu sein. Wenn Sie ein gutes Beispiel haben, werde ich versuchen, es in die offizielle Dokumentation aufzunehmen. Vielen Dank!

culix
quelle
3
Zu Ihrer Information , ein Beispiel hierfür finden Sie in der Dokumentation unter Beispiele -> Serialisierung von JSON -> JsonPropertyAttribute-Name . Ich bin mir nicht sicher, zu welchem ​​Zeitpunkt es hinzugefügt wurde.
Brian Rogers

Antworten:

791

Sie können die gewünschte Eigenschaft, die ihren Namen steuert, mit dem [JsonProperty]Attribut dekorieren, mit dem Sie einen anderen Namen angeben können:

using Newtonsoft.Json;
// ...

[JsonProperty(PropertyName = "FooBar")]
public string Foo { get; set; }

Dokumentation: Serialisierungsattribute

Darin Dimitrov
quelle
1
Erfordert dies, dass ich meine Daten in ein benutzerdefiniertes Objekt einlese, das ich anstelle eines DataSets erstelle?
Culix
3
@culix, ja, es erfordert die Verwendung eines Modells. Ein DataSet ist eine schwach typisierte Struktur, daher ist es nicht sehr logisch, über Eigenschaftsnamen zu sprechen.
Darin Dimitrov
76
Als Abkürzung können Sie auch tun[JsonProperty("FooBar")]
Bart Verkoeijen
2
@DarinDimitrov gibt es eine Möglichkeit, dies ohne Json .NET zu tun?
CH81
12
Die Verwendung eines Modells ist jedoch einfach. Nehmen Sie einfach ein Beispiel Ihres JSON und fügen Sie es mit "Inhalte einfügen" -> "JSON als Klassen einfügen" in eine leere CS-Datei ein. - Es ist in Visual Studio integriert. - Von dort aus müssen Sie im Grunde nur Dinge als Titel- / Umbenennungsmaterial einrichten, um .NET-Namenskonventionen usw. zu verwenden (mit einem Titel-Fall-Konverter für das erstere und dem JsonProperty-Attribut für das letztere).
BrainSlugs83
71

Wenn Sie keinen Zugriff auf die Klassen haben, um die Eigenschaften zu ändern, oder nicht immer dieselbe Umbenennungseigenschaft verwenden möchten, können Sie die Umbenennung auch durch Erstellen eines benutzerdefinierten Resolvers durchführen.

Wenn Sie beispielsweise eine Klasse MyCustomObjectmit einer Eigenschaft namens haben LongPropertyName, können Sie einen benutzerdefinierten Resolver wie diesen verwenden.

public class CustomDataContractResolver : DefaultContractResolver
{
  public static readonly CustomDataContractResolver Instance = new CustomDataContractResolver ();

  protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
  {
    var property = base.CreateProperty(member, memberSerialization);
    if (property.DeclaringType == typeof(MyCustomObject))
    {
      if (property.PropertyName.Equals("LongPropertyName", StringComparison.OrdinalIgnoreCase))
      {
        property.PropertyName = "Short";
      }
    }
    return property;
  }
}

Rufen Sie dann die Serialisierung an und liefern Sie den Resolver:

 var result = JsonConvert.SerializeObject(myCustomObjectInstance,
                new JsonSerializerSettings { ContractResolver = CustomDataContractResolver.Instance });

Das Ergebnis wird auf {"Short": "prop value"} anstelle von {"LongPropertyName": "prop value"} gekürzt.

Weitere Informationen zu benutzerdefinierten Resolvern finden Sie hier

StingyJack
quelle
1
Dies ist eine bessere Lösung, wenn Ihre zu serialisierende Klasse in einer anderen Assembly deklariert ist, die eine andere Version des Newtonsoft.Json-Pakets enthält. (Es kann nicht einmal einen Fehler werfen). Das DefaultContractResolvermuss in dieselbe Assembly gestellt werden, in der die Methode JsonConvert.Serialize () verwendet wird.
Artemious
6

Es gibt noch eine andere Möglichkeit, die darin besteht, eine bestimmte NamingStrategy zu verwenden , die auf eine Klasse oder eine Eigenschaft angewendet werden kann, indem sie mit [JSonObject]oder dekoriert werden [JsonProperty].

Es gibt vordefinierte Namensstrategien wie CamelCaseNamingStrategy, aber Sie können Ihre eigenen implementieren.

Die Implementierung verschiedener Namensstrategien finden Sie hier: https://github.com/JamesNK/Newtonsoft.Json/tree/master/Src/Newtonsoft.Json/Serialization

JotaBe
quelle
3
Wenn Sie in der Lage sind, teilen Sie bitte ein Beispiel für eine benutzerdefinierte NamingStrategy-Implementierung
user1007074
Natürlich nicht. Sie hätten es selbst tun sollen, aber ich werde Ihnen die Zeit ersparen, Ihnen zu sagen, dass Sie einfach newtonsoft.com/json/help/html/ erben müssen. Sie können die vorhandene Klassenimplementierung sehen und Ihre eigene erstellen.
JotaBe
Danke - ich hätte meinen Kommentar aktualisieren sollen: Dank des Ruhms von GitHub kann man tatsächlich eine von Newtonsofts eigenen Implementierungen als Beispiel verwenden, zum Beispiel diese
user1007074
8
@JotaBe, das ist nicht der Geist des Stackoverflow. Und als Programmierer, der nur meine Arbeit erledigen möchte, wäre es für mich tausendmal besser gewesen, den Code, den Sie möglicherweise bereitgestellt haben, aufzuheben. Und du hättest auch meine Stimme bekommen. Ich habe 18 Jahre Erfahrung im Codieren und werde von TripleByte als "Experte" in c # eingestuft. Nicht JEDES Problem muss als "Übung für den Leser" belassen werden. Manchmal wollen wir einfach nur unseren Job machen und weitermachen.
bboyle1234
2
Ich stimme Ihnen zu und schreibe normalerweise keinen solchen Kommentar. Ich kann jedoch versichern, dass in diesem Fall das Betrachten des verknüpften Codes viel besser ist als jede Erklärung, die ich geben kann. Und json.net ist eine sehr gut dokumentierte Open-Source-Bibliothek. Enthaltener Link zu den Implementierungen (perfekte Beispiele)
JotaBe