如何在我的JSON模型类中使用保留关键字作为标识符?

我之前从未使用过Web API,但我需要一个接受/返回JSON对象的Web服务,并且使用它似乎是一个合理的事情。 它看起来很简单(如果不是为了我的目的有点过分),但我需要处理的数据结构看起来像:

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

所以我去制作一个Model对象:

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

问题是默认似乎是受保护的关键字。 必须有一些方法来解决这个问题,对吧?

我建议采取不同的方式。 保持您的C#对象模型尽可能多的标准(我不会使用@ sign和C# keywords作为属性名称)

我们可以通过使用Json.NETfunction来分离序列化(JSON)世界和C#对象。

最简单的一个是使用属性装饰:

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

在这种情况下,我们必须在项目中引用Newtonsoft.Json。 如果它必须是POCO,我们可以引入来自DefaultContractResolver CustomResolver并在那里定义这些转换…

但我会说,在这种情况下,分离关注点是一个更纯粹的解决方案

编辑:JSON合同解析员草案 (见评论)

重要说明: Newtonsoft.Json是Web API的一部分。 它不仅是一个开源,甚至MS团队都认为它是一个核心的JSON序列化器。

1)Newtonsoft.Json(作为Web.API的一部分)已经安装在您的解决方案中。 所以你不必单独下载(nuget)。 它总是在你的packages文件夹中。 因此,使用该属性只是添加引用。 它在那里……

2) 在保留POCO的同时,有一个小草案如何做属性的东西 。 正如我在此尝试解释的那样: POCO,行为和Peristance Igorance ,为了保持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; } ... 

这样我们就像[JsonPropertyAttribute]一样向serailizer提供了相同的信息。

现在,我们只需要使用它。 有很多方法(例如全局),但我们只能为控制器执行此操作:

 protected override void Initialize(HttpControllerContext context) { base.Initialize(context); var jSettings = context.Configuration.Formatters.JsonFormatter.SerializerSettings; jSettings.ContractResolver = MyResolver; } 

您可以在C#中使用关键字作为标识符,方法是在它们前面添加@。

使用camel约定的DropDownValues类:

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

你可以使用前缀@来传递,但它仍然没有遵循C#编码约定。

更好的解决方案是使用CamelCasePropertyNamesContractResolver既可以避免使用保留关键字又仍然使用C#编码约定:

 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() };