应用ModelState和Data Annotation做服务器端数据验证

来源:互联网 发布:哈萨克斯坦知乎 编辑:程序博客网 时间:2024/05/17 01:39


前言

在提交数据前进行数据验证可以保证数据的完整性及有效性。

本节介绍MVC框架中常用的两种服务器端数据验证方式:

  • 向ModelState中直接添加错误信息

  • 通过Data Annotation验证数据

通过ModelState验证数据

首先,在Models文件夹下创建Model,文件名为ModelStateModel.cs,代码如下:

隐藏代码namespace SlarkInc.Models{    public class ModelStateModel    {        public string Name { get; set; }        public string Email { get; set; }    }}

Model有Name 和 Email 两个属性,后面我们将对这两个属性做验证。

在Controllers文件夹下创建名为DataValidationController的控制器,代码如下:

隐藏代码using System.Web.Mvc;using SlarkInc.Models;using System.Text.RegularExpressions;namespace SlarkInc.Controllers{    public class DataValidationController : Controller    {        public ActionResult ModelStateAction()        {            return View();        }        [HttpPost]        public ActionResult ModelStateAction(ModelStateModel model)        {            if (string.IsNullOrEmpty(model.Name))            {                ModelState.AddModelError("Name", "Name is required");            }            if (string.IsNullOrEmpty(model.Email))            {                ModelState.AddModelError("Email", "Email is required");            }            else            {                string expression = @"^\s*([A-Za-z0-9_-]+(\.\w+)*@([\w-]+\.)+\w{2,3})\s*$";                Regex reg = new Regex(expression);                if(!reg.IsMatch(model.Email))                {                    ModelState.AddModelError("Email", "Email is invalid");                }            }            if (ModelState.IsValid)            {                ViewBag.Name = model.Name;                ViewBag.Email = model.Email;            }            return View(model);        }    }}

代码第9行是通过Get方法访问ModelStateAction,第14行通过Post方法访问ModelStateAction。我们知道服务器端验证是验证提交到服务器的数据,那么这个验证就一定是在Post方法调用的Action中。第17-20行,表示如果model.Name是空,则在ModelState中加入错误信息。AddModelError函数有两个参数,第一个是错误信息的Key,第二个是错误信息的内容。Key的内容一般是属性的名字,这样将来在View中就能在属性对应的地方显示错误信息。同理21-14行验证邮箱是否填写。27-32行验证邮箱是否有效。第34行,ModelState.IsValid是一个bool变量。当没有任何服务器端验证错误时,IsValid是true,否则是false。第34-39行表示如果没有错误则将提交的信息在View中显示出来。

接下来在Views\DataValidation\文件夹下创建ModelStateAction.cshtml文件,对应之前创建的Action。View代码如下:

隐藏代码@model SlarkInc.Models.ModelStateModel@{    ViewBag.Title = "ModelStateAction";}<h2>ModelState Validation</h2>@Html.ValidationSummary()@using (Html.BeginForm()){    if(@ViewData.ModelState.IsValid && ViewBag.Name != null)    {        <b>            Name : @ViewBag.Name            <br />            Email: @ViewBag.Email        </b>    }    <fieldset>        <div class="editor-label">            @Html.LabelFor(model=>model.Name)        </div>        <div class="editor-field">            @Html.EditorFor(model => model.Name)            @Html.ValidationMessageFor(model => model.Name)        </div>        <div class="editor-label">            @Html.LabelFor(model=>model.Email)        </div>        <div class="editor-field">            @Html.EditorFor(model => model.Email)            @Html.ValidationMessageFor(model => model.Email)        </div>        <br />        <input type="submit" value="Submit" />    </fieldset>

之前我们在Controller中做了服务器端验证,那么这里的View就负责显示验证错误信息。

第6行,Html.ValidationSummary()会把所有验证不通过的信息逐条显示出来。第9行,ViewData.ModelState.IsValid表示验证是否通过。第9-16行表示如果通过验证则在View中显示出来提交的信息。第23、30行,用Html.ValidationMessageFor函数显示属性对应的验证错误信息。

按F5运行这个View。

填入如下所示信息并提交,可以看到数据验证信息:

从图中可以看到ValidationSummary()函数显示了所有验证信息。ValidationMessageFor()函数显示自己对应属性的验证信息。

下面输入正确信息,显示结果如图所示:

图中红色方框内的信息就是提交验证成功ModelState.IsValid为true时显示出来的。

通过Data Annotation验证数据

在Models文件夹下创建名为DataAnnotationModel的Model。代码如下:

隐藏代码using System.ComponentModel.DataAnnotations;namespace SlarkInc.Models{    public class DataAnnotationModel    {        [Required(ErrorMessage = "Name is required")]        public string Name { get; set; }        [Required(ErrorMessage = "Email is required")]        [RegularExpression(@"^\s*([A-Za-z0-9_-]+(\.\w+)*@([\w-]+\.)+\w{2,3})\s*$", ErrorMessage = "Email is invalid")]        public string Email { get; set; }    }}

不同于ModelState的方法,这里主要是在Model中加入需要验证的条件。

第1行,要使用Data Annotation就需要引用System.ComponentModel.DataAnnotations。第7、10、11行使用了Data Annotation,是对属性的注解。其形式就是一个中括号里包了一个函数。第7、10行,Required()表示这个属性是必填的,ErrorMessage的值是必填项没有填时,显示的错误提示信息。第11行,RegularExpression()是正则表达式验证,只有符合正则表达式的字符串才能通过验证。

在DataValidationController中加入DataAnnotationAction(),代码如下:

隐藏代码using System.Web.Mvc;using SlarkInc.Models;using System.Text.RegularExpressions;namespace SlarkInc.Controllers{    public class DataValidationController : Controller    {        public ActionResult DataAnnotationAction()        {            return View();        }        [HttpPost]        public ActionResult DataAnnotationAction(DataAnnotationModel model)        {            if (ModelState.IsValid)            {                ViewBag.Name = model.Name;                ViewBag.Email = model.Email;            }            return View(model);        }    }}

这里的Controller相对前一种验证要简单一些。唯一与验证相关的是第17行ModelState.IsValid,如果验证通过,则向View传入提交的信息。

下面来写这个Action对应的View。在Views\DataValidation文件夹中创建DataAnnotationAction.cshtml文件,写入如下代码:

隐藏代码@model SlarkInc.Models.DataAnnotationModel@{    ViewBag.Title = "DataAnnotationAction";}<h2>Data Annotation Validation</h2>@Html.ValidationSummary()@using (Html.BeginForm()){    if (@ViewData.ModelState.IsValid && ViewBag.Name != null)    {        <b>            Name : @ViewBag.Name            <br />            Email: @ViewBag.Email        </b>    }    <fieldset>        <div class="editor-label">            @Html.LabelFor(model => model.Name)        </div>        <div class="editor-field">            @Html.EditorFor(model => model.Name)            @Html.ValidationMessageFor(model => model.Name)        </div>        <div class="editor-label">            @Html.LabelFor(model => model.Email)        </div>        <div class="editor-field">            @Html.EditorFor(model => model.Email)            @Html.ValidationMessageFor(model => model.Email)        </div>        <br />        <input type="submit" value="Submit" />    </fieldset>}

基本上和上一个方法的View一模一样,验证相关的语句都已经用黄色标出。

按F5运行当前View,填入以下信息并提交,页面会显示如下错误信息:

填入正确信息提交之后之后,会显示出提交的信息,结果如下:

结尾

本节我们用了两种不同的方法ModelState和Data Annotation进行服务器端验证。可以看到,两种方法是等效的,结果一模一样。

0 0