第6章:数据注解和验证
@Html.EditorForModel():
会反射model的每一个属性,并找到最合适的方式渲染
FormCollection:
Action中使用FormCollection作为参数,可以获取所有表单的值
验证注解的使用:
数据注解定义在System.ComponentModel.DataAnnotation中(有些特性不是)。
他们提供了服务器端验证和客户端验证。
基本验证:
Required:必输校验
StringLength:长度校验(注意重载)
RegularExpression:正则表达式校验
Range:数值范围校验,重载有int,double。可使用重载其它类型,如decimal(书上说可以验证date,可是试过不行?)
System.Web.Mvc下的特性验证:
Remote:允许通过服务器端的回调函数执行客户端验证逻辑,如下
Model: [Remote("CheckUserName","Account")] public string UserName{set;get;} Controller: public JsonResult CheckUserName(string username) { return Json(false,JsonRequestBehavior.AllowGet); }
Compare:用于确保两个属性有相同的值,如下:
[Compare("Email")] public string EmailConfrm{get;set;}
自定义错误提示及本地化:
可选参数里都能定义错误信息,错误信息中写{0}可与获得当前属性的显示名,如下:
[Required(ErrorMessage="Your {0} is required!")] public string LastName{get;set;}
将提示:Your LastName is required!
使用
ErrorMessageResourceType=typeof(ErrorMessage),ErrorMessageResourceName="LastNameRequired")]
public string LastName{get;set;}
可以读取ErrorMessage.resx的资源文件,并获取其中的LastNameRequired值
注解的后台原理:
默认情况下,ASP.NET MVC框架在模型帮顶时执行验证逻辑。
模型邦定器一旦完成对模型属性的更新,就会利用当前的模型元数据获得模型的所有验证器。这运行时提供了一个验证其(DataAnnotationModelValidator)来与注解一同工作。这个模型验证器会找到所有的验证特性并执行它们包含的验证逻辑。ModelBinder捕获所有失败的验证其规则并把它们放入ModelState中。
模型绑定的主要产物就是ModelState(Controller的属性)。
这个对象不仅包含了用户所有想放入模型属性里的值,也包括与每一个属性相关联的所有错误,和模型本身的错误,如果存在错误ModelState.IsValid返回false。
ModelState("LastName").Errors[0].ErrorMessage;//查看LastName属性的错误信息
View中查看:@Html.ValadationMessageFor(m=>m.LastName)
在编辑操作的PostAction中,可以先使用ModelState.IsValid属性判断是否通过验证,在不同对待。
自定义验证逻辑——自定义Attribute:
需要实现抽象类ValidationAtribute的IsValid方法,它定义在Syetem.ComponentModel.DataAnnotations,例子如下:
//验证属性中包含的单词最大值 public class MaxWordsAttrbute:ValidationAttribute { private readonly int maxWords; public MaxWordsAttrbute(int maxWords/*最大单词数*/) : base("{0} has too many words.") { this.maxWords = maxWords; } protected override ValidationResult IsValid(object value/*需要验证的值*/, ValidationContext validationContext) { if (value != null) { var valueAsString = value.ToString(); if (valueAsString.Split(' ').Length > maxWords) { var errorMessage = FormatErrorMessage(validationContext.DisplayName); return new ValidationResult(errorMessage); } } return ValidationResult.Success; } }
自定义验证逻辑——实现IValidatableObject:
例子如下:
public class LogOnModel:IValidatableObject { [Required] public string UserName { get; set; } [Required] public string Password { get; set; } public bool RememberMe { get; set; } public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) { if (!string.IsNullOrEmpty(UserName) && UserName.ToUpper() == "TEST") { yield return new ValidationResult("用户名不能是TEST!", new string[] { "UserName"}); } if (!string.IsNullOrEmpty(Password) && Password == "123456") { yield return new ValidationResult("密码不能是123456!", new string[] { "Password" }); } } }
显示和编辑注解:
Deiplay:为Model:显示友好的显示名
ScaffoldColumn:可以隐藏EditorForModel和DisplayForModel等渲染的一些属性。注意,如果请求里有匹配的值,还是会绑定。
DisplayFormat:按指定的格式显示,如下:
[DisplayFormat(ApplyFormatInEditMode=true,DataFormatString="{0:c}")]
public decimal Total { get; set; }
值为123时候,将会显示为¥123.00,注意ApplyFormatInEditMode属性在编辑和模型绑定时候的问题。
ReadOnly
DataType
HiddenInput:显示为隐藏域
UIHint:模版名字(不懂,后面会讲到)