如何在我的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() };