Gibt es eine Möglichkeit, die Reihenfolge der Felder in einem serialisierten JSON-Objekt mithilfe von JSON.NET anzugeben ?
Es würde ausreichen anzugeben, dass immer zuerst ein einzelnes Feld angezeigt wird.
Gibt es eine Möglichkeit, die Reihenfolge der Felder in einem serialisierten JSON-Objekt mithilfe von JSON.NET anzugeben ?
Es würde ausreichen anzugeben, dass immer zuerst ein einzelnes Feld angezeigt wird.
Antworten:
Die unterstützte Methode besteht darin, das
JsonProperty
Attribut für die Klasseneigenschaften zu verwenden, für die Sie die Reihenfolge festlegen möchten. Weitere Informationen finden Sie in der Bestelldokumentation zu JsonPropertyAttribute .Übergeben Sie den
JsonProperty
einOrder
Wert und der Serializer wird der Rest kümmern.Dies ist sehr ähnlich zu
der
System.Runtime.Serialization
Tage.Hier ist ein wichtiger Hinweis von @ kevin-babcock
quelle
Order
Eigenschaft vonJsonPropertyAttribute
kann die Reihenfolge gesteuert werden, in der Felder serialisiert / deserialisiert werden. Das Festlegen der Reihenfolge auf 1 funktioniert jedoch nur, wenn Sie für alle anderen Eigenschaften eine Reihenfolge größer als 1 festlegen. Standardmäßig erhält jede Eigenschaft ohne Auftragseinstellung den Auftrag -1. Sie müssen also entweder alle serialisierten Eigenschaften und die Reihenfolge angeben oder Ihren ersten Artikel auf -2 setzen.JavaScriptSerializer
.Sie können steuern , tatsächlich die Reihenfolge durch die Implementierung
IContractResolver
oder das übergeordneteDefaultContractResolver
‚s -CreateProperties
Methode.Hier ist ein Beispiel für meine einfache Implementierung, bei
IContractResolver
der die Eigenschaften alphabetisch geordnet sind:Legen Sie dann die Einstellungen fest und serialisieren Sie das Objekt. Die JSON-Felder werden in alphabetischer Reihenfolge angezeigt:
quelle
In meinem Fall hat Mattias 'Antwort nicht funktioniert. Die
CreateProperties
Methode wurde nie aufgerufen.Nach einigem Debuggen von
Newtonsoft.Json
Interna habe ich eine andere Lösung gefunden.quelle
In meinem Fall hat die Lösung von niaher nicht funktioniert, da sie keine Objekte in Arrays verarbeitet hat.
Basierend auf seiner Lösung habe ich mir das ausgedacht
quelle
Wie Charlie bemerkte, können Sie die Reihenfolge der JSON-Eigenschaften etwas steuern, indem Sie die Eigenschaften in der Klasse selbst anordnen. Leider funktioniert dieser Ansatz nicht für Eigenschaften, die von einer Basisklasse geerbt wurden. Die Eigenschaften der Basisklasse werden so angeordnet, wie sie im Code angeordnet sind, werden jedoch vor den Eigenschaften der Basisklasse angezeigt.
Und für alle, die sich fragen, warum Sie JSON-Eigenschaften alphabetisch sortieren möchten, ist es viel einfacher, mit JSON-Rohdateien zu arbeiten, insbesondere für Klassen mit vielen Eigenschaften, wenn diese geordnet sind.
quelle
Dies funktioniert auch für normale Klassen, Wörterbücher und ExpandoObject (dynamisches Objekt).
quelle
CreateProperties
wird während der Serialisierung eines Wörterbuchs nicht aufgerufen. Ich habe das JSON.net-Repo untersucht, um herauszufinden, welche Maschinen tatsächlich durch die Wörterbucheinträge tuckern. Es lässt sich nicht in eineoverride
oder andere Anpassung für die Bestellung einbinden. Es werden nur die Einträge wie sie sind aus dem Enumerator des Objekts übernommen. Es scheint, dass ich einSortedDictionary
oderSortedList
erstellen muss, um JSON.net dazu zu zwingen. Feature-Vorschlag eingereicht: github.com/JamesNK/Newtonsoft.Json/issues/2270Wenn Sie nicht
JsonProperty
Order
jeder Klasseneigenschaft ein Attribut zuweisen möchten, können Sie ganz einfach Ihren eigenen ContractResolver erstellen ...So was:
Implementieren:
quelle
Die folgende rekursive Methode verwendet Reflektion, um die interne Token-Liste für eine vorhandene
JObject
Instanz zu sortieren, anstatt ein brandneues sortiertes Objektdiagramm zu erstellen. Dieser Code basiert auf internen Json.NET-Implementierungsdetails und sollte nicht in der Produktion verwendet werden.quelle
Da mein Objekt bereits ein JObject war, habe ich die folgende Lösung verwendet:
und dann benutze es so:
quelle
Wenn Sie die Klasse steuern (dh schreiben), ordnen Sie die Eigenschaften in alphabetischer Reihenfolge an, und sie werden beim
JsonConvert.SerializeObject()
Aufruf in alphabetischer Reihenfolge serialisiert .quelle
Ich möchte ein kombiniertes Objekt serialisieren und die Reihenfolge der Eigenschaften beibehalten, wie sie im Code definiert wurden. Ich kann nicht einfach hinzufügen,
[JsonProperty(Order = 1)]
da die Klasse selbst außerhalb meines Bereichs liegt.Diese Lösung berücksichtigt auch, dass Eigenschaften, die in einer Basisklasse definiert sind, eine höhere Priorität haben sollten.
Dies ist möglicherweise nicht kugelsicher, da nirgends definiert ist, dass
MetaDataAttribute
die richtige Reihenfolge gewährleistet ist, aber es scheint zu funktionieren. Für meinen Anwendungsfall ist dies in Ordnung. da ich nur die menschliche Lesbarkeit für eine automatisch generierte Konfigurationsdatei beibehalten möchte.quelle
Wenn Sie Ihre API global mit geordneten Feldern konfigurieren möchten, kombinieren Sie bitte die Antwort von Mattias Nordberg:
mit meiner Antwort hier:
Wie kann ich die ASP.NET-Web-API zwingen, immer JSON zurückzugeben?
quelle
AKTUALISIEREN
Ich habe gerade die Abstimmungen gesehen. Bitte lesen Sie die Antwort von 'Steve' unten, wie das geht.
ORIGINAL
Ich folgte dem
JsonConvert.SerializeObject(key)
Methodenaufruf über Reflection (wobei der Schlüssel eine IList war) und stellte fest, dass JsonSerializerInternalWriter.SerializeList aufgerufen wird. Es nimmt eine Liste und durchläuft viafor (int i = 0; i < values.Count; i++) { ...
Dabei ist values der eingegebene IList-Parameter.
Die kurze Antwort lautet ... Nein, es gibt keine integrierte Möglichkeit, die Reihenfolge festzulegen, in der die Felder in der JSON-Zeichenfolge aufgeführt sind.
quelle
Es gibt keine Reihenfolge der Felder im JSON-Format, daher ist das Definieren einer Reihenfolge nicht sinnvoll.
{ id: 1, name: 'John' }
ist äquivalent zu{ name: 'John', id: 1 }
(beide repräsentieren eine streng äquivalente Objektinstanz)quelle