使用 DataAnnotationsModelValidatorProvider.RegisterAdapter 的 MVC 2 與 MVC 3 自定義驗證屬性
我讀過一些文章,但現在找不到它,因為在 MVC 3 中實際上不需要創建驗證器,只需要創建屬性。這是真的?我確實說我發現屬性上有 IClientValidatable 令人困惑。那麼,如果註解具有客戶端腳本名稱(IClientValidatable)和驗證能力(ValidationAttribute IsValid),DataAnnotationsModelValidator 類會做什麼?
如果我不必在全域中使用 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; } }最後一段程式碼替換所有其他程式碼有問題嗎?為什麼我要保留驗證器類?
瘋狂飛鏢,
該
IClientValidatable介面是在MVC3中添加的。您的第二個範例顯示了對這個新介面的有效使用。您是正確的,它不必註冊,它將提供必要的客戶端驗證規則,以及進行必要的伺服器端驗證。
來吧,享受它。
輔導員本
當我使用 CrazyDart 的最後一個選項時,伺服器端部分在 MVC4 中執行良好。
除非我無法讓客戶端驗證正常工作。它從不檢查客戶端的必填欄位(儘管添加了一些標籤)。
我還查看了 Simon Ince 的第二篇博文(第一篇是海報的靈感):http: //blogs.msdn.com/b/simonince/archive/2011/02/04/conditional-validation-in -asp-net-mvc-3.aspx