扩展CamelCasePropertyNamesContractResolver不起作用

时间:2018-10-17 08:55:01

标签: c# json json.net asp.net-web-api2 camelcasing

我扩展了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()方法。

有人可以解释一下这里发生了什么吗? 我想念什么吗?

1 个答案:

答案 0 :(得分:3)

ResolvePropertyName()不再由CamelCasePropertyNamesContractResolver调用。 Issue #950: Breaking change in 9.0.1 for custom contract resolvers?中记录了此内容,resolvedJamesNK记录如下:

  

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的{​​{1}}已经在设置中:

config.Formatters.JsonFormatter.SerializerSettings.ContractResolver

(注意-我自己尚未使用预先存在的解析器进行测试。)