Обеспечение того, чтобы ключи JSON были строчными в .NET - PullRequest
93 голосов
/ 09 июня 2011

Есть ли простой способ использования JSON в .NET, чтобы гарантировать, что ключи отправляются в нижнем регистре?

В данный момент я использую библиотеку NewtonSoft Json.NET и просто использую

.
string loginRequest = JsonConvert.SerializeObject(auth);

В этом случае auth - это просто следующий объект

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

В результате

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

Есть ли способ обеспечить ввод букв username и apitoken в нижнем регистре?

Я не хочу просто пропустить его через String.ToLower(), конечно, потому что значения для username и apitoken в смешанном регистре.

Я понимаю, что могу программно сделать это и создать строку JSON вручную, но мне нужно это примерно для примерно 20 строк данных JSON, и я вижу, смогу ли я сэкономить время. Мне интересно, есть ли какие-либо уже созданные библиотеки, которые позволяют использовать строчные буквы для создания ключей.

Ответы [ 4 ]

163 голосов
/ 09 июня 2011

Для этого вы можете создать собственный распознаватель контрактов.Следующий обработчик контракта преобразует все ключи в нижний регистр:

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

Использование:

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

В результате вы получите:

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

Если вы всегдаЕсли вы хотите сериализовать, используя LowercaseContractResolver, попробуйте заключить его в класс, чтобы избежать повторения:

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

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

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

Что можно использовать следующим образом:

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

ASP.NET MVC4 / WebAPI

Если вы используете ASP.NET MVC4 / WebAPI, вы можете использовать CamelCasePropertyNamesContractResolver из библиотеки Newtonsoft.Json, которая включена по умолчанию.

21 голосов
/ 10 декабря 2015
protected 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();
    }
}
8 голосов
/ 15 декабря 2017

В Json.NET 9.0.1 и более поздних версиях можно обеспечить преобразование всех имен свойств в нижний регистр с помощью пользовательского NamingStrategy.Этот класс извлекает логику для алгоритмического сопоставления имен свойств из решателя контракта в отдельный легкий объект, который можно установить на DefaultContractResolver.NamingStrategy.Это избавляет от необходимости создавать custom ContractResolver и, следовательно, может быть проще интегрировать в каркасы, которые уже имеют свои собственные средства разрешения контрактов.

Определите LowercaseNamingStrategy следующим образом:

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

Затем выполните сериализацию следующим образом:

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

Примечания -

  • Использование string.ToLowerInvariant() гарантирует, что один и тот же контракт будет сгенерирован во всех локалях.

  • Чтобы определить, являются ли переопределенные имена свойств, ключи словаря и имена данных расширений строчными, выможно установить NamingStrategy.OverrideSpecifiedNames, NamingStrategy.ProcessDictionaryKeys или NamingStrategy.ProcessExtensionDataNames (Json.NET 10.0.1 и более поздние версии) на true.

  • Возможно, вы захотите кэшировать распознаватель контрактов для лучшей производительности .

  • Если у вас нет доступа к настройкам сериализатора в вашемрамки, вы можете применить NamingStrategy непосредственно к вашему объекту следующим образом:

    [JsonObject(NamingStrategyType = typeof(LowercaseNamingStrategy))]
    public class Authority
    {
        public string Username { get; set; }
        public string ApiToken { get; set; }
    }
    
  • Не изменяйте NamingStrategy из CamelCasePropertyNamesContractResolver.Этот распознаватель контрактов совместно использует информацию о типах во всех своих экземплярах, поэтому изменение любого экземпляра может привести к неожиданным побочным эффектам.

4 голосов
/ 24 ноября 2017

Вы можете использовать "JsonProperty":

Использование:

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

var json  = JsonConvert.SerializeObject(authority);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...