我读了一些帖子,但现在不能发现,在MVC 3中,创建验证器并不是真正需要的,只是属性.这是真的?我说我觉得这个属性有它的IClientValidatable,令人困惑.那么如果注释具有客户端脚本名称(IClientValidatable)和验证(ValidationAttribute IsValid)的能力,DataAnnotationsModelValidator类将执行什么操作?
如果我没有在全局中注册与验证器的属性,这将是非常好的.这可以做吗我读了一些不好的建议吗?
编辑:有趣的是,我只是通过排除验证器来测试它,将所有的逻辑放在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,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,DependentProperty); yield return modelClientValidationRule; } }