Как использовать зарезервированное ключевое слово в качестве идентификатора в классе модели JSON?

Я никогда раньше не использовал веб-API, но мне нужен веб-сервис, который будет принимать / возвращать объекты JSON,и использование этого казалось разумным. Это выглядело довольно просто (если не немного излишне для моих целей), но структура данных, с которой мне нужно иметь дело, выглядит примерно так:

{
    "values":["foo", "bar"],
    "default":"bar"
}

и поэтому я пошел, чтобы сделать объект модели:

class DropDownValues {
    public string[] values { get; set; }
    public string default { get; set; }
}

проблема в том, что по умолчанию используется защищенное ключевое слово. Там должен быть какой-то способ обойти это?

3 ответов


Я бы предложил пойти другим путем. Держите c модель объект# столько стандартных (я бы не использовал @ знак а C# keywords как имя свойства).

мы можем отделить сериализованный (JSON) мир и объекты C# - просто с помощью Json.NET особенности.

один из самых простых в использовании является украшение с атрибутов:

[JsonProperty(PropertyName = "default")]
public string DefaultValue { get; set; }

в этом случае мы должны ссылаться на Newtonsoft.Json в проекте. Если это должен быть POCO, мы можем вводим CustomResolver которые можно вывести из DefaultContractResolver и определить эти преобразования...

но разделение беспокойства в этом случае немного более чистое решение, я бы сказал

EDIT: проект преобразователя контрактов JSON (см. комментарии)

важное замечание: Newtonsoft.В JSON является частью веб-API. Это не только открытый исходный код, но даже MS team делает ставку на это как на основной сериализатор JSON.

1) Newtonsoft.Json(как часть сети.API) уже установлен в вашем решении. Таким образом, вам не нужно загружать (nuget) отдельно. Это всегда будет в вашем . Итак, чтобы использовать атрибут, просто добавьте ссылку. Она здесь...

2) есть небольшой проект, как сделайте атрибутивный материал, сохраняя POCO. Как я попытался объяснить здесь:поко, поведение и сопротивление Игоранс, чтобы сохранить POCO (например, мы получаем прибыль от многоуровневая архитектура с NHibernate на уровне данных), мы можем заменить С Contract Resolver. Наша библиотека POCO не должна ссылаться ни на что

нам просто нужно расширить уровень обслуживания:

public class MyResolver : DefaultContractResolver
{
    protected override JsonProperty CreateProperty(
         MemberInfo member,
         MemberSerialization memberSerialization)
    {

        var jProperty = base.CreateProperty(member, memberSerialization);

        var propertyInfo = member as PropertyInfo;
        if (propertyInfo == null)
        {
            return jProperty;
        }

        // just adjust in case if Property name is DefaultValue
        var isDefaultValueProeprty =
                  propertyInfo.Name.Equals("DefaultValue");

        if(isDefaultValueProeprty)
        {
            jProperty.PropertyName = "default";
        }

        return jProperty;
    }
    ...

таким образом мы предоставили ту же информацию serailizer С [JsonPropertyAttribute].

теперь, мы просто должны использовать его. Есть много способов (например, глобальный), но мы можем сделать это для контроллера только:

protected override void Initialize(HttpControllerContext context)
{
  base.Initialize(context);

  var jSettings = context.Configuration.Formatters.JsonFormatter.SerializerSettings;
  jSettings.ContractResolver = MyResolver;
}

вы можете использовать ключевые слова в C# в качестве идентификаторов, добавляя @ перед ними.


класс DropDownValues использование конвенции camel:

class DropDownValues {
    public string[] values { get; set; }
    public string default { get; set; }
}

вы можете использовать префикс @ для passby, но он все еще не следует соглашению о кодировании C#.

лучшее решение, которое вы можете как избежать зарезервированного ключевого слова, так и использовать соглашение о кодировании c#, использует CamelCasePropertyNamesContractResolver:

class DropDownValues {
    public string[] Values { get; set; }
    public string Default { get; set; }
}

и настройка JsonFormatter чтобы избежать несоответствия между C# и JSON-объектом, как показано ниже:

var jsonFormatter = configuration.Formatters.JsonFormatter;
jsonFormatter.SerializerSettings = new JsonSerializerSettings()
{  
    ContractResolver = new CamelCasePropertyNamesContractResolver()
};