ASP.NET MVC5(四):数据注解和验证

前言



  用户输入验证的工作,不仅要在客户端浏览器中执行,还要在服务端执行。主要原因是客户端验证会对输入数据给出即时反馈,提高用户体验;服务器端验证,主要是因为不能完全信任用户提供的数据。ASP.NET MVC框架提供了强大的验证组件帮助我们处理这些繁杂的问题。

数据验证


验证注解的使用

  验证注解特性定义在命名空间System.ComponentModel.DataAnnotations中,它们提供了服务器端验证的功能,当在模型的属性上使用时,框架也支持客户端验证。常用特性简介:

  • Required
    当属性值为null或者空时,将引发一个验证错误,可以理解为若添加了Required特性,则此项为必填项。
  • StringLength
    限定字符串长度。
  • RegularExpression
    使用正则表达式验证输入的字符串是否符合格式要求。
  • Range
    用来指定输入数值来的最小值和最大值。
  • Compare
    用来判断两个属性是否拥有相同的值。例如,确保两次输入的密码相同。
  • Remote
    利用服务器端的回调函数执行客户端的逻辑验证。

下面,通过一个简单的示例来讲解这些特性的使用方法。
假设现在我们开发一套图书管理系统,在Models文件夹中创建Book类,用来保存书籍的基本信息。

public class Book
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Author { get; set; }
    public int PagesNumber { get; set; }
    public string Publisher { get; set; }
    public string PublicationDate { get; set; }
    public string Content { get; set; }
    public decimal Price { get; set; }
    public decimal PriceConfirm { get; set; }
}

添加BooksController,启动项目,此时,ASP.NET MVC已经利用基架模板帮助我们创建好了相应的controller和View,直接将浏览器定位到/Books/Create,可浏览如下用来添加书籍的页面。

在添加书籍时,用户希望对输入的数据进行一些验证,当输入的数据无法通过相关验证时,返回错误信息。此时,验证注解特性就派上了用场。
第一步,引入命名空间

using System.ComponentModel.DataAnnotations;
using System.Web.Mvc;

向BooksController中添加CheckContent方法(为了使用remote特性做准备)

    public JsonResult CheckContent(string content)
    {
        var result = db.Books.Where(m => m.Content == content).Count() == 0;
        return Json(result, JsonRequestBehavior.AllowGet);
    }

修改Book类,分别添加验证注解:

    public int Id { get; set; }
    [Required] //必填
    public string Name { get; set; }
    [StringLength(50)] //作者姓名的长度不能超过50个字符
    public string Author { get; set; }
    [Range(100, 10000)] //页数保证在100~10000页之间
    public int PagesNumber { get; set; }
    public string Publisher { get; set; }
    [RegularExpression(@"^\d{4}(\-|\/|\.)\d{1,2}\1\d{1,2}$")]   //日期格式
    public string PublicationDate { get; set; }
    [Remote("CheckContent", "Books")]   //内容介绍不能重复
    public string Content { get; set; }
    public decimal Price { get; set; }
    [System.ComponentModel.DataAnnotations.Compare("Price")]  //两次输入的价格必须一致
    public decimal PriceConfirm { get; set; }

重新启动项目,在Create页面输入不符合验证逻辑的数据,效果如下:

重新输入正确的数据,点击Create,数据成功录入后,我们再录入另外一本书籍,Content内容与上一次添加的内容相同,得到错误信息,此时Remote特性调用了CheckContent方法进行验证。

★注意,Remote特性自动发送AJAX请求访问后台代码来实现验证,它只有客户端验证,没有服务端验证。也就是说,当用户浏览器关闭js,Remote检查将不起作用,因此,Remote特性存在一定的安全隐患。同理,如果创建Controller时没有勾选Reference script libraries选项,Remote特性也将不起任何作用。

自定义错误提示

  每个验证特性都允许传入一个带有自定义错误提示消息的参数,例如以上示例中RegularExpression特性返回的错误消息,用户可能无法理解正则表达式的含义,此时,我们就需要返回一些简单易懂的错误消息,向RegularExpression传入ErrorMessage参数。

    [RegularExpression(@"^\d{4}(\-|\/|\.)\d{1,2}\1\d{1,2}$",ErrorMessage ="请输入有效的日期格式,例如:2017-06-16")]   //日期格式
    public string PublicationDate { get; set; }

效果如下:

验证注解的后台原理及控制器操作

  默认情况下,ASP.NET MVC框架在模型绑定时执行验证逻辑。模型绑定器一旦使用新值完成对模型属性的更新,就会利用当前的模型元数据获得模型的所有验证器。ASP.NET MVC运行时提供了一个验证器DataAnnotationsModelValidator来与数据注解一同工作。这个模型验证器会找到所有的验证特性并执行它们包含的验证逻辑。模型绑定器捕获所有失败的验证规则并把它们存放在模型状态中。

  控制器操作决定了在模型验证失败或成功时程序的执行流程。通常情况下,验证成功,保存用户输入数据,验证失败,重新渲染视图,返回错误消息。以下是系统自动创建的Create方法,首先判断模型状态ModelState是否存在错误,若不存在,则保存书籍信息,若存在败,则重新渲染视图。

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Create([Bind(Include = "Id,Name,Author,PagesNumber,Publisher,PublicationDate,Content,Price,PriceConfirm")] Book book)
    {
        if (ModelState.IsValid)
        {
            db.Books.Add(book);
            db.SaveChanges();
            return RedirectToAction("Index");
        }

        return View(book);
    }

