狮王

导航

MVC 两种自定义验证方法

1.使用MVC缺省的DataAnnotationsModelValidatorProvider,这样我们只需要自己定义一个从ValidationAttribute继承的类,并实现其IsValid(object value)方法的逻辑即可实现服务器端验证,要实现其客户端验证,需要定义一个从DataAnnotationsModelValidator<CustomAttribute>继承的验证类,其需实现其GetClientValidationRules方法,并在Application_Start()中使用DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(ConfirmValidatorAttribute), typeof(ConfirmValidator)); 注册,最后再加上客户端代码即可.
例:
[AttributeUsage(AttributeTargets.All, AllowMultiple = false)]
 public class CustomAttribute : ValidationAttribute {
        public override bool IsValid(object value)
        {
            var val = value as string;
            if (string.IsNullOrEmpty(val))
            {
                return false;
            }
            return val.Equals("Hello,world!", StringComparison.OrdinalIgnoreCase);
        }
}
 
public class CustomValidator : DataAnnotationsModelValidator<CustomAttribute> {
  public CustomValidator(ModelMetadata metadata, ControllerContext context, CustomAttribute attribute)
   : base(metadata, context, attribute) {
  }
  public override IEnumerable<ModelClientValidationRule> GetClientValidationRules() {
   return new[] {
    new ModelClientValidationRule {
     ErrorMessage = "输入: Hello,world!",
     ValidationType = "custom"
    }
   };
  }
        public override IEnumerable<ModelValidationResult> Validate(object container)
        {
            return base.Validate(container);
        }
 }
 
protected void Application_Start()
{
DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(ConfirmValidatorAttribute), typeof(ConfirmValidator));
}
2.使用自己定义的验证提供器,首先定义一个特性类(继承于Attribute),然后再定义一个验证类(继承于ModelValidator)并重写Validate方法实现验证逻辑,再创建用于产生提供者类继承于AssociatedValidatorProvider并实现GetValidators方法,最后在Application_Start()中使用ModelValidatorProviders.Providers.Add(new ConfirmValidatorProvider())注册即可实现自定义的服务器端验证,要实现客户端验证,需要在验证类中重写GetClientValidationRules方法再加上客户端代码即可.
来自:http://www.cnblogs.com/xfrog/archive/2011/01/25/1944867.html
下例将实现一个ConfirmValidator,用于验证用户注册时两次密码必须输入一致:

1、创建一个空MVC项目

2、添加用户信息模型UserInfo.cs

显示行号 复制代码 UserInfo
  1. public class UserInfo
    
  2.  {
    
  3.     public string UserName { get; set; }
    
  4.     public string Password { get; set; }
    
  5.     public string ConfirmPassword { get; set; }
    
  6.     public string Email { get; set; }
    
  7. }
    
  8. 
    

3、创建一个特性,用于指定与属性关联的另一个属性的名称

显示行号 复制代码 ConfirmValidatorAttribute
  1. public class ConfirmValidatorAttribute : Attribute
    
  2.  {
    
  3.     public String ConfirmPropertyName { get; set; }
    
  4. 
    
  5.     public ConfirmValidatorAttribute(string name)
    
  6.     {
    
  7.         ConfirmPropertyName = name;
    
  8.     }
    
  9. }
    
  10. 
    

4、创建用于实现验证逻辑的ConfirmValidator类

显示行号 复制代码 ConfirmValidator
  1. public class ConfirmValidator : ModelValidator
    
  2.  {
    
  3.     private string  confirmPropertyName;
    
  4.     public ConfirmValidator(ModelMetadata metaData, ControllerContext context, string confirmProperty)
    
  5.         : base(metaData, context)
    
  6.     {
    
  7.         confirmPropertyName = confirmProperty;
    
  8.     }
    
  9. 
    
  10.     public override IEnumerable<ModelValidationResult> Validate(object container)
    
  11.     {
    
  12.         if (container == null)
    
  13.             yield break;
    
  14.         PropertyInfo pi = container.GetType().GetProperty(confirmPropertyName);
    
  15.         if (pi != null)
    
  16.         {
    
  17.             string confirmValue = (string)pi.GetValue(container, null);
    
  18.             if ( !(Metadata.Model??String.Empty).Equals(confirmValue??String.Empty))
    
  19.             {
    
  20.                 yield return new ModelValidationResult()
    
  21.                 {
    
  22.                     Message = "两次输入不一致!"
    
  23.                 };
    
  24.             }
    
  25.         }
    
  26.         else
    
  27.         {
    
  28.             throw new InvalidOperationException("属性" + confirmPropertyName + "不存在");
    
  29.         }
    
  30.     }
    
  31. }
    
  32. 
    

