ASP.NET MVC的四种验证编程方式(2)

针对 “某个值必须在指定的范围内”这样的验证规则,我们定义一个DomainAttribute特性。如下面的代码片断所示,DomainAttribute具有一个IEnumerable<string>类型的只读属性Values提供了一个有效值列表,该列表在构造函数中被初始化。具体的验证实现在重写的IsValid方法中,如果被验证的值在这个列表中,则视为验证成功并返回True。为了提供一个友好的错误消息,我们重写了方法FormatErrorMessage。

[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)] public class DomainAttribute : ValidationAttribute { public IEnumerable<string> Values { get; private set; } public DomainAttribute(string value) { this.Values = new string[] { value }; } public DomainAttribute(params string[] values) { this.Values = values; } public override bool IsValid(object value) { if (null == value) { return true; } return this.Values.Any(item => value.ToString() == item); } public override string FormatErrorMessage(string name) { string[] values = this.Values.Select(value => string.Format("'{0}'", value)).ToArray(); return string.Format(base.ErrorMessageString, name,string.Join(",", values)); } }

由于ASP.NET MVC在进行参数绑定的时候会自动提取应用在目标参数类型或者数据成员上的ValidationAttribute特性,并利用它们对提供的数据实施验证,所以我们不再需要像上面演示的实例一样自行在Action方法中实施验证,而只需要在定义参数类型Person的时候应用相应的ValidationAttribute特性将采用的验证规则与对应的数据成员相关联。

如下所示的是属性成员上应用了相关ValidationAttribute特性的Person类型的定义。我们在三个属性上均应用了RequiredAttribute特性将它们定义成必需的数据成员,Gender和Age属性上则分别应用了DomainAttribute和RangeAttribute特性对有效属性值的范围作了相应限制。

public class Person { [DisplayName("姓名")] [Required(ErrorMessageResourceName = "Required", ErrorMessageResourceType = typeof(Resources))] public string Name { get; set; } [DisplayName("性别")] [Required(ErrorMessageResourceName = "Required", ErrorMessageResourceType = typeof(Resources))] [Domain("M", "F", "m", "f", ErrorMessageResourceName = "Domain", ErrorMessageResourceType = typeof(Resources))] public string Gender { get; set; } [DisplayName("年龄")] [Required(ErrorMessageResourceName = "Required", ErrorMessageResourceType = typeof(Resources))] [Range(18, 25, ErrorMessageResourceName = "Range", ErrorMessageResourceType = typeof(Resources))] public int? Age { get; set; } }

三个ValidationAttribute特性采用的错误消息均定义在项目默认的资源文件中(我们可以采用这样的步骤创建这个资源文件:右键选择Solution Exploror中的项目,并在上下文菜单中选择“属性”选项打开“项目属性”对象框。最后在对话框中选择“资源”Tab页面,通过点击页面中的链接创建一个资源文件),具体定义如图2所示。

由于ASP.NET MVC会自动提取应用在绑定参数类型上的ValidationAttribute特性对绑定的参数实施自动化验证,所以我们根本不需要在具体的Action方法中来对参数作手工验证。如下面的代码片断所示,我们在Action方法Index中不再显式调用Validate方法,但是运行该程序并在输入不合法数据的情况下提交表单后依然会得到如图1所示的输出结果。

public class HomeController : Controller { //其他成员 [HttpPost] public ActionResult Index(Person person) { if (!ModelState.IsValid) { return View(person); } else { return Content("输入数据通过验证"); } } }

三、让数据类型实现IValidatableObject接口

除了将验证规则通过ValidationAttribute特性直接定义在数据类型上并让ASP.NET MVC在进行参数绑定过程中据此来验证参数之外,我们还可以将验证操作直接定义在数据类型中。既然我们将验证操作直接实现在了数据类型上,意味着对应的数据对象具有“自我验证”的能力,我们姑且将这些数据类型称为“自我验证类型”。这些自我验证类型是实现了具有如下定义的接口IValidatableObject,该接口定义在“System.ComponentModel.DataAnnotations”命名空间下。

public interface IValidatableObject { IEnumerable<ValidationResult> Validate( ValidationContext validationContext); }

如上面的代码片断所示,IValidatableObject接口具有唯一的方法Validate,针对自身的验证就实现在该方法中。对于上面演示实例中定义的数据类型Person,我们可以按照如下的形式将它定义成自我验证类型。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wjwxwj.html