如何仅在属性级验证器之后评估模块级验证器?
-
05-10-2019 - |
题
我正在使用模块级验证器:“ propertiesMustMatch”在我的视图模型上,就像这样:
[PropertiesMustMatch("Password", "PasswordConfirm")]
public class HomeIndex
{
[Required]
public string Name { get; set; }
public string Password { get; set; }
public string PasswordConfirm { get; set; }
}
我注意到,如果我提交未填写名称的表格,则验证()助手仅返回以下错误:
- 名称字段是必需的。
但是,如果我填写名称, 然后 验证()将返回propertiesMustMatch错误:
- “密码”和“ password Confirm”不匹配。
因此,看来首先对属性级验证器进行评估,然后是模型级验证器。
我更希望他们一次都得到了一次验证,并且验证会返回:
- 名称字段是必需的。
- “密码”和“ password Confirm”不匹配。
有什么想法我可以做什么来解决这个问题?
我正在研究MVC 2源代码,以尝试确定为什么会发生这种情况。
解决方案
我发现是什么原因引起的,但是我的“解决方案”可能会破坏验证器的正常处理。谨慎使用。
我在DefaultModelBinder的OnModelupdated函数中找到了条件返回语句:
protected override void OnModelUpdated(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
IDataErrorInfo errorProvider = bindingContext.Model as IDataErrorInfo;
if (errorProvider != null)
{
string errorText = errorProvider.Error;
if (!String.IsNullOrEmpty(errorText))
{
bindingContext.ModelState.AddModelError(bindingContext.ModelName, errorText);
}
}
// BEGIN CONDITION
if (!IsModelValid(bindingContext))
{
return;
}
// END CONDITION
foreach (ModelValidator validator in bindingContext.ModelMetadata.GetValidators(controllerContext))
{
foreach (ModelValidationResult validationResult in validator.Validate(null))
{
bindingContext.ModelState.AddModelError(CreateSubPropertyName(bindingContext.ModelName, validationResult.MemberName), validationResult.Message);
}
}
}
如果我理解此代码(我可能不这样做),似乎MVC团队目前会跳过目标模型验证器。
我已经制作了自己的自定义模型燃烧器,其中我重新运行了本应避免的代码:
public class CustomModelBinder : DefaultModelBinder
{
protected override void OnModelUpdated(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
base.OnModelUpdated(controllerContext, bindingContext);
foreach (ModelValidator validator in bindingContext.ModelMetadata.GetValidators(controllerContext))
{
foreach (ModelValidationResult validationResult in validator.Validate(null))
{
bindingContext.ModelState.AddModelError(CreateSubPropertyName(bindingContext.ModelName, validationResult.MemberName), validationResult.Message);
}
}
}
}
这似乎解决了这个问题。
不隶属于 StackOverflow