如何使用带有点分隔名称的JSON.Net CamelCasePropertyNamesContractResolver



我们的应用程序使用验证属性来使用ASP.NET模型验证,但这会为验证错误提供点分隔的名称。当通过CamelCasePropertyNamesContractResolver时,它只将camelcase应用于第一个点之前,而我们希望将camelcase应用于名称的每个部分。

例如,我们当前得到的json响应是:

{
"body.State": [
"The state field is required."
],
"body.LatestVersion": [
"The latestVersion field is required."
]
}

但想要退出:

{
"body.state": [
"The state field is required."
],
"body.latestVersion": [
"The latestVersion field is required."
]
}

在我们的MVC设置中,我们确实有一条类似的线路

services.AddJsonOptions(options => options.ContractResolver = new CamelCasePropertyNamesContractResolver());

我们非常感谢任何解决方案,无论是对我们如何设置解析器的修改,还是对我们如何修改验证的修改。


编辑:仅供参考,生成此请求的请求的模型结构如下:

public sealed class RequestModel
{
[FromRoute, DisplayName("entity"), Required, MaximumLength(255)]
public string Entity { get; set; }
[FromBody, DisplayName("body"), Required]
public BodyModel Body { get; set; }
}
public sealed class BodyModel
{
[DisplayName("latestVersion"), Required, MaximumLength(255)]
public string LatestVersion { get; set; }
[DisplayName("state"), Required]
public ModelState State { get; set; }
}

发送的请求体为:

{
}

假设验证错误被序列化为某些T的某种IDictionary<string, T>,那么通过创建自定义命名策略,可以在每个.字符之间对与字典键相对应的JSON属性名进行分段大小写。

Json.NET封装了在NamingStrategy类型(特别是CamelCaseNamingStrategy)中以算法方式重新映射属性名和字典键的逻辑(例如骆驼大小写)。要修改命名策略的逻辑以应用于.字符之间的属性名称的每一部分,可以采用decorator模式并创建一个decorator命名策略,该策略将一些内部策略应用于名称的每部分,如下所示:

public class PiecewiseNamingStrategy : NamingStrategy
{
readonly NamingStrategy baseStrategy;
public PiecewiseNamingStrategy(NamingStrategy baseStrategy)
{
if (baseStrategy == null)
throw new ArgumentNullException();
this.baseStrategy = baseStrategy;
}
protected override string ResolvePropertyName(string name)
{
return String.Join(".", name.Split('.').Select(n => baseStrategy.GetPropertyName(n, false)));
}
}

然后,按如下方式配置MVC:

options.ContractResolver = new DefaultContractResolver
{
NamingStrategy = new PiecewiseNamingStrategy(new CamelCaseNamingStrategy()) 
{ 
OverrideSpecifiedNames = true, ProcessDictionaryKeys = true 
},
};

这利用了这样一个事实,即如参考源中所示,CamelCasePropertyNamesContractResolver基本上只是DefaultContractResolver的一个子类,它使用具有ProcessDictionaryKeys = trueOverrideSpecifiedNames = trueCamelCaseNamingStrategy

注:

Json.NET 9.0.1中引入了命名策略,因此此答案不适用于早期版本。
  • 为了获得最佳性能,您可能需要静态缓存契约解析程序。

  • 通过将NamingStrategy.ProcessDictionaryKeys设置为true,命名策略将应用于所有字典键。

  • 相关内容

    • 没有找到相关文章

    最新更新