我以前从未使用过Web API,但我需要一个能够接受/返回JSON对象的Web服务,使用它似乎是一件合理的事情。它看起来很简单(如果不是有点过分),但我需要处理的数据结构类似于:
{
"values":["foo", "bar"],
"default":"bar"
}
所以我做了一个模型对象:
class DropDownValues {
public string[] values { get; set; }
public string default { get; set; }
}
问题是default似乎是一个受保护的关键字。一定有办法绕过这件事,对吧?
我建议走不同的路。尽可能保持C#对象模型的标准(我不会使用@
符号和C#关键字
作为属性名)。
我们可以将序列化(JSON)世界和C#对象分开--只需使用JSON.NET特性即可。
其中一个最简单的使用是带有属性的装饰:
[JsonProperty(PropertyName = "default")]
public string DefaultValue { get; set; }
在这种情况下,我们必须在项目中引用NewtonSoft.json。如果必须是POCO,我们可以引入从DefaultContractResolver
派生的CustomResolver
,并在那里定义这些转换...
但在这种情况下,分离关注是一个更纯粹的解决方案,我会说
编辑:JSON Contract Resolver草案(参见注释)
重要提示:newtonsoft.json是Web API的一部分。它不仅是一个开源的,甚至连MS团队都把它作为一个核心的JSON序列化器。
1)newtonsoft.json(作为web.api的一部分)已经安装在您的解决方案中。因此您不必单独下载(nuget)。它将始终位于packages
文件夹中。因此,使用该属性只是添加引用。它就在那里...
2)这里有一个小的草案,如何做属性的东西,同时保持POCO。正如我在这里试着解释的:POCO的,行为和periospance Igorance,以保持POCO(例如。我们确实从数据层上的NHibernate的分层体系结构中获益),我们可以用契约解析器
替换属性。我们的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;
}