我们的应用程序使用验证属性来利用ASP.NET模型验证,但是这为验证错误提供了点分隔的名称。当通过CamelCasePropertyNamesContractResolver
传递时,这仅适用于第一个点之前的驼峰字母,而我们希望将驼峰字母应用于名称的每个部分。
例如,我们当前得到当前的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; }
}
,发送的请求正文为:
{
}
答案 0 :(得分:1)
假设对于某些IDictionary<string, T>
,验证错误已被序列化为T
,那么对应于字典键的JSON属性名称可以分段驼峰式地封装在每个.
之间通过创建自定义的naming strategy字符。
Json.NET封装了逻辑,以算法重新映射NamingStrategy
类型(特别是CamelCaseNamingStrategy
)中的属性名称和字典键(例如,驼峰大小写)。要修改命名策略的逻辑以应用于.
个字符之间的属性名称的每个部分,您可以采用decorator pattern并创建一个装饰器命名策略,以将一些内部策略应用于该属性名称的每个部分。像这样的名字:
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
},
};
这利用了一个事实,如reference source所示,CamelCasePropertyNamesContractResolver
基本上只是DefaultContractResolver
的子类,它使用CamelCaseNamingStrategy
与{{1} }和ProcessDictionaryKeys = true
。
注意:
命名策略是在Json.NET 9.0.1中引入的,因此此答案不适用于早期版本。
您可能想cache the contract resolver statically for best performance。
通过将NamingStrategy.ProcessDictionaryKeys
设置为OverrideSpecifiedNames = true
,命名策略将应用于所有字典键。