114 Stimmen

Sicherstellen, dass JSON-Schlüssel in .NET kleinbuchstabig sind

Gibt es einen einfachen Weg, JSON in .NET zu verwenden, um sicherzustellen, dass die Schlüssel kleingeschrieben werden?

Derzeit verwende ich die Json.NET-Bibliothek von Newtonsoft und verwende einfach

string loginRequest = JsonConvert.SerializeObject(auth);

In diesem Fall ist auth nur das folgende Objekt

public class Authority
{
    public string Username { get; set; }
    public string ApiToken { get; set; }
}

Dies führt zu

{"Username":"Mark","ApiToken":"xyzABC1234"}

Gibt es eine Möglichkeit sicherzustellen, dass die Schlüssel username und apitoken kleingeschrieben werden?

Ich möchte es natürlich nicht einfach durch String.ToLower() laufen lassen, da die Werte für username und apitoken gemischt sind.

Ich weiß, dass ich dies programmatisch tun und den JSON-String manuell erstellen kann, aber ich benötige dies für ungefähr 20 oder so JSON-Datenzeichenfolgen und möchte sehen, ob ich mir etwas Zeit sparen kann. Ich frage mich, ob es bereits vorhandene Bibliotheken gibt, die es Ihnen ermöglichen, die Kleinbuchstaben für die Schlüsselerstellung durchzusetzen.

186voto

alexn Punkte 55397

Sie können für dies einen benutzerdefinierten Vertragslöser erstellen. Der folgende Vertragslöser konvertiert alle Schlüssel in Kleinbuchstaben um:

public class LowercaseContractResolver : DefaultContractResolver
{
    protected override string ResolvePropertyName(string propertyName)
    {
        return propertyName.ToLower();
    }
}

Verwendung:

var Einstellungen = new JsonSerializerSettings();
settings.ContractResolver = new LowercaseContractResolver();
var json = JsonConvert.SerializeObject(authority, Formatting.Indented, settings);

Ergebnis:

{"username":"Mark","apitoken":"xyzABC1234"}

Wenn Sie immer den LowercaseContractResolver verwenden möchten, sollten Sie in Betracht ziehen, ihn in einer Klasse zu verpacken, um sich nicht zu wiederholen:

public class LowercaseJsonSerializer
{
    private static readonly JsonSerializerSettings Einstellungen = new JsonSerializerSettings
    {
        ContractResolver = new LowercaseContractResolver()
    };

    public static string ObjektSerialisieren(object o)
    {
        return JsonConvert.SerializeObject(o, Formatting.Indented, Einstellungen);
    }

    public class LowercaseContractResolver : DefaultContractResolver
    {
        protected override string ResolvePropertyName(string propertyName)
        {
            return propertyName.ToLower();
        }
    }
}

Das kann so verwendet werden:

var json = LowercaseJsonSerializer.SerializeObject(new { Foo = "bar" });
// { "foo": "bar" }

ASP.NET MVC4 / WebAPI

Wenn Sie ASP.NET MVC4 / WebAPI verwenden, können Sie einen CamelCasePropertyNamesContractResolver aus der Newtonsoft.Json-Bibliothek verwenden, die standardmäßig enthalten ist.

24voto

Sagi Punkte 8222
geschützt void Application_Start() {
    JsonConfig.Configure();   
}

public static class JsonConfig
{
    public static void Configure(){
        var formatters = GlobalConfiguration.Configuration.Formatters;
        var jsonFormatter = formatters.JsonFormatter;
        var settings = jsonFormatter.SerializerSettings;

        settings.ContractResolver = new CamelCasePropertyNamesContractResolver();
    }
}

18voto

dbc Punkte 90210

In Json.NET 9.0.1 und später ist es möglich sicherzustellen, dass alle Eigenschaftsnamen in Kleinbuchstaben konvertiert werden, indem eine benutzerdefinierte NamingStrategy verwendet wird. Diese Klasse extrahiert die Logik für die algorithmische Umbenennung von Eigenschaftsnamen aus dem Vertragsauflöser zu einem separaten, leichtgewichtigen Objekt, das auf DefaultContractResolver.NamingStrategy gesetzt werden kann. Dadurch entfällt die Notwendigkeit, einen benutzerdefinierten ContractResolver zu erstellen und kann daher einfacher in Frameworks integriert werden, die bereits ihre eigenen Vertragsauflöser haben.

Definieren Sie LowercaseNamingStrategy wie folgt:

public class LowercaseNamingStrategy : NamingStrategy
{
    protected override string ResolvePropertyName(string name)
    {
        return name.ToLowerInvariant();
    }
}

Dann serialisieren Sie wie folgt:

var settings = new JsonSerializerSettings
{
    ContractResolver = new DefaultContractResolver { NamingStrategy = new LowercaseNamingStrategy() },
};
string loginRequest = JsonConvert.SerializeObject(auth, settings);

Anmerkungen -

  • Die Verwendung von string.ToLowerInvariant() garantiert, dass der gleiche Vertrag in allen Sprachumgebungen generiert wird.

  • Um zu steuern, ob überschriebene Eigenschaftsnamen, Wörterbuchschlüssel und Erweiterungsdatennamen in Kleinbuchstaben konvertiert werden, können Sie NamingStrategy.OverrideSpecifiedNames, NamingStrategy.ProcessDictionaryKeys oder NamingStrategy.ProcessExtensionDataNames (Json.NET 10.0.1 und später) auf true setzen.

  • Sie sollten den Vertragsauflöser für die beste Leistung zwischenspeichern.

  • Wenn Sie keinen Zugriff auf die Serializer-Einstellungen in Ihrem Framework haben, können Sie direkt ein NamingStrategy auf Ihr Objekt anwenden wie folgt:

    [JsonObject(NamingStrategyType = typeof(LowercaseNamingStrategy))]
    public class Authority
    {
        public string Username { get; set; }
        public string ApiToken { get; set; }
    }
  • Ändern Sie nicht den NamingStrategy von CamelCasePropertyNamesContractResolver. Dieser Vertragsauflöser teilt global Typinformationen über alle seine Instanzen, und die Änderung einer Instanz kann unerwartete Nebenwirkungen haben.

12voto

Jorgelig Punkte 154

Sie können "JsonProperty" verwenden:

Verwendung:

public class Authority
{
    [JsonProperty("Benutzername")] // oder [JsonProperty("username")]
    public string Username { get; set; }
    [JsonProperty("apiToken")] // oder [JsonProperty("apitoken")]
    public string ApiToken { get; set; }
}

var json  = JsonConvert.SerializeObject(authority);

0voto

workabyte Punkte 3330

Für mich habe ich eine Kombination einiger anderer Antworten verwendet und bin letztendlich auf das hier gekommen

        return JsonConvert.SerializeObject(obj, Formatting.Indented, new JsonSerializerSettings
        {
            ContractResolver = new CamelCasePropertyNamesContractResolver()
        });

war näher an einer Lösung, nach der ich gesucht habe, da ich nicht beabsichtigt hatte, meine eigene zu erstellen

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X