我读过一些帖子,但现在无法找到它,在MVC 3中并不是真的需要创建一个Validator,只有Attribute。这是真的?我确实说我发现该属性上有IClientValidatable令人困惑。那么,如果注释具有客户端脚本名称(IClientValidatable),那么DataAnnotationsModelValidator类会做什么,以及验证的能力(ValidationAttribute IsValid)?
如果我不必在全局中使用Validator注册Attribute,那将是非常好的。可以这样做吗?我读过一些不好的建议吗?
编辑:有趣的是我只是通过排除验证器来测试它,将所有逻辑放在IsValid中并且它工作得很好。我想唯一可能缺少的是控制器上下文,但我不确定它在验证中是否有用。如果我需要服务,IsValid有ValidationContext,它有ServiceContainer。我没有在这里找到任何真正的劣势吗?
编辑2: 我将从此示例中的验证器开始:http://blogs.msdn.com/b/simonince/archive/2010/06/04/conditional-validation-in-mvc.aspx
属性:
public class RequiredIfAttribute : ValidationAttribute, IClientValidatable
{
private RequiredAttribute innerAttribute = new RequiredAttribute();
public string DependentProperty { get; set; }
public object TargetValue { get; set; }
public RequiredIfAttribute(string dependentProperty, object targetValue)
{
this.DependentProperty = dependentProperty;
this.TargetValue = targetValue;
}
public override bool IsValid(object value)
{
return innerAttribute.IsValid(value);
}
public System.Collections.Generic.IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
ModelClientValidationRule modelClientValidationRule = new ModelClientValidationRule()
{
ErrorMessage = FormatErrorMessage(metadata.DisplayName),
ValidationType = "requiredifattribute"
};
modelClientValidationRule.ValidationParameters.Add("requiredifattribute", DependentProperty);
yield return modelClientValidationRule;
}
}
验证者:
public class RequiredIfValidator : DataAnnotationsModelValidator<RequiredIfAttribute>
{
public RequiredIfValidator(ModelMetadata metadata, ControllerContext context, RequiredIfAttribute attribute)
: base(metadata, context, attribute)
{
}
public override IEnumerable<ModelClientValidationRule> GetClientValidationRules()
{
return base.GetClientValidationRules();
}
public override IEnumerable<ModelValidationResult> Validate(object container)
{
var field = Metadata.ContainerType.GetProperty(Attribute.DependentProperty);
if (field != null)
{
var value = field.GetValue(container, null);
if ((value == null && Attribute.TargetValue == null) ||
(value.Equals(Attribute.TargetValue)))
{
if (!Attribute.IsValid(Metadata.Model))
yield return new ModelValidationResult { Message = ErrorMessage };
}
}
}
}
使用上面的当前代码,我需要在Global.asax.cs文件中注册:
DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(RequiredIfAttribute), typeof(RequiredIfValidator));
但如果我将所有内容都移到属性中,我就不必注册它:
public class RequiredIfAttribute : ValidationAttribute, IClientValidatable
{
private RequiredAttribute innerAttribute = new RequiredAttribute();
public string DependentProperty { get; set; }
public object TargetValue { get; set; }
public RequiredIfAttribute(string dependentProperty, object targetValue)
{
this.DependentProperty = dependentProperty;
this.TargetValue = targetValue;
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
var field = validationContext.ObjectInstance.GetType().GetProperty(DependentProperty);
if (field != null)
{
var dependentValue = field.GetValue(validationContext.ObjectInstance, null);
if ((dependentValue == null && TargetValue == null) ||
(dependentValue.Equals(TargetValue)))
{
if (!innerAttribute.IsValid(value))
return new ValidationResult(ErrorMessage);
}
}
return ValidationResult.Success;
}
public System.Collections.Generic.IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
ModelClientValidationRule modelClientValidationRule = new ModelClientValidationRule()
{
ErrorMessage = FormatErrorMessage(metadata.DisplayName),
ValidationType = "requiredifattribute"
};
modelClientValidationRule.ValidationParameters.Add("requiredifattribute", DependentProperty);
yield return modelClientValidationRule;
}
}
最后一段代码替换所有其他代码是否有问题?为什么我会保留验证器类?
答案 0 :(得分:10)
CrazyDart,
MVC3中添加了IClientValidatable
接口。
您的第二个示例显示了此新界面的有效使用。你是正确的,它不需要注册,它将提供必要的客户端规则进行验证,以及进行必要的服务器端验证。
来吧,享受吧。
counsellorben
答案 1 :(得分:0)
当我使用CrazyDart的最后一个选项时,服务器端部分在MVC4中运行良好。
除了我无法使客户端验证工作。它从不检查客户端上的必填字段(尽管添加了一些标记)。
我还查看了Simon Ince的第二篇博文(第一篇是海报的灵感): http://blogs.msdn.com/b/simonince/archive/2011/02/04/conditional-validation-in-asp-net-mvc-3.aspx