我们的应用程序使用验证属性来使用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 = true
和OverrideSpecifiedNames = true
的CamelCaseNamingStrategy
。
注:
Json.NET 9.0.1中引入了命名策略,因此此答案不适用于早期版本。为了获得最佳性能,您可能需要静态缓存契约解析程序。
通过将NamingStrategy.ProcessDictionaryKeys
设置为true
,命名策略将应用于所有字典键。