只要一直走,慢点又何妨。javascript
在使用MVC模式进行开发时,数据注解是常用的(模型之上操做),下面是我看书整理的一些常见的用法。html
验证java
从全局来看,发现逻辑仅是整个验证的很小的一部分。验证首先须要管理用户友好(本地化)的与验证逻辑相关的错误提示消息;当验证失败时,在把这些错误提示消息呈现给用户界面上,固然还要向用户提供从验证失败中恢复的机制。正则表达式
数据注解sql
注解是一种通用机制,能够用来向框架注入元数据,同时,框架不仅驱动元数据的验证,还能够在生成显示和编辑模型的HTML标记时使用元数据。通俗的说就是模型上面的特定标识符(具备必定意义和做用)。数据库
数据注解定义在通常在命名空间”System.ComponentModel.DataAnnotations”提供了服务器端验证的功能,在模型属性上使用时,框架也支持客户端验证。注解后面都是能够添加错误提示语的,ErrorMessage是每一个验证特性中用来设置错误提示消息的参数,好比:编程
[Required(ErrorMessage = "不能为空")] public int Age { get; set; }
强调属性是必须的,不可为空。当属性中有一个是null或空时,会引起一个验证错误。json
[Required] public int Age { get; set; }
要求必须输入名字的长度。参数能够限制最小的。以下:数组
[StringLength(160,MinimumLength = 3)] public string Name { get; set; }
正则表达式验证,好比邮箱等须要验证正则的地方。非常方便,这样就减小了服务端的验证。安全
[RegularExpression(@"^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+(.[a-zA-Z0-9_-])+",ErrorMessage = "邮箱输入有误,从新输入。")] public string Email { get; set; }
用来指定数值类型值得最小值和最大值。主要为int类型服务。其他的也能够,须要使用构造函数的重载版本。Type参数来作。
[Range(20,30,ErrorMessage = "年龄不符合要求")] public int Age { get; set; }
[Range(typeof(decimal),"0.00","59.99")] public decimal Price { get; set; }
肯定两个模型属性拥有同样的值。密码的验证(输入两次,看两者是否同样。),参数为前面模型的值。
[Required(ErrorMessage = "密码不能为空")] public string Password { get; set; } [Compare("Password")] public string PasswordPalt { get; set; }
此特性利用服务器端的回调函数执行客户端的验证逻辑。通俗的说就是这个特性能够直接找到某个控制器的action而且执行其中的方法。
/// <summary> /// 验证模型中输入的姓名是否和数据库中重复 /// </summary> /// <returns></returns> public JsonResult CheckUserName(string username) {
//数据库中的相关验证 return Json(DateTime.Now.ToString(),JsonRequestBehavior.AllowGet); }
[Remote("CheckUserName", "Admin")] public string UserName { get; set; }
上面控制器操做会利用与UserName属性同名的参数进行验证,同时返回一个javascript object Notaion(json)对象中的布尔类型值(0/1)
使用{0}占位符,来显示用户的输入,而且造成友好提示。
[Range(20,30,ErrorMessage = "年龄{0}不符合要求")] public int Age { get; set; }
ASP.NET MVC的验证特性是由模型绑定器,模型元数据,模型验证器和模型状态组成。
验证和模型绑定
这里有一个隐式地执行模型绑定,通常咱们都须要这样写,这样也安全,不会说暴露出来参数。
这个实际项目中使用的不多,通常都是经过隐式进行转换的。
[HttpPost,ActionName("Create")] public ActionResult CreatePost(Student model) { var model2 = new Student(); UpdateModel(model2); if (TryUpdateModel(model2)) { } return View(model); }
能够看到参数中的为隐式转换,里面的model2为显式转换。if中的返回的是bool类型。模型绑定器一旦使用新值完成对模型属性的更新,就会利用当前的 模型元数据得到模型的全部验证器。MVC运行时提供了一个验证器(DataAnnotationsModelValidator)来与数据注解一同工做,这个模型验证器会找到全部的验证特性并执行它们包含的验证逻辑,模型绑定器捕获全部失败的验证规则并把它们放入模型状态中。
编程的一个重要原则是不能相信用户的输入
验证与模型状态
模型绑定的副产品是模型状态,也就是咱们服务端验证的ModelState,此状态中不只包含用户的输入,也含有每一个相关属性的全部错误(与模型状态自己有关的错误),有错误,ModelState.IsValid就返回false。从而咱们就能够进行验证。
public ActionResult CreatePost(Student model) { var s=ModelState.IsValidField("UserName"); var ss=ModelState["UserName"].Errors.Count; var userName = ModelState["UserName"].Errors[0].ErrorMessage; //获取错误消息 if (ModelState.IsValid) //返回bool类型 { } return View(model); }
显示模型属性设置友好的“显示名称”
[Display(Name = "姓名")] [StringLength(160,MinimumLength = 3)] public string Name { get; set; }
能够隐藏HTML的辅助方法
[ScaffoldColumn(false)] public string Address { get; set; }
处理属性各类格式化选项,当属性包含空值,能够提供可选的显示文本。也能够为包含标记的属性关闭HTML编码。还能够运行时指定一个应用于属性值的格式化字符串。
[DisplayFormat(ApplyFormatInEditMode = true,DataFormatString = "{0:c}")] public decimal Total { get; set; }
能够确保默认的模型绑定器不使用请求中的新值来更新属性。
运行时提供关于属性的特定用途信息。String类型的属性可应用于不少场合--能够保存e-mail地址,URL或密码。
[Required(ErrorMessage = "密码不能为空")] [DataType(DataType.Password)] public string Password { get; set; }
给运行时提供一个模版名称,以备调用模版辅助方法渲染输出时使用。
把验证逻辑封装在自定义的数据注解中能够轻松地实如今多个模型中重用逻辑。须要在特性内部编写代码以应对不一样类型的模型中。
自定义注解
全部的验证注解特性最终都派生自基类ValidationAttribute,它是个抽象类,在System.ComponentMode.DataAnnotation中定义。一样自定义的验证逻辑必须派生自ValidationAttribute的类。且重写IsValid方法(方法里面实现咱们相应的逻辑)。
需求:限制用户输入地址中单词数量,设定一个最大值。
/// <summary> /// 自定义模型验证 /// 输入数字的单词最大数量 /// </summary> public class MaxWordsAttribute:ValidationAttribute { private readonly int _maxWord; public MaxWordsAttribute(int maxWord) { _maxWord = maxWord; } protected override ValidationResult IsValid(object value,ValidationContext validationContext) { if (value!=null) { //将输入转换为string类型 var valueAsString = value.ToString(); //使用split(' ')空格来分隔输入值,统计生成字符串的数量。对数目比较验证。 if (valueAsString.Split(' ').Length>_maxWord) { return new ValidationResult("单词超过长度"); //string类型 } } return ValidationResult.Success; //bool类型 } }
第一个参数要验证对象中的值。后面进行逻辑的判断。这样作这里的错误提示不能显示到前台。咱们须要修改下,使用ValidationAttrubute的ErrorMessage属性来自定义提示错误消息。
修改以后
public class MaxWordsAttribute:ValidationAttribute { private readonly int _maxWord; public MaxWordsAttribute(int maxWord) :base("{0} has too many words") { _maxWord = maxWord; } protected override ValidationResult IsValid(object value,ValidationContext validationContext) { if (value!=null) { //将输入转换为string类型 var valueAsString = value.ToString(); //使用split(' ')空格来分隔输入值,统计生成字符串的数量。对数目比较验证。 if (valueAsString.Split(' ').Length>_maxWord) { var errorMessage = FormatErrorMessage(validationContext.DisplayName); return new ValidationResult(errorMessage); } } return ValidationResult.Success; //bool类型 } }
[MaxWords(5)] public string Address { get; set; }
这样效果就会将咱们基类中的错误信息显示出来。
咱们能够模型基础上添加自定义错误显示。
[MaxWords(5,ErrorMessage = "你输入的单词数超界限,请从新输入。")] public string Address { get; set; }
这里须要注意这里的执行顺序,它是先执行模型上面的验证,接着在到控制器中的action中去的。利用ModelState.IsValid来进行验证。
自验证模型(IValidatableObject)
自验证模型是指一个知道如何验证自身的模型对象,可让类实现IVaalidatableObject接口来实现对自身的验证。
public class Information:IValidatableObject { public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) { if (UserName!=null&&UserName.Split(' ').Length>5) { yield return new ValidationResult("单词超界限了"); } } [Display(Name = "用户名")] public string UserName { get; set; } }
其实书上面是在错误返回值中返回的是string类型的数组,以下
yield return new ValidationResult("单词超界限了",new []{"UserName"});
能够我不知道从那里取出来这个错误消息。只能单独的显示出来。其实把错误消息放在数组中能够进行多模型的验证,从而统一将错误显示出来。
本身的感受要是须要模型验证,最好仍是进行第一种方法,最起码代码看起来干净,第二种给人的感受是很乱,可是第二种适合比较模型多的场合。
我就是我,颜色不同的烟火。