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 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);
}
{
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) {
}
: base(metadata, context, attribute) {
}
public override IEnumerable<ModelClientValidationRule> GetClientValidationRules() {
return new[] {
new ModelClientValidationRule {
ErrorMessage = "输入: Hello,world!",
ValidationType = "custom"
}
};
}
return new[] {
new ModelClientValidationRule {
ErrorMessage = "输入: Hello,world!",
ValidationType = "custom"
}
};
}
public override IEnumerable<ModelValidationResult> Validate(object container)
{
return base.Validate(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方法再加上客户端代码即可.
下例将实现一个ConfirmValidator,用于验证用户注册时两次密码必须输入一致:
1、创建一个空MVC项目
2、添加用户信息模型UserInfo.cs
public class UserInfo{
public string UserName { get; set; } public string Password { get; set; } public string ConfirmPassword { get; set; } public string Email { get; set; } }3、创建一个特性,用于指定与属性关联的另一个属性的名称
public class ConfirmValidatorAttribute : Attribute{
public String ConfirmPropertyName { get; set; } public ConfirmValidatorAttribute(string name) { ConfirmPropertyName = name; } }4、创建用于实现验证逻辑的ConfirmValidator类
public class ConfirmValidator : ModelValidator{
private string confirmPropertyName;
public ConfirmValidator(ModelMetadata metaData, ControllerContext context, string confirmProperty): base(metaData, context)
{ confirmPropertyName = confirmProperty; } public override IEnumerable<ModelValidationResult> Validate(object container) { if (container == null)yield break;
PropertyInfo pi = container.GetType().GetProperty(confirmPropertyName);
if (pi != null) { string confirmValue = (string)pi.GetValue(container, null); if ( !(Metadata.Model??String.Empty).Equals(confirmValue??String.Empty)) { yield return new ModelValidationResult() {Message = "两次输入不一致!"
};
} }else
{
throw new InvalidOperationException("属性" + confirmPropertyName + "不存在"); } } }5、创建用于产生ConfirmValidator的提供者类:ConfirmValidatorProvider
public class ConfirmValidatorProvider : AssociatedValidatorProvider{
protected override IEnumerable<ModelValidator> GetValidators(ModelMetadata metadata, ControllerContext context, IEnumerable<Attribute> attributes) { foreach (ConfirmValidatorAttribute attr in attributes.OfType<ConfirmValidatorAttribute>()) { yield return new ConfirmValidator(metadata, context, attr.ConfirmPropertyName); } } }6、创建用于测试的控制器及视图
public class HomeController : Controller { public ActionResult Index() { return View(new UserInfo()); }[HttpPost]
public ActionResult Index(UserInfo ui) {return View(ui);
} } <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/S "></script>cripts/Micro softAjax.js <script type="text/javascript" src="http://www.cnblogs.com/S "></script>cripts/Micro softMvcValid ation.js 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/S "></script>cripts/Micro softAjax.js <script type="text/javascript" src="http://www.cnblogs.com/S "></script>cripts/Micro softMvcValid ation.js <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>