你的位置:首页 > ASP.net教程

[ASP.net教程]MVC学习系列10


     这篇文章,我将会说到,使用数据注解API来进行服务端验证。ASP.NET MVC 框架在执行的时候,验证所有传递到控制器的数据,如果验证失败就把错误消息,填充到ModelState对象中,并且把这个对象传递给控制器,然后控制器中的方法,根据Modelstate的状态来判断,是否验证失败还是验证通过。

     在这里,我将会使用两种方法来验证数据的合法性,一个是手动添加错误消息到ModelState对象中,另外一个方法是使用数据注解【Data Annotation】 API,来做。

 

先来看看使用手动验证的方式吧:

我们新建一个空白的MVC项目:添加一个Student实体:

using System;using System.Collections.Generic;using System.Linq;using System.Web;namespace Server_Side_Validation_IN_MVC.Models{  public class Student  {    public string Name { get; set; }    public string Email { get; set; }  }}

然后添加一个Student控制器:

using Server_Side_Validation_IN_MVC.Models;using System;using System.Collections.Generic;using System.Linq;using System.Text.RegularExpressions;using System.Web;using System.Web.Mvc;namespace Server_Side_Validation_IN_MVC.Controllers{  public class StudentController : Controller  {    // GET: Student    public ActionResult Index()    {      return View();    }    [HttpPost]    public ActionResult Index(Student model)    {      //服务端验证,方法一,手动添加错误消息到ModelState对象中            //如果Name是空的      if (string.IsNullOrEmpty(model.Name))      {        ModelState.AddModelError("Name", "Name is required");      }      //如果Email是空的      if (string.IsNullOrEmpty(model.Email))      {        ModelState.AddModelError("Email", "Email is required");      }      else      {        string emailRegex = @"^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}" +                      @"\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\" +                        @".)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$";        Regex re = new Regex(emailRegex);        //Email不为空的时候,但格式不合法        if (!re.IsMatch(model.Email))        {          ModelState.AddModelError("Email", "Email is not valid");        }      }      //实体验证通过      if (ModelState.IsValid)      {        ViewBag.Name = model.Name;        ViewBag.Email = model.Email;      }      return View(model);    }  }}

创建Index视图:

@model Server_Side_Validation_IN_MVC.Models.Student@{  Layout = null;}<!DOCTYPE html><html><head>  <meta name="viewport" content="width=device-width" />  <title>Index</title></head><body>  <div>     @using (Html.BeginForm())    {     //使用ViewData.ModelState.IsValid来判断ModelState的状态      if (ViewData.ModelState.IsValid)      {        if (ViewBag.Name != null)        {         <b>          Name:@ViewBag.Name<br/>          Email:@ViewBag.Email        </b>        }      }            <fieldset>        <legend>Student</legend>        <div>          @*生成label标签*@          @Html.LabelFor(model=>model.Name)        </div>        <div>          @*生成文本框*@          @Html.EditorFor(model=>model.Name)          @*不合法*@          //// @if (!ViewData.ModelState.IsValid)//这样写有问题
正确的写法:
 @if (!ViewData.ModelState.IsValid &&ViewData.ModelState["Email"].Errors.Count>0) { //从字典中获取错误消息:@ViewData.ModelState["Name"].Errors[0].ErrorMessage <span style="color:red">@ViewData.ModelState["Name"].Errors[0].ErrorMessage</span> } </div> <div> @Html.LabelFor(model=>model.Email) </div> <div> @Html.EditorFor(model=>model.Email) /////@if (!ViewData.ModelState.IsValid) 这样写有问题:
// 正确的写法在下面
  @if (!ViewData.ModelState.IsValid &&ViewData.ModelState["Email"].Errors.Count>0) { //从字典中获取错误消息:@ViewData.ModelState["Email"].Errors[0].ErrorMessage <span style="color:red">@ViewData.ModelState["Email"].Errors[0].ErrorMessage</span> } </div> <p> <input type="submit" value="Create"/> </p> </fieldset> } </div></body></html>

然后,修改一下默认的路由:

 public static void RegisterRoutes(RouteCollection routes)    {      routes.IgnoreRoute("{resource}.axd/{*pathInfo}");      routes.MapRoute(        name: "Default",        url: "{controller}/{action}/{id}",        defaults: new { controller = "Student", action = "Index", id = UrlParameter.Optional }      );    }

运行项目:

首先:验证一下,不输入任何数据,点击Create:

然后验证一下,Name有值,而Email没有值的情况:

运行之后,报错。查找了一下原因,修改了一下视图代码:

运行之后,

接着验证一下,Name不为空,Email输入非法格式的数据:

最后验证一下,输入合法的数据:

 

 好了,现在看看第二种方式,使用数据注解来进行服务端验证

新建一个类:避免混淆,

using System;using System.Collections.Generic;using System.ComponentModel.DataAnnotations;using System.Linq;using System.Web;namespace Server_Side_Validation_IN_MVC.Models{  public class StudentServer  {    [Required(ErrorMessage="Name为必填项")]    public string Name { get; set; }    [Required(ErrorMessage="电子邮件必须")]    [EmailAddress(ErrorMessage="电子邮件格式不对")]    public string Email { get; set; }  }}

在控制器中新建两个方法:

 public ActionResult SeverSideIndex()    {      return View();    }    [HttpPost]    public ActionResult SeverSideIndex(StudentServer model)    {      if (ModelState.IsValid)      {        ViewBag.Name = model.Name;        ViewBag.Email = model.Email;      }      return View();    }

对应的视图:

@model Server_Side_Validation_IN_MVC.Models.StudentServer@{  Layout = null;}@if (ViewData.ModelState.IsValid){  if (ViewBag.Name != null)  {   <b>    Name:@ViewBag.Name<br />    Email:@ViewBag.Email  </b>  }}<!DOCTYPE html><html><head>  <meta name="viewport" content="width=device-width" />  <title>SeverSideIndex</title></head><body>  <div>     @using (Html.BeginForm())    {     @Html.ValidationSummary(true)      <fieldset>        <legend>Student</legend>        <div>          @Html.LabelFor(model=>model.Name)        </div>        <div>          @Html.EditorFor(model=>model.Name)          @Html.ValidationMessageFor(model=>model.Name)        </div>        <div>          @Html.LabelFor(model => model.Email)        </div>        <div>          @Html.EditorFor(model => model.Email)          @Html.ValidationMessageFor(model => model.Email)        </div>        <p>          <input type="submit" value="Create"/>        </p>      </fieldset>          }  </div></body></html>

运行一下:

首先验证,都为空的情况:

Name不为空,Email为空

Name不为空,Email输入非法格式数据

两个都输入合法的数据:

好了,以上就是MVC中服务端验证了,我们一般是使用第二种,来进行验证。也就是数据注解。