c# - 扩展 CamelCasePropertyNamesContractResolver 不起作用
问题描述
我扩展了 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
。这记录在问题 #950:9.0.1 中针对自定义合同解析器的重大更改?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 使用它自己的 contract resolver JsonContractResolver
,你可能想要修改NamingStrategy
现有的config.Formatters.JsonFormatter.SerializerSettings.ContractResolver
,假设已经在设置中分配了一个 resolver:
var resolver = json.ContractResolver as DefaultContractResolver ?? new DefaultContractResolver();
resolver.NamingStrategy = new CustomNamingStrategy();
json.ContractResolver = resolver;
(注意 - 我自己没有使用预先存在的解析器进行测试。)
推荐阅读
- fpga - Zynq SOC 无法通过交换机向桌面发送原始以太网数据包
- c - C程序更改网络适配器的MAC地址
- java - 如何在 Java 中突出显示数字?
- c# - 对于 .NET Core,Visual Studio 发布忽略 Views 文件夹中的 .js 文件
- javascript - 在提交按钮上阻止特殊字符验证
- reactjs - React + Redux - 架构 API 方法
- android - 回收站视图中的间距网格项目
- .htaccess - Htaccess - 只允许从 pdf.js 访问文件
- microsoft-graph-api - 更新 Planner 存储桶的 orderHint 时,Microsoft Graph 失败
- icalendar - 通过 Outlook 日历中的 .ics 添加和删除约会/日历条目