ASP.NET MVC5验证系列之服务端验证

这篇文章,我将会说到,使用数据注解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 }
   );
  }

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

运行之后,

接着验证一下,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中服务端验证了,我们一般是使用第二种,来进行验证。也就是数据注解。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • asp.net实现获取客户端详细信息

    本文实例讲述了asp.net实现获取客户端详细信息代码.分享给大家供大家参考.具体如下: 运行效果截图如下: 具体代码如下: 其中aspx页面的控件代码: 复制代码 代码如下: <asp:ListBox runat="server" ID="lbHoverTreeInfo" ClientIDMode="Static"> </asp:ListBox> 以下是实现代码: using System; using System.W

  • ASP.NET获取真正的客户端IP地址的6种方法

    在ASP中使用 Request.ServerVariables("REMOTE_ADDR") 来取得客户端的IP地址,但如果客户端是使用代理服务器来访问,那取到的就是代理服务器的IP地址,而不是真正的客户端IP地址. 要想透过代理服务器取得客户端的真实IP地址,就要使用 Request.ServerVariables("HTTP_X_FORWARDED_FOR") 来读取. 不过要注意的事,并不是每个代理服务器都能用 Request.ServerVariables(

  • asp.net 客户端浏览器缓存的Http头介绍

    让浏览器做缓存需要给浏览器发送指定的Http头,告诉浏览器缓存多长时间,或者坚决不要缓存.作为.net的程序员,其实我们一直都在用这种方法,在OutputCache指令中指定缓存的Location为Client时,其实就是给浏览器发送了一个Http头,告诉浏览器这个Url要缓存多长时间,最后修改的时间. 微软在OutputCacheModule中对这些缓存用到的Http头给我们进行了很好的封装,但是了解这些Http头可以更灵活的使用它们. 和客户端缓存相关的Http头有以下几个,分别是: 1.

  • asp.net(C#)中给控件添加客户端js事件的方法

    放在服务器端,也可以用ajax来实现,不刷页面.但我觉得有更直接更简单方法,用一个js事件是可以实现的. 但,DropDownList不偈Button等控件提供了一些像"OnClientClick"前台事件,只有服务端事件. 想到,所有C#页面代码,最终都是生成HTML,js事件也是最终运在浏览器中,以Html为基础的.服务端控件最终生成的HTML控件有什么js事件,我们应该就能在aspx中给它添加相应的事件. DropDownList 生成的Htm是元素<Select>是

  • ASP.NET MVC+EF在服务端分页使用jqGrid以及jquery Datatables的注意事项

    一直想自己做个博客网站,技术路线是用ASN.NET MVC5+EF6(Code First)+ZUI+各种Jquery插件,有了这个想法之后就开始选择UI,看了好多bootstrap的模板之后,发现即使你用了bootstrap还是要自己写css样式,都是自学的,前端真的很垃圾,在网上找了很多UI,以下是各种UI的地址,需要的可以去看看: H-ui:http://www.h-ui.net/H-ui.admin.shtml ,是一个前端大牛弄得,模仿bootstrap,做适合中国网上的UI. Ama

  • ASP.net中获取客户端参数操作系统信息

    复制代码 代码如下: /// <summary> /// 获取用户操作系统信息 /// </summary> /// <returns></returns> public string GetUserOS() { string strSysVersion = "其他"; HttpRequest Request = HttpContext.Current.Request; string strAgentInfo = Request.Serv

  • ASP.NET简单获取服务端和客户端计算机名称的方法

    本文实例讲述了ASP.NET简单获取服务端和客户端计算机名称的方法.分享给大家供大家参考,具体如下: //获取服务端计算机名称 string serverPCName = System.Net.Dns.GetHostName(); //获取客户端计算机名称 System.Net.IPAddress clientIP = System.Net.IPAddress.Parse(Request.UserHostAddress);//根据目标IP地址获取IP对象 System.Net.IPHostEnt

  • asp.net根据计算机MAC地址限定每台机子只能领取一次账号

    下面开始吧: 首先写一个简单的前台代码: 复制代码 代码如下: <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "

  • 设置ASP.NET页面不被缓存(客户端/服务器端取消缓存方法)

    复制代码 代码如下: /// <summary> /// 设置页面不被缓存 /// </summary> private void SetPageNoCache() { Response.Buffer = true; Response.ExpiresAbsolute = System.DateTime.Now.AddSeconds(-1); Response.Expires = 0; Response.CacheControl = "no-cache"; Res

  • asp.net 从客户端中检测到有潜在危险的 Request.Form 值错误解

    从客户端(ftbContent="<P><A href="http://l...")中检测到有潜在危险的 Request.Form 值. 说明: 请求验证过程检测到有潜在危险的客户端输入值,对请求的处理已经中止.该值可能指示危及应用程序安全的尝试,如跨站点的脚本攻击.通过在 Page 指令或 配置节中设置 validateRequest=false 可以禁用请求验证.但是,在这种情况下,强烈建议应用程序显式检查所有输入. 异常详细信息: System.Web

随机推荐