2011-05-24 75 views
17

我是新的數據註釋。我想知道是否有可能(以及如何)動態添加一些驗證。這是非常廣泛的解釋爲什麼,但我有一個ViewModel接收和創建時的對象。在這個對象中,我必須檢查一些財產,並根據它的價值我應該有或沒有一些驗證。ASP.NET MVC 3數據註釋:動態添加驗證

一個例子:

public class ProfileViewModel 
{ 
    [Required(ErrorMessage = "The field {0} is required")] 
    [Display(Name = "Client Code")] 
    public int ClientCode { get; set; } 

    [Required(ErrorMessage = "The field {0} is required")] 
    [StringLength(100, ErrorMessage = "The field {0} must have up to 100 characters.")] 
    [Display(Name = "Company")] 
    public string Company { get; set; } 

    [StringLength(50, ErrorMessage = "The field {0} must have up to 50 characters.")] 
    [Display(Name = "Name")] 
    public string Name { get; set; } 

    [StringLength(50, ErrorMessage = "The field {0} must have up to 50 characters.")] 
    [Display(Name = "LastName")] 
    public string LastName { get; set; } 

    public ProfileViewModel(User usr) 
    { 
     if (usuario.ClientCode != null) 
     { 
      ClientCode = Convert.ToInt32(usr.ClientCode); 
     } 
     else 
     { 
      //ClientCode and Company are not yet required. 
      //Name and LastName are now required. 
     } 
     Company = usr.Company; 
     Name = usr.Name; 
     LastName = usr.LastName; 
    } 
} 

回答

9

我認爲做什麼,我想最簡單的方法是實施IValidatableObject

public class Product : IValidatableObject 
{ 
    public int Prop1 { get; set; } 
    public int Prop2 { get; set; } 

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) 
    { 
     if (Prop1 < Prop2) 
      yield return new ValidationResult("Property 1 can't be less than Property 2"); 
    } 
} 

另見:Class-Level Model Validation with ... ASP.NET MVC 3

+1

的問題是,這種不添加客戶端驗證。因此,如果您已經使用基於屬性的客戶端驗證,則會導致不一致的用戶體驗。 MS把它全部錯誤地綁定到屬性驗證。 – xr280xr 2015-06-22 17:27:11

+0

你說得對。這不會添加客戶端驗證。如果你需要它,我相信最好的方法是編寫你自己的腳本來添加驗證。 – Diego 2015-06-22 17:50:05

5

定製屬性

[AttributeUsage(AttributeTargets.Property, AllowMultiple = true, Inherited = true)] 
public class CustomRequiredIfAttribute : CustomAttribute 
{ 
    private RequiredAttribute innerAttribute = new RequiredAttribute(); 
    public string DependentProperty { get; set; } 
    public object TargetValue { get; set; } 

    public CustomRequiredIfAttribute() 
    { 
    } 

    public CustomRequiredIfAttribute(string dependentProperty, object targetValue) 
     : base() 
    { 
     this.DependentProperty = dependentProperty; 
     this.TargetValue = targetValue; 
    } 

    public override bool IsValid(object value) 
    { 
     return innerAttribute.IsValid(value); 
    } 
} 


定製RequiredIfValidator

using System; 
using System.Collections.Generic; 
using System.Web.Mvc; 

namespace Custom.Web.Validation 
{ 
    public class RequiredIfValidator : DataAnnotationsModelValidator<CustomRequiredIfAttribute> 
    { 
     public RequiredIfValidator(ModelMetadata metadata, ControllerContext context, CustomRequiredIfAttribute attribute) 
      : base(metadata, context, attribute) 
     { 
     } 

     public override IEnumerable<ModelClientValidationRule> GetClientValidationRules() 
     { 
      return base.GetClientValidationRules(); 
     } 

     public override IEnumerable<ModelValidationResult> Validate(object container) 
     { 
      // get a reference to the property this validation depends upon 
      var field = Metadata.ContainerType.GetProperty(Attribute.DependentProperty); 

      if (field != null) 
      { 
       // get the value of the dependent property 
       object value = field.GetValue(container, null); 

       // compare the value against the target value 
       if (this.IsEqual(value) || (value == null && Attribute.TargetValue == null)) 
       { 
        // match => means we should try validating this field 
        if (!Attribute.IsValid(Metadata.Model)) 
        { 
         // validation failed - return an error 
         yield return new ModelValidationResult { Message = ErrorMessage }; 
        } 
       } 
      } 
     } 

     private bool IsEqual(object dependentPropertyValue) 
     { 
      bool isEqual = false; 

      if (Attribute.TargetValue != null && Attribute.TargetValue.GetType().IsArray) 
      { 
       foreach (object o in (Array)Attribute.TargetValue) 
       { 
        isEqual = o.Equals(dependentPropertyValue); 
        if (isEqual) 
        { 
         break; 
        } 
       } 
      } 
      else 
      { 
       isEqual = Attribute.TargetValue.Equals(dependentPropertyValue); 
      } 

      return isEqual; 
     } 
    } 
} 


註冊定製DataAnnotationsModelValidatorProvider

DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(CustomRequiredIfAttribute), typeof(RequiredIfValidator)); 


使用此CustomRequiredIf視圖模型

[CustomRequiredIf("CategoryId", 3, ErrorMessageResourceName = GlobalResourceLiterals.AccountGroup_Required)] 
public string AccountGroup { get; set; }