Asp.Net MVC 模型驗證詳解-實現客戶端、服務端雙重驗證

概要

         在asp.net webform開發中常常會對用戶提交輸入的信息進行校驗,通常爲了安全起見你們都會在客戶端進行Javascript(利於交互)、服務端雙重校驗(安全)。書寫校驗代碼是一個繁瑣的過程。在Asp.Net MVC中就很好的解決了這一問題、利用模型的數據註解實現客戶端與服務端雙重校驗,使你的開發效率大大提升。javascript

 

數據註解

         微軟提供了不少數據註解的類(通俗點就是特性標籤類),也爲咱們提供了自定義接口來知足開發人員不一樣的需求。下面一一爲你們說明。html

         命名空間:System.ComponentModel.DataAnnotations;java

       程序集:System.ComponentModel.DataAnnotations;jquery

StringLength特性-限制長度

         這個特性看它命名規則就知道它是什麼意思了,字符串長度對吧。是的你沒看錯,就是字符串長度。實例代碼:web

[StringLength(20,ErrorMessage = "密碼不能超過20個字符")]
public string Password { get; set; }

咱們只須要在模型屬性上加上這麼個特性,那麼校驗的時候這個字符串不能超過20個字符。ErrorMessage就是校驗不經過時的消息。正則表達式

Required特性-不能爲空

         這個特性表必須的、不能爲空的。用於不爲空校驗。默認爲不容許爲空。容許爲空則添加AllowEmptyStrings = true數據庫

[Required(ErrorMessage = "密碼不能超過20個字符")]
public string Password { get; set; }

RegularExpression-規則校驗(正則校驗)

         正則表達式在校驗中是必不可少的一部分、微軟也爲咱們提供了這個類型,很是方便的使用。安全

[RegularExpression(@"^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$", ErrorMessage = "郵箱不正確")]
public string Email { get; set; }

Range-數值範圍

         當對一個數值進行校驗時、通常可能會用到取值範圍。好比年齡:app

[Range(0,120,ErrorMessage = "年齡取值範圍0-120")]
public int Age { set; get; }

Compare-比較

         比較兩個值是否一致,通常用於二次輸入。Password是須要比較的值框架

[Compare("Password",ErrorMessage = "兩次輸入不一致")]
public string PasswordConfirm { get; set; }

Remote-遠程校驗

         這個在登陸的時候用的很是多。好比你的用戶名ID是否已經被註冊,這是須要從數據庫查詢以後才知道的。這個類有些特殊,它不在System.ComponentModel.DataAnnotations命名空間下,它是在System.Web.Mvc;命名空間下的。

 

[Remote("CheckUserName","Register",ErrorMessage = "用戶名已被註冊")]
public string UserName { get; set; }

 

Action:表明你要請求的方法

Controller:表示你要請求的控制器

這個特性有一個約定,就是你請求的這個路徑必須返回True或False,而且是以Json格式返回的。至於返回True或False的邏輯,看你們本身的需求了。

 

public ActionResult CheckUserName()
{
     return Json(false, JsonRequestBehavior.AllowGet);
}

 

Display-顯示名稱

         這個特性、我的認爲不屬於校驗裏面的一部分,它只是用戶前臺展現時的一個顯示名稱。後面在爲你們講解這個的實際應用

[Display(Name = "年齡")]
 public int Age { set; get; }

總結:

經過以上五種模型註解,通常能知足生產中大部分校驗,若有特殊校驗,能夠自定義特性來進行模型註解。瞭解了模型註解,也就是開始咱們asp.net MVC校驗的第一步了。自定義數據註解我就不說了,看下這個就能夠了:

 

http://www.cnblogs.com/zhangkai2237/archive/2012/12/12/2814825.html

數據綁定及驗證

首先要進行客戶端校驗有幾個比較重要的點:

一、  必需要用@Html.BeginForm()這種方式包含住輸入標籤。(本身試驗了下,是這樣的。若是有錯誤請好心提醒)

二、  必需要用強類型頁面。

三、  必需要引用Jquery庫、Jquery.Validate、Jquery.Validate.unobtrusive這三個文件

四、  web.config文件中這兩個值必須爲True。默認爲True

 

<appSettings>
    <add key="ClientValidationEnabled" value="true" />
    <add key="UnobtrusiveJavaScriptEnabled" value="true" />
</appSettings>

前臺代碼:

