我扩展了Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver并将新的解析器应用到我的WebApi中:
public static void Register(HttpConfiguration config)
{
var json = config.Formatters.JsonFormatter.SerializerSettings;
json.ContractResolver = new CustomPropertyNamesContractResolver();
json.Formatting = Formatting.Indented;
config.MapHttpAttributeRoutes();
}
这是我的自定义名称解析器(CustomPropertyNamesContractResolver类)的重写方法:
protected override string ResolvePropertyName(string propertyName)
{
if (propertyName.Equals("ID"))
return "id";
// return the camelCase
propertyName = base.ResolvePropertyName(propertyName);
if (propertyName.EndsWith("ID"))
propertyName = propertyName.Substring(0, propertyName.Length - 1) + "d";
return propertyName;
}
我的问题是结果的确是驼峰式的,但是“ QuestionID”之类的属性从未转换为“ questionId”,而我一直收到的是“ questionID”。
另外,从未调用过我的自定义ResolvePropertyName()方法(使用断点对其进行了测试),因此似乎仅以某种方式调用了父类(CamelCasePropertyNamesContractResolver)的ResolvePropertyName()方法。
现在,当我直接从DefaultContractResolver(它是CamelCasePropertyNamesContractResolver的父级)继承时,将调用我的自定义ResolvePropertyName()方法。
有人可以解释一下这里发生的事情吗?
我想念什么吗?
最佳答案
ResolvePropertyName()
不再由CamelCasePropertyNamesContractResolver
调用。在Issue #950: Breaking change in 9.0.1 for custom contract resolvers?中由resolved命名为JamesNK的文档如下:
JamesNK于2016年7月4日评论
是的,现在将中断。由于CamelCasePropertyNamesContractResolver的工作方式发生了变化,因此从未调用该方法[ResolvePropertyName]。
您可以做的是从CamelCaseNamingStrategy继承并做类似的事情,然后将其分配给DefaultContractResolver。请注意,您应该将合同解析器缓存在静态变量上,这样就不会一直重新创建它。
按照那里的建议,您应该像这样从CamelCaseNamingStrategy
继承:
public class CustomNamingStrategy : CamelCaseNamingStrategy
{
protected override string ResolvePropertyName(string propertyName)
{
if (propertyName.Equals("ID"))
return "id";
// return the camelCase
propertyName = base.ResolvePropertyName(propertyName);
if (propertyName.EndsWith("ID"))
propertyName = propertyName.Substring(0, propertyName.Length - 1) + "d";
return propertyName;
}
}
然后像这样在
DefaultContractResolver.NamingStrategy
上设置它:json.ContractResolver = new DefaultContractResolver { NamingStrategy = new CustomNamingStrategy() };
或者,由于我相信ASP.NET Web API使用其自己的协定解析器
JsonContractResolver
,因此您可能希望修改现有NamingStrategy
的config.Formatters.JsonFormatter.SerializerSettings.ContractResolver
,假设已经在设置中分配了解析器:var resolver = json.ContractResolver as DefaultContractResolver ?? new DefaultContractResolver();
resolver.NamingStrategy = new CustomNamingStrategy();
json.ContractResolver = resolver;
(注意-我自己尚未使用预先存在的解析器进行测试。)