2011-05-24 41 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; }