因爲我時間問題、我建立視圖的時候就直接建立了編輯視圖了。

 

   <script src="@Url.Content("~/Scripts/jquery-1.7.1.min.js")" type="text/javascript"></script>
    <script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
    <script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
    
    @using (Html.BeginForm("Create","Register")) {
        @Html.ValidationSummary(true)
        <fieldset>
            <legend>RegisterViewModel</legend>
    
            <div class="editor-label">
                @Html.LabelFor(model => model.UserName)
            </div>
            <div class="editor-field">
                @Html.EditorFor(model => model.UserName)
                @Html.ValidationMessageFor(model => model.UserName)
            </div>
    
            <div class="editor-label">
                @Html.LabelFor(model => model.Password)
            </div>
            <div class="editor-field">
                @Html.EditorFor(model => model.Password)
                @Html.ValidationMessageFor(model => model.Password)
            </div>
    
            <div class="editor-label">
                @Html.LabelFor(model => model.PasswordConfirm)
            </div>
            <div class="editor-field">
                @Html.EditorFor(model => model.PasswordConfirm)
                @Html.ValidationMessageFor(model => model.PasswordConfirm)
            </div>
    
            <div class="editor-label">
                @Html.LabelFor(model => model.Phone)
            </div>
            <div class="editor-field">
                @Html.EditorFor(model => model.Phone)
                @Html.ValidationMessageFor(model => model.Phone)
            </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>
    
            <p>
                <input type="submit" value="Save" />
            </p>
        </fieldset>
    }

補充前面一個內容、在屬性前加上Display特性,那麼在前臺@Html.LabelFor(model => model.Email)這種代碼就會優先使用Display裏面定義的名稱,若是沒有定義,則顯示屬性的名稱(UserName)。

 

後臺代碼:

 

public class RegisterController : Controller
    {
        //
        // GET: /Register/

        public ActionResult Index()
        {
            if (ModelState.IsValid)
            {
                //後臺校驗。判斷全部數據是否建議經過、
            }
            return View();
        }
        
        public ActionResult CheckUserName()
        {
            return Json(false, JsonRequestBehavior.AllowGet);
        }

        [HttpPost]
        public ActionResult Create(RegisterViewModel model)
        {
            return View();
        }
    }

 

使用Entity Framework模型

 

在實際生產中咱們用到的頗有可能就是ORM框架,或者代碼生成器生成的代碼。爲了不每次從新生成後而將咱們的數據註解給消失掉、微軟也提供了一種叫元數據共享的一種方式(我叫它」元數據」共享)

 

    /// <summary>
    /// 驗證類
    /// </summary>
    public class RegisterViewModel_Validate
    {
        [Display(Name = "用戶名")]
        [Required(ErrorMessage = "不能爲空",AllowEmptyStrings = false)]
        [Remote("CheckUserName","Register",ErrorMessage = "用戶名已被註冊")]
        public string UserName { get; set; }

        [Display(Name = "密碼")]
        [Required(ErrorMessage = "密碼不能超過20個字符")]
        public string Password { get; set; }

        [Display(Name = "確認密碼")]
        [System.ComponentModel.DataAnnotations.Compare("Password",ErrorMessage = "兩次輸入不一致")]
        public string PasswordConfirm { get; set; }

        [Display(Name = "公司電話")]
        [Required(ErrorMessage = "公司電話不能爲空")]
        [StringLength(20, ErrorMessage = "錯誤的公司電話")]
        [RegularExpression("^[0-9]+$", ErrorMessage = "公司電話不正確")]
        public string Phone { get; set; }


        [Required(ErrorMessage = "註冊人郵箱不能爲空")]
        [RegularExpression(@"^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$", ErrorMessage = "郵箱不正確")]
        public string Email { get; set; }

        [Display(Name = "年齡")]
        [Range(0,120,ErrorMessage = "年齡取值範圍0-120")]
        public int Age { set; get; }
    }
    /// <summary>
    /// 自動生成的類
    /// </summary>
    [MetadataType(typeof(RegisterViewModel_Validate))]//該類共享RegisterViewModel_Validate元數據
    public partial class RegisterViewModel
    {

    }

 

我來了看起來方便就將兩個類放到了一個文件夾下面,在生產中你仍是得分開他們,否則自動生產代碼仍是會覆蓋咱們寫的驗證代碼。

總結:

  想一想應該算是比較完整的了。但願對一些還不太明白的朋友有所幫助,本身也從新加深了印象。從事MVC開發後,

感受開發起來確實比較Web Form Happy多了,asp.net MVC這種開發方式我很是喜歡,並且可操做性、靈活性更強。

但願更多的朋友一塊兒加入MVC的陣營吧。一塊兒享受MVC 編碼的樂趣.....

 

  還有不明白的朋友能夠私密我。歡迎討論

相關文章
相關標籤/搜索