[翻译-ASP.NET MVC]Contact Manager开发之旅迭代3 - 验证表单
注:為保證可讀性,文中Controller、View、Model、Route、Action等ASP.NET MVC核心單詞均未翻譯。
?
ContactManager開發之旅-索引頁
ContactManager開發之旅 迭代1 - 創建應用程序
ContactManager開發之旅 迭代2 - 修改樣式,美化應用
迭代3 - 驗證表單
這是Contact Manager的第三次迭代,在這次迭代中我們將為Contact Manager添加基本的表單驗證。如果用戶填寫的表單不完整,我們將阻止其表單的提交。另外我們還要驗證電話號碼和電子郵件地址的合法性。(圖1)
?
圖1
本次迭代中,我們將驗證邏輯直接寫在controller的action中,不過這并不是ASP.NET MVC應用所推薦的方式。更好的辦法是將這些驗證邏輯布置到另外的service層中。下一次迭代的時候我們將重構Contact Manager應用,使其更易維護。
為了讓本文看起來直觀些,我們將在本次迭代中手寫所有的驗證代碼。當然我們也可以利用某些現成的驗證框架來實現自動生成這些驗證代碼。比如你可以使用Microsoft Enterprise Library Validation Application Block (VAB)來實現ASP.NET MVC的驗證邏輯。欲知更多VAB的信息,請看下面的鏈接:
http://msdn.microsoft.com/en-us/library/dd203099.aspx
為Create View添加驗證規則
現在就讓我們開始為Create view添加驗證規則吧。在前兩次迭代中,我們已經通過VS生成了Create view,拖VS的福我們的Create view已經包含了頁面中顯示驗證消息所需的所有邏輯。Create view如下:
?
<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<ContactManager.Models.Contact>" %><asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server"><h2>Create</h2><%= Html.ValidationSummary("Create was unsuccessful. Please correct the errors and try again.") %> <% using (Html.BeginForm()) {%> <fieldset><legend>Fields</legend><p><label for="FirstName">FirstName:</label><%= Html.TextBox("FirstName") %> <%= Html.ValidationMessage("FirstName", "*") %> </p><p><label for="LastName">LastName:</label><%= Html.TextBox("LastName") %> <%= Html.ValidationMessage("LastName", "*") %> </p><p><label for="Phone">Phone:</label><%= Html.TextBox("Phone") %> <%= Html.ValidationMessage("Phone", "*") %> </p><p><label for="Email">Email:</label><%= Html.TextBox("Email") %> <%= Html.ValidationMessage("Email", "*") %> </p><p><input type="submit" value="Create" /></p></fieldset><% } %> <div><%=Html.ActionLink("Back to List", "Index") %> </div></asp:Content>注意緊靠HTML表單頂部的Html.ValidationSummary()這個helper方法。如果存在驗證產生的錯誤信息,這個方法將使用無序列表呈現這些消息。
另外,每個表單對象后面調用的Html.ValidationMessage()方法會顯示對應這個表單對象所產生的驗證錯誤消息。比如上面所示代碼中的情況下,如果存在驗證錯誤,那么這里將會顯示一個*號。
最后,如果存在驗證錯誤,Html.TextBox()方法會自動為相關表單對象添加一個名為input-validation-error 的樣式
當你新建一個ASP.NET MVC應用程序的時候,Content文件夾中默認生成的Site.css中便包含了這些驗證相關的樣式定義:
/* messages -------------*/div.information, div.error, div.success, ul.validation-summary-errors {margin:1em 0;padding:1em; }div.information {color:#C60;background-color:#FF9;border:1px solid #F90; }div.error, ul.validation-summary-errors {color: #F00;background-color:#C99;border:1px solid #900; }div.success {color: #060;background-color:#9C9;border:1px solid #060; }.input-validation-error {border: 1px solid #ff0000;background-color: #ffeeee; }?
field-validation-error是用來定義Html.ValidationMessage()呈現時的樣式,input-validation-error用來定義textbox(input)的樣式,而Vaidation-summary-errors則用來定義Html.ValidationSummary()方法呈現的無序列表的樣式。
你可以通過修改這些默認的樣式規則從而美化和自定義這些驗證錯誤消息的表現。
為Create Action添加驗證規則
到目前為止,Create view不會顯示任何的驗證錯誤信息。因為我們尚未編寫其生成消息的邏輯規則。這里你需要向ModelState添加錯誤消息。
指定的表單對象的值與對應屬性發生驗證錯誤時,UpdateModel()方法將自動添加錯誤消息到ModelState中。例如,如果你打算將“apple”作為BirthDate屬性的值但是該屬性只接受DateTime類型,則UpdateModel()方法會添加一個錯誤至ModelState中。
修改后的Create()方法代碼如下,我們其添加了在新聯系人插入數據庫前驗證聯系人屬性的相關代碼部分:
//// POST: /Home/Create[AcceptVerbs(HttpVerbs.Post)]public ActionResult Create([Bind(Exclude = "Id")] Contact contactToCreate){//Validation logicif (contactToCreate.FirstName.Trim().Length == 0)ModelState.AddModelError("FirstName", "First name is required");if (contactToCreate.LastName.Trim().Length == 0)ModelState.AddModelError("LastName", "Last name is required");if (contactToCreate.Phone.Trim().Length == 0 || !Regex.IsMatch(contactToCreate.Phone, @"((\(\d{3}\) ?)|(\d{3}-))?\d{3}-\d{4}"))ModelState.AddModelError("Phone", "Invalid phone number");if (contactToCreate.Email.Trim().Length == 0 || !Regex.IsMatch(contactToCreate.Email, @"^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$"))ModelState.AddModelError("Email", "Invalid email address");if (!ModelState.IsValid){return View();}else{try{_entities.AddToContactSet(contactToCreate);_entities.SaveChanges();return RedirectToAction("Index");}catch{return View();}}}- FirstName屬性的長度必須大于0(并且不計算空格)
- LastName屬性長度必須大于0(并且不計算空格)。
- 如果Phone屬性有值(且長度大于0),則Phone屬性必須匹配正則表達式。
- 如果Email屬性有值(且長度大于0),則Email屬性必須匹配正則表達式。
如果違反了其中某條驗證規則,則一條錯誤消息將通過AddModelError()方法添加至ModelState中,你只需指定需驗證的屬性以及違反相應驗證規則時顯示的錯誤提示信息。這條信息將會顯示在view中調用Html.ValidationSummary()和Html.ValidationMessage()方法的地方。
驗證規則執行后就可以使用ModelState的IsValid屬性了。該屬性根據屬性是否遵循ModelState中的規則返回一個布爾值。如果未通過驗證,Create表單中將顯示錯誤信息。
我是從http://regexlib.com/的“正則表達式倉庫”中找到驗證電話號碼和電子郵件地址的正則表達式的,希望它能幫到你。
為Edit Action添加驗證規則
Edit() action用來更新一個聯系人信息。它需要執行與Create() action中基本相似的驗證規則。我們在這里重構Contact controller使得Create()及Edit() action可以復用驗證規則。代碼如下:
using System; using System.Collections.Generic; using System.Linq; using System.Text.RegularExpressions; using System.Web; using System.Web.Mvc; using System.Web.Mvc.Ajax; using ContactManager.Models;namespace ContactManager.Controllers {public class ContactController : Controller{private ContactManagerEntities _entities = new ContactManagerEntities();protected void ValidateContact(Contact contactToValidate){if (contactToValidate.FirstName.Trim().Length == 0)ModelState.AddModelError("FirstName", "First name is required.");if (contactToValidate.LastName.Trim().Length == 0)ModelState.AddModelError("LastName", "Last name is required.");if (contactToValidate.Phone.Length > 0 && !Regex.IsMatch(contactToValidate.Phone, @"((\(\d{3}\) ?)|(\d{3}-))?\d{3}-\d{4}"))ModelState.AddModelError("Phone", "Invalid phone number.");if (contactToValidate.Email.Length > 0 && !Regex.IsMatch(contactToValidate.Email, @"^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$"))ModelState.AddModelError("Email", "Invalid email address.");}//// GET: /Home/public ActionResult Index(){return View(_entities.ContactSet.ToList());}//// GET: /Home/Details/5public ActionResult Details(int id){return View();}//// GET: /Home/Createpublic ActionResult Create(){return View();}//// POST: /Home/Create[AcceptVerbs(HttpVerbs.Post)]public ActionResult Create([Bind(Exclude = "Id")] Contact contactToCreate){//Validation logicValidateContact(contactToCreate);if (!ModelState.IsValid){return View();}else{try{_entities.AddToContactSet(contactToCreate);_entities.SaveChanges();return RedirectToAction("Index");}catch{return View();}}}//// GET: /Home/Edit/5public ActionResult Edit(int id){var contractToEdit = _entities.ContactSet.Where(c => c.Id == id).FirstOrDefault();return View(contractToEdit);}//// POST: /Home/Edit/5[AcceptVerbs(HttpVerbs.Post)]public ActionResult Edit(Contact contactToEdit){ValidateContact(contactToEdit);if (!ModelState.IsValid)return View();try{var originalContact = _entities.ContactSet.Where(c => c.Id == contactToEdit.Id).FirstOrDefault();_entities.ApplyPropertyChanges(originalContact.EntityKey.EntitySetName, contactToEdit);_entities.SaveChanges();return RedirectToAction("Index");}catch{return View();}}//// GET: /Home/Delete/5public ActionResult Delete(int id){var contactToDelete = _entities.ContactSet.Where(c => c.Id == id).FirstOrDefault();return View(contactToDelete);}//// POST: /Home/Delete/5[AcceptVerbs(HttpVerbs.Post)]public ActionResult Delete(Contact contactToDelete){try{var originalContact = _entities.ContactSet.Where(c => c.Id == contactToDelete.Id).FirstOrDefault();_entities.DeleteObject(originalContact);_entities.SaveChanges();return RedirectToAction("Index");}catch{return View();}}} }總結
在本次迭代中,我們為Contact Manager應用添加了基本的表單驗證。我們的驗證邏輯會阻止用戶在新增聯系人、編輯聯系人的情景下將未填寫FirstName或LastName屬性的表單進行提交。并且用戶需要填寫有效的電話號碼和電子郵箱地址。
本文中我們使用了最簡單的方式為Contact Manager應用添加驗證邏輯,然而將驗證規則與controller耦合將會對應用程序的維護產生深遠的負面影響。我們的應用將越來越難維護和修改。
我們會在下一次迭代中重構我們的驗證邏輯和數據庫存儲邏輯并將其與controller解耦。得益于適當設計模式的幫助,應用中耦合將更加松散且程序更易維護。
轉載于:https://www.cnblogs.com/cxd4321/archive/2009/09/17/1568696.html
總結
以上是生活随笔為你收集整理的[翻译-ASP.NET MVC]Contact Manager开发之旅迭代3 - 验证表单的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 结构体指定初始化
- 下一篇: 简单JS实现走马灯效果的文字(无需jQu