創建ASP.NET Core MVC應用程序(6)-添加驗證
DRY原則
DRY("Don't Repeat Yourself")是MVC的設計原則之一。ASP.NET MVC鼓勵你只定義一次功能或行為,然后在應用程序中各處進行使用。這會大大
減少需要編寫的代碼量,使你的代碼不容易出錯,更便於測試和維護。
MVC和Entity Framework Core Code First所提供的驗證功能是實際應用中DRY原則的一個很好的實例。你可以在一個地方(在模型類中)聲明指定的驗證規則,在整個應用中生效。
在 User 模型類中添加驗證規則
DataAnnotations提供了一組內置的驗證特性,你可以應用在任何類或者屬性中。(字也包含了類似於DataType
這樣的格式化特性來幫助你格式化數據而不是提供任何驗證功能)
添加內置的Required
,StringLength
,RegularExpression
和Range
驗證特性。
public class User
{
public int ID { get; set; }
[Display(Name = "姓名")]
[StringLength(10, MinimumLength = 3)]
[Required]
public string Name { get; set; }
[Display(Name = "郵箱")]
[DataType(DataType.EmailAddress)]
public string Email { get; set; }
[Display(Name = "身高")]
[Required]
[Range(150, 230)]
public decimal Height { get; set; }
[Display(Name = "職稱")]
public string Title { get; set; }
[Display(Name = "部門")]
public string Dept { get; set; }
[Display(Name = "簡介")]
public string Bio { get; set; }
}
其中Required
和MinimumLength
Attribute表示屬性不能為空;但無法阻止用戶輸入空格來滿足該驗證條件。RegularExpression
Attribute用來限制用戶可以輸入的字符。Range
Attribute限制值必須在指定的范圍內。StringLength
Attribute可讓你設置字符串的最大長度,和可選的最小長度。值類型(例如decimal
,int
,float
,DateTime
)是自身必須的,不需要[Required]
Attribute。
驗證錯誤
在輸入錯誤的數據時,jQuery客戶端驗證馬上會發現錯誤,並顯示一個錯誤信息。注意表單在每個包含無效數據的字段下自動呈現適當的驗證錯誤消息。錯誤會在客戶端(使用JavaScript和jQuery)和服務器端執行。
你會發現你不需要修改UserController
類或者Create.cshtml視圖中的一行代碼,就可以驗證UI。之前創建的Controller和視圖會自動使用你在User
模型類中屬性上指定的驗證特性規則。使用Edit
操作方法測試驗證,同樣會生效。
在 Create 視圖和 Create 動作方法中驗證是如何觸發的
你可能會好奇在沒有對控制器或者視圖進行更新的情況下驗證UI是如何產生的。
// GET: User/Create
public IActionResult Create()
{
return View();
}
// POST: User/Create
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("ID,Name,Email,Bio,Height,Title,Dept")]User user)
{
if (ModelState.IsValid)
{
_context.Add(user);
await _context.SaveChangesAsync();
return RedirectToAction("Index");
}
return View(user);
}
第一個(HTTP GET)Create
方法顯示初始的Create表單。第二個([HttpPost]
)版本負責處理POST請求,通過調用ModelState.IsValid
來檢查是否有任何驗證錯誤。調用該方法會驗證任何已應用到對對象上的驗證。如果對象有驗證錯誤,Create
方法會重新顯示表單。如果沒有錯誤,方法會保存數據到數據庫。
在這個例子中,在客戶端驗證檢測到錯誤時,表單不會POST到服務器,如果你在瀏覽器中禁用了JS,客戶端驗證將會禁用,那么HTTP POST Create
方法中的ModelState.IsValid
會檢測任何驗證錯誤。
Input Tag Helper
會使用(Consume)DataAnnotations
特性並在客戶端產生(Produce)jQuery驗證所需要的HTML屬性。Validation Tag Helper
負責顯示驗證錯誤。
非常Nice的是這個方案控制器和視圖模板不需要知道任何實際執行的驗證規則或者具體的錯誤消息。驗證規則和錯誤字符串只在模型類中指定。同樣的騅規則會自動地應用到任何你想要創建或者修改該Model的視圖模板。
當你想更改驗證邏輯時,你只需要在一個地方給Model添加驗證特性。不用擔心應用的不同部分執行不同的驗證規則 - 所有的驗證邏輯在同一個地方定義,在各處使用。這意味着你充分遵循了DRY原則。
使用 DataType Attributes
System.ComponentModel.DataAnnotations
命名空間提供了內置的驗證特性以外的格式化特性。比如:
[Display(Name = "生日")]
[DataType(DataType.Date)]
public DateTime BirthDate { get; set; }
[Range(8000, 10000)]
[DataType(DataType.Currency)]
public decimal Salary { get; set; }
DataType
特性只用於視圖引擎對數據進行格式化(以及為URL提供<a>
標簽和為Email提供<a href="mailto:EmailAddress.com">
)。你可以使用RegularExpression
特性驗證數據的格式。DataType
特性用於指定比數據庫本身類型更為具體的數據類型,它們不是驗證特性,這本例中,我們只需要跟蹤日期,而不需要具體的時間。
在DataType
枚舉中提供了很多的數據類型,例如Date, Time, PhoneNumber, Currency, EmailAddress等。DataType
特性可以讓應用自動提供特定數據類型的特征。例如,DataType.EmailAddress
可以創建mailto:
鏈接,DataType.Date
可以在瀏覽器提供一個日期選擇器。DataType
特性會產生HTML 5瀏覽器所支持的HTML 5 data-
屬性。DataType
不提供任何驗證。
DataType.Date
不是指定日期的顯示格式。默認情況,數據字段默認的顯示格式是基於服務器的CultureInfo
設置來決定的。