5、创建用于产生ConfirmValidator的提供者类:ConfirmValidatorProvider

显示行号 复制代码 ConfirmValidatorProvider
  1. public class ConfirmValidatorProvider : AssociatedValidatorProvider
    
  2.  {
    
  3.     protected override IEnumerable<ModelValidator> GetValidators(ModelMetadata metadata, ControllerContext context, IEnumerable<Attribute> attributes)
    
  4.     {
    
  5.         foreach (ConfirmValidatorAttribute attr in attributes.OfType<ConfirmValidatorAttribute>())
    
  6.         {
    
  7.             yield return new ConfirmValidator(metadata, context, attr.ConfirmPropertyName);
    
  8.         }
    
  9.     }
    
  10. }
    
  11. 
    

6、创建用于测试的控制器及视图

显示行号 复制代码 HomeController
  1. public class HomeController : Controller
    
  2. {
    
  3.     public ActionResult Index()
    
  4.     {
    
  5.         return View(new UserInfo());
    
  6.     }
    
  7.     [HttpPost]
    
  8.     public ActionResult Index(UserInfo ui)
    
  9.     {
    
  10.         return View(ui);
    
  11.     }
    
  12. }
    
  13. 
    
<body>
    <div>
    <%using(Html.BeginForm()){ %>
        <%= Html.ValidationSummary(true) %>
        <%= Html.EditorFor(x=>x) %>
        <input type="submit" value="提交" />
    <%} %>
    </div>
</body>

7、修改UserInfo.cs,在ConfirmPassword属性上添加ConfirmValidator特性。

[ConfirmValidator("Password")]
public string ConfirmPassword { get; set; }
 

8、在Global Application_Start中添加ConfirmValidatorProvider

ModelValidatorProviders.Providers.Add(new ConfirmValidatorProvider());
 

    实现客户端验证:

1、修改ConfirmValidator类,添加GetClientValidationRules方法。

public override IEnumerable<ModelClientValidationRule> GetClientValidationRules()
{
    ModelClientValidationRule rule = new ModelClientValidationRule()
    {
        ErrorMessage = "两次输入不一致!",
        ValidationType = "ConfirmValidator"
    };
    rule.ValidationParameters["ConfirmPropertyName"] = confirmPropertyName;
    yield return rule;
}
 

2、修改Index.aspx,添加对Ajax脚本的引用

<script type="text/javascript" src="http://www.cnblogs.com/Scripts/MicrosoftAjax.js"></script>
<script type="text/javascript" src="http://www.cnblogs.com/Scripts/MicrosoftMvcValidation.js"></script>

3、添加自定义验证脚本

<script type="text/javascript">
    Sys.Mvc.ValidatorRegistry.validators.ConfirmValidator = function (rule) {
        var propertyName = rule.ValidationParameters.ConfirmPropertyName;
        return function (value, context) {
            var confirmValue = document.getElementsByName(propertyName)[0].value;
            return (value == confirmValue);
        }
    };
</script>

4、开启客户端验证功能

<%Html.EnableClientValidation(); %>

5、将ConfirmPassword属性加入客户端验证

<% Html.ValidateFor(x => x.ConfirmPassword); %>

修改后完整视图代码:

<body>
    <div>
    <%Html.EnableClientValidation(); %>
    <%using(Html.BeginForm()){ %>
        <%= Html.ValidationSummary(true) %>
        <% Html.ValidateFor(x => x.ConfirmPassword); %>
        <%= Html.EditorFor(x=>x) %>
        <input type="submit" value="提交" />
    <%} %>
    </div>
    <script type="text/javascript" src="http://www.cnblogs.com/Scripts/MicrosoftAjax.js"></script>
    <script type="text/javascript" src="http://www.cnblogs.com/Scripts/MicrosoftMvcValidation.js"></script>
    <script type="text/javascript">
        Sys.Mvc.ValidatorRegistry.validators.ConfirmValidator = function (rule) {
            var propertyName = rule.ValidationParameters.ConfirmPropertyName;
            return function (value, context) {
                var confirmValue = document.getElementsByName(propertyName)[0].value;
                return (value == confirmValue);
            }
        };
    </script>
</body>

posted on 2011-02-16 15:12  狮王  阅读(1478)  评论(0编辑  收藏  举报