文章出處

     這篇文章,我將會說到,使用數據注解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中服務端驗證了,我們一般是使用第二種,來進行驗證。也就是數據注解。

 

總結:

Server side validations ensure that the received data is correct and valid. If the received data is valid then we do further processing with the data. Server side validations are very important before playing with sensitive information of a user.

Server-side validation must be done whether we validate the received data on the client side. User could disable script in his browser or do something else to bypass client-side validation. In this case server-side validation must require to protect our data from dirty input.

 

 


文章列表




Avast logo

Avast 防毒軟體已檢查此封電子郵件的病毒。
www.avast.com


arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()