自定义验证逻辑



  上一节中介绍了这么多验证注解,我们不禁会问,用户经常会提出很多奇葩的需求,我们能否自己定义一些验证逻辑呢?答案是肯定的。本节,将介绍如何完成自定义逻辑验证。

自定义注解

  所有验证注解特性最终都派生自基类ValidationAttribute,它是个抽象类,因此,创建自定义注解特性时也必须派生自ValidationAttribute类。
假设用户提出一个需求,由于某位作者遭到无情封杀,录入书籍信息时,作者一栏不能为指定的人名。

首先,添加CheckAuthorAttribute类派生自基类ValidationAttribute:

using System.ComponentModel.DataAnnotations;

namespace MyFirstMvcProject.Infrastructure
{
    public class CheckAuthorAttribute : ValidationAttribute
    {
    }
}

为了实现这个验证,需要重写基类的IsValid方法,ValidationContext参数提供了可在IsValid方法内部使用的信息,如模型类型、模型对象实例、用来验证属性的显示名称等。IsValid方法的第一个参数是要验证的对象的值,另外,我们通过构造函数获取不能通过验证的人名。

public class CheckAuthorAttribute : ValidationAttribute
{
    public string Author { get; set; }

    public CheckAuthorAttribute(string author) : base("{0} can not be this one. ")
    {
        this.Author = author;
    }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        if (value != null)
        {
            if (value.ToString() == Author)
            {
                return new ValidationResult(FormatErrorMessage(validationContext.DisplayName));
            }
        }
        return ValidationResult.Success;
    }
}

上述代码有两点需要注意:

  1. 向基类构造函数传递一个默认值的错误提示信息。
  2. FormatErrorMessage方法:基于出现比较错误的数据字段对错误消息应用格式设置。

修改Book类,在Author属性上添加CheckAuthor特性。

    [StringLength(50)] //作者姓名的长度不能超过50个字符
    [CheckAuthor("Thomas", ErrorMessage = "Author can not be this one.")]
    public string Author { get; set; }

运行程序,输入Author,点击Create,效果如下:

到目前为止,我们已经成功创建自定义注解特性,但是细心的用户又发现了,新添加的验证只有在点击了Create后才能触发,其他的验证都可以给出即时反馈。正如用户所说,目前我们只添加了服务端验证,下面将介绍如何为CheckAuthor特性添加客户端验证。

修改MaxWordsAttribute类,使其继承IClientValidatable接口,实现GetClientValidationRules方法。

 public class CheckAuthorAttribute : ValidationAttribute, IClientValidatable
 {
    public string Author { get; set; }

    public CheckAuthorAttribute(string author) : base("{0} can not be this one. ")
    {
        this.Author = author;
    }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        if (value != null)
        {
            if (value.ToString() == Author)
            {
                return new ValidationResult(FormatErrorMessage(validationContext.DisplayName));
            }
        }
        return ValidationResult.Success;
    }

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
    {
        var rule = new ModelClientValidationRule() { ValidationType = "checkauthor", ErrorMessage = FormatErrorMessage(metadata.GetDisplayName()) };
        rule.ValidationParameters.Add("author", Author);

        yield return rule;
    }
}

说明:

  1. IClientValidatable接口为ASP.NET MVC验证框架提供一种用于在运行时发现验证程序是否支持客户端验证的方法。GetClientValidationRules在类中实现,返回该类的客户端验证规则。
  2. ErrorMessage属性用于存放错误提示消息。
  3. ValidationParameters集合用于存放客户端需要的参数,本例中即为Thomas.
  4. ValidationType属性标识了客户端需要的一段JavaScript代码。

在Scripts文件夹下添加JavaScript文件,命名为customvalidators.js,键入如下代码:

/// <reference path="jquery.validate.js" />
/// <reference path="jquery.validate.unobtrusive.js" />

$.validator.addMethod("checkauthor", function (value, element, author) {
    if (value) {
        if (value == author) {
            return false;
        }
    }
    return true;
});

$.validator.unobtrusive.adapters.addSingleVal("checkauthor", "author");

说明:

  1. AddSingleVal为需要从元数据中检索唯一参数值的验证规则创建适配器。第一个参数是适配器名称,第二个参数是要从元数据中检索的参数的名称。
  2. 调用validator.AddMethod方法添加新的验证器。

最后,在Views/Books/Create.cshtml中添加对customvalidators.js的引用:

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
    <script src="~/Scripts/customValidators.js"></script>
}

