Ich habe ein Web-API-Projekt, das wie folgt konfiguriert wird:
config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
Ich möchte jedoch, dass das Gehäuse der Wörterbuchschlüssel unverändert bleibt. Gibt es ein Attribut in Newtonsoft.Json
einer Klasse, das angibt, dass das Gehäuse während der Serialisierung unverändert bleiben soll?
public class SomeViewModel
{
public Dictionary<string, string> Data { get; set; }
}
Antworten:
Es gibt kein Attribut dafür, aber Sie können dies tun, indem Sie den Resolver anpassen.
Ich sehe, dass Sie bereits eine verwenden
CamelCasePropertyNamesContractResolver
. Wenn Sie daraus eine neue Resolver-Klasse ableiten und dieCreateDictionaryContract()
Methode überschreiben , können Sie eine Ersatzfunktion bereitstellenDictionaryKeyResolver
, die die Schlüsselnamen nicht ändert.Hier ist der Code, den Sie benötigen würden:
Demo:
Hier ist die Ausgabe von oben. Beachten Sie, dass alle Namen der Klasseneigenschaften in Kamelform vorliegen, die Wörterbuchschlüssel jedoch ihre ursprüngliche Schreibweise beibehalten haben.
quelle
contract.DictionaryKeyResolver = key => key;
funktioniert.DictionaryKeyResolver
nur konditionieren kann, wenn meine Dictionary-Eigenschaft ein benutzerdefiniertes Attribut hat?Json.NET 9.0.1 führte die
NamingStrategy
Klassenhierarchie ein, um diese Art von Problem zu behandeln. Es extrahiert die Logik für die algorithmische Neuzuordnung von Eigenschaftsnamen aus dem Vertragsauflöser in eine separate, leichtgewichtige Klasse, mit der gesteuert werden kann, ob Wörterbuchschlüssel , explizit angegebene Eigenschaftsnamen und Erweiterungsdatennamen (in 10.0.1 ) neu zugeordnet werden.Durch Verwenden
DefaultContractResolver
und FestlegenNamingStrategy
einer Instanz von könnenCamelCaseNamingStrategy
Sie JSON mit Kamel-ummantelten Eigenschaftsnamen und unveränderten Wörterbuchschlüsseln generieren, indem Sie Folgendes festlegenJsonSerializerSettings.ContractResolver
:Anmerkungen:
Die aktuelle Implementierung von gibt
CamelCasePropertyNamesContractResolver
außerdem an, dass .Net-Mitgliedern mit explizit angegebenen Eigenschaftsnamen (z. B. solchen, bei denenJsonPropertyAttribute.PropertyName
sie festgelegt wurden) ihre Namen neu zugeordnet werden sollen:Das Obige
resolver
bewahrt dieses Verhalten. Wenn Sie dies nicht möchten, stellen Sie einOverrideSpecifiedNames = false
.Json.NET verfügt über mehrere integrierte Namensstrategien, darunter:
CamelCaseNamingStrategy
. Eine Namensstrategie für Kamelfälle, die die zuvor eingebettete Logik zur Neuzuordnung von Namen enthältCamelCasePropertyNamesContractResolver
.SnakeCaseNamingStrategy
. Eine Strategie zur Benennung von Schlangenfällen .DefaultNamingStrategy
. Die Standardbenennungsstrategie. Eigenschaftsnamen und Wörterbuchschlüssel bleiben unverändert.Oder Sie können Ihre eigenen erstellen, indem Sie von der abstrakten Basisklasse erben
NamingStrategy
.Es ist zwar auch möglich, die
NamingStrategy
einer Instanz von zu ändernCamelCasePropertyNamesContractResolver
, da letztere Vertragsinformationen global für alle Instanzen jedes Typs gemeinsam nutztCamelCasePropertyNamesContractResolver
. Dies kann jedoch zu unerwarteten Nebenwirkungen führen, wenn Ihre Anwendung versucht, mehrere Instanzen von zu verwenden . Es gibt kein solches ProblemDefaultContractResolver
, daher ist es sicherer, es zu verwenden, wenn eine Anpassung der Gehäuselogik erforderlich ist.quelle
public Dictionary<string, Dictionary<string, string>> Values { get; set; }
. CamelCase für die inneren Wörterbuchschlüssel wird weiterhin ausgeführt.CamelCasePropertyNamesContractResolver
. Grundsätzlich würdeNamingStrategy
für die erste die von der zweiten generierten Verträge beeinflusst. Das könnten Sie sehen. Versuchen Sie stattdessen die neue Empfehlung und lassen Sie mich wissen, ob Ihr Problem behoben ist.NamingStrategy
, so dass es sowohl Kamel- als auch Pascal-Fälle analysieren kann?config
soll im ersten Codebeispiel sein?config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
. Es sieht die MVC 4 Web - API zu seinHttpConfiguration
, siehe Wie Satz individuelle JsonSerializerSettings für Json.NET in MVC 4 Web - API? .Das ist eine sehr schöne Antwort. Aber warum nicht einfach das überschreiben
ResolveDictionaryKey
?quelle
Die ausgewählte Antwort ist perfekt, aber ich denke, wenn ich dies schreibe, muss sich der Vertragsauflöser in so etwas ändern, da DictionaryKeyResolver nicht mehr existiert :)
quelle
DictionaryKeyResolver
wurde in Version 7.0.1 hinzugefügt undPropertyNameResolver
als veraltet markiert.