概要
在asp.net webform開發中經常會對用戶提交輸入的信息進行校驗,一般為了安全起見大家都會在客戶端進行Javascript(利於交互)、服務端雙重校驗(安全)。書寫校驗代碼是一個繁瑣的過程。在Asp.Net MVC中就很好的解決了這一問題、利用模型的數據注解實現客戶端與服務端雙重校驗,使你的開發效率大大提高。
數據注解
微軟提供了很多數據注解的類(通俗點就是特性標簽類),也為我們提供了自定義接口來滿足開發人員不同的需求。下面一一為大家說明。
命名空間:System.ComponentModel.DataAnnotations;
程序集:System.ComponentModel.DataAnnotations;
StringLength特性-限制長度
這個特性看它命名規則就知道它是什么意思了,字符串長度對吧。是的你沒看錯,就是字符串長度。實例代碼:
[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-數值范圍
當對一個數值進行校驗時、一般可能會用到取值范圍。比如年齡:
[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
數據綁定及驗證
首先要進行客戶端校驗有幾個比較重要的點:
1、 必須要用@Html.BeginForm()這種方式包含住輸入標簽。(自己試驗了下,是這樣的。如果有錯誤請好心提醒)
2、 必須要用強類型頁面。
3、 必須要引用Jquery庫、Jquery.Validate、Jquery.Validate.unobtrusive這三個文件
4、 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 編碼的樂趣.....
還有不明白的朋友可以私密我。歡迎討論