启动程序,将Url定位到/Books/Create,在Author文本框中输入Thomas,当焦点离开Author文本框后即可完成验证。

时间: 2024-10-25 04:51:40

ASP.NET MVC5(四):数据注解和验证的相关文章

asp.net mvc常用的数据注解和验证以及entity framework数据映射

终于有时间整理一下asp.net mvc 和 entity framework 方面的素材了. 闲话少说,步入正题: 下面是model层的管理员信息表,也是大伙比较常用到的,看看下面的代码大伙应该不会陌生, 在此Model上我们用到了asp.net mvc的数据注解和验证,entity framework对数据库的映射 1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.T

数据注解和验证

①利用数据注解进行验证 ②创建自定义的验证逻辑 ③模型元数据注解的用法 ①先创建数据源 1,创建我们的Model  Order 2,创建控制器带EF 选择模型为Order 当你运行的时候会报错,需要代码迁移    code First 更新数据库 这篇文章可解决这个问题. 3,添加,不做处理的时候,显示的是这个 ②验证注解的使用 2.1自定义错误提示信息及其本地化 2.2 注解的后台原理 ASP.NET MVC 的验证特性是由模型绑定器.模型元数据.模型验证器和模型状态组成的协调系统的一部分.

数据注解和验证 &ndash; ASP.NET MVC 4 系列

       不仅在客户端浏览器中需要执行验证逻辑,在服务器端也需要执行.客户端验证能即时给出一个错误反馈(阻止请求发送至服务器),是时下 Web 应用程序所期望的特性.服务器端验证,主要是因为来自网络的信息都是不可信任的.        当在 ASP.NET MVC 设计模式上下文中谈论验证时,主要关注的是验证模型的值.ASP.NET MVC 验证特性可以帮助我们验证模型值,且这样验证特性是可扩展的,所以我们可以采用任意想要的方式构建验证模式,默认方法是一种声明式验证,即数据注解特性.    

ASP.NET MVC5----常见的数据注解和验证

只要一直走,慢点又何妨. 在使用MVC模式进行开发时,数据注解是经常使用的(模型之上操作),下面是我看书整理的一些常见的用法. 什么是验证,数据注解 验证 从全局来看,发现逻辑仅是整个验证的很小的一部分.验证首先需要管理用户友好(本地化)的与验证逻辑相关的错误提示消息:当验证失败时,在把这些错误提示消息呈现给用户界面上,当然还要向用户提供从验证失败中恢复的机制. 数据注解 注解是一种通用机制,可以用来向框架注入元数据,同时,框架不只驱动元数据的验证,还可以在生成显示和编辑模型的HTML标记时使用

Asp.net MVC 数据注解与验证

数据注解特性定义在名称空间System.ComponentModel.DataAnnotations中(有些特性定义在其他名称空间中),它们提供了服务器端验证的功能,当在模型的属性上使用这些特性时,框架也支持客户端验证. 常用特性 1.Required --必填字段示例:[Required]2.StringLength --字符长度限制示例:[StringLength(16,MinimumLength=3)]3.RegularExpression --正则表达式验证示例:[RegularExpr

枚举帮助方法,枚举数据注解自定义验证器

枚举辅助类 获取枚举项列表 获取枚举值列表 枚举项包含 枚举值包含 转换枚举 代码如下 1 /// <summary> 2 /// 枚举辅助类 3 /// </summary> 4 public class EnumHelper 5 { 6 7 private static readonly Dictionary<Type, object> EnumCache = new Dictionary<Type, object>(); 8 9 private sta

MVC4数据注解和验证

model中的验证注解特性: public class StuInfo { public int ID { get; set;} [Display(Name = "姓名")] //设置要显示的字段名 [Required(ErrorMessage = "您需要填写{0}")] //设置为必须字段 已经错误提示 [StringLength(50, MinimumLength = 3)] //设置最大长度和最小长度 public string Name { get; se

数据注解与验证

mvc自带验证的使用方法: 一,在类中打上标记 1,[Required]  不为空 2,[StringLength(50,MinimumLength=3)] 字符串长度最大和最小值 3,[RegularExpression("正则")]  正则表达式验证 4,[Range(1,10)] 数字长度 5,[Compare("类名")]判断两次输入是否一致 6,[Display(Name="",Order=100)] 设置视图中的名称以及排序 Erro

MVC 5 数据注解

ASP.NET MVC5中的数据注解(转载) ASP.NET MVC5中数据注解原理: 1.asp.net MVC 的验证特性是由模型绑定器.模型元数据.模型验证器.模型状态组成的协调系统的一部分. 2.注解原理和步骤:  验证与模型绑定:   (1).ASP.NET  MVC 默认情况下,在模型绑定时执行验证逻辑.如果控制器中的操作方法带有参数时,就会隐式地执行模型绑定.或者是利用控制器的UpdateModel或者            TryUpdateModel方法显式执行模型绑定.