Как использовать зарезервированное ключевое слово в качестве идентификатора в классе модели 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;
}
класс 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()
};