ASP.NET Core 中文文檔 第二章 指南(4.9)添加驗證

来源:http://www.cnblogs.com/dotNETCoreSG/archive/2016/06/21/aspnetcore-2_4_9-validation.html
-Advertisement-
Play Games

原文: "Adding Validation" 作者: "Rick Anderson" 翻譯: "謝煬(Kiler)" 校對: "孟帥洋(書緣)" 、 "婁宇(Lyrics)" 、 "許登洋(Seay)" 在本章節中你將為 模型類添加驗證邏輯,以確保在用戶試圖創建或編輯影片數據時強制執行驗證規則。 ...


原文:Adding Validation
作者:Rick Anderson
翻譯:謝煬(Kiler)
校對:孟帥洋(書緣)婁宇(Lyrics)許登洋(Seay)

在本章節中你將為 Movie 模型類添加驗證邏輯,以確保在用戶試圖創建或編輯影片數據時強制執行驗證規則。

保持DRY原則

ASP.NET MVC 的核心原則之一是 DRY (“不要重覆自己”)。ASP.NET MVC 鼓勵你只指定一次行為或者功能,然後可以在應用程式裡面到處使用,這樣大大的減少了需要編寫的代碼量,並且使你編寫不容易出錯,更容易測試,以及更容易維護的代碼。

ASP.NET MVC 和 Entity Framework Core Code First 中的驗證功能,是 DRY 原則實際應用的一個很好的實例。你可以在某個位置(模型類)聲明指定方式的驗證規則,驗證規則可以在整個應用程式中生效。

讓我們來看看如何在電影應用程式中利用驗證功能。

向 Movie 模型中添加驗證規則

打開 Movie.cs 文件。DataAnnotations 提供了內置的驗證屬性,你可以對任何類或屬性應用。(它也同時包含了一些格式化屬性比如 DataType 用來幫你格式化數據而非提供驗證功能。)

現在修改 Movie 類,利用內置的 RequiredStringLengthRegularExpression 以及 Range 驗證屬性。

public class Movie
{
    public int ID { get; set; }

    [StringLength(60, MinimumLength = 3)] //手工高亮
    public string Title { get; set; }

    [Display(Name = "Release Date")]
    [DataType(DataType.Date)]
    public DateTime ReleaseDate { get; set; }

    [RegularExpression(@"^[A-Z]+[a-zA-Z''-'\s]*$")] //手工高亮
    [Required] //手工高亮
    [StringLength(30)] //手工高亮
    public string Genre { get; set; }

    [Range(1, 100)] //手工高亮
    [DataType(DataType.Currency)] //手工高亮
    public decimal Price { get; set; }

    [RegularExpression(@"^[A-Z]+[a-zA-Z''-'\s]*$")] //手工高亮
    [StringLength(5)] //手工高亮
    public string Rating { get; set; }
}

驗證特性指定了你想要應用到模型屬性上的驗證行為。Required 以及 MinimumLength 屬性表示屬性不能為空,但無法阻止用戶用填寫空格的方式來滿足此驗證條件。RegularExpression 屬性用來限制用戶輸入的文字類型。 在上面的例子中,Genre 以及 Rating 只能輸入字母(不允許輸入空格、數字以及特殊字元)。Range 屬性限制值在指定的範圍內。StringLength 屬性可讓你設定字元串最大長度,以及最小長度(可選)。值類型(如decimal, int, float, DateTime)預設情況下,並不需要 [Required] 屬性。

ASP.NET 自動執行的驗證規則將有助於使你的應用程式更加健壯。它還確保提醒你不要忘記驗證數據,讓非法數據進入到資料庫中。

MVC 中的驗證錯誤 UI

運行程式並導航到 Movies controller。

點擊 Create New 鏈接創建一個新的 Movie。在表單中填寫一些無效的數據,jQuery 客戶端驗證馬上就會發現錯誤,立刻呈現到界面上。

validation/_static/val.png

註意
你也許無法在 Price 欄位中輸入小數點或者逗號。為了讓 jQuery validation 支持非英語環境使用逗號(",")代替小數點,以及非美式英語日期格式,你必須採取措施國際化你的應用程式。參考 附錄資源 獲取更多信息。 現在僅僅輸入整數,比如 10。

請註意,表單自動使用紅色邊框突出顯示包含無效的數據的文本框,併在每一個旁邊提示適當的驗證錯誤消息。錯誤包括客戶端(使用 JavaScript 和 jQuery )和伺服器端(以防用戶已禁用 JavaScript)。

一個顯而易見的好處是,你並不需要改變 MoviesController 類或者 Create.cshtml 視圖中的一行代碼,就可以實現驗證界面。你在本教程前面創建的控制器和視圖,自動使用你指定的 Movie 模型類的屬性上的驗證屬性的驗證規則。使用 Edit Action 方法測試驗證,(與Create 方法)同樣的驗證生效。

表單數據不會被髮送到伺服器直到沒有客戶端驗證錯誤。你可以通過在 HTTP Post 方法中設置一個斷點來驗證這一點,通過使用 Fiddler 工具或者 F12 開發者工具

創建視圖和創建方法中如何觸發驗證

也許你會好奇生成的控制器或視圖中的代碼沒有任何更新的情況下驗證界面是如何產生的。下一個清單顯示的是兩個 Create 方法。

// GET: Movies/Create
public IActionResult Create()
{
    return View();
}

// POST: Movies/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,Genre,Price,ReleaseDate,Title,Rating")] Movie movie)
{
    if (ModelState.IsValid)
    {
        _context.Add(movie);
        await _context.SaveChangesAsync();
        return RedirectToAction("Index");
    }
    return View(movie);
}

第一個(HTTP GET) Create 的操作方法顯示初始創建表單。第二個([HttpPost])版本的操作方法負責處理 post 請求。第二個 Create 的方法(HttpPost 版本)調用 ModelState.IsValid 檢查是否有任何驗證錯誤。調用該方法將檢查任何已應用到對象屬性上的驗證。如果對象的 Create 方法驗證錯誤,重新顯示表單。如果沒有錯誤,該方法在資料庫中保存新的 movie。在我們的 movie 例子中,在客戶端驗證檢測到的錯誤的時候,表單將不會發送到伺服器,第二個 Create 方法不會被調用。如果你在你的瀏覽器禁用了JavaScript,客戶端驗證被禁用,HTTP POST 版本的 Create 方法調用 ModelState.IsValid,以檢查是否存在任何驗證錯誤。

你可以在 [HttpPost] Create 方法中設置一個斷點,用來驗證該方法不會被調用,客戶端驗證發現錯誤時將不提交表單數據。如果你在你的瀏覽器禁用了 JavaScript ,然後提交有錯誤的表單,斷點會命中。不支持 JavaScript 的情況下,你仍然可以得到充分驗證。下麵的圖片展示瞭如何在 IE 瀏覽器中禁用 JavaScript 腳本。

validation/_static/p8_IE9_disableJavaScript.png

下麵的圖片展示瞭如何在 FireFox 瀏覽器中禁用 JavaScript 腳本。

validation/_static/ff.png

下麵的圖片展示瞭如何在 Chrome 瀏覽器中禁用 JavaScript 腳本。

validation/_static/chrome.png

在禁用 JavaScript 腳本之後,post 非法數據併在調試器中單步調試。

validation/_static/ms.png

下麵是你在本教程前面用基架生成的 Create.cshtml 視圖模板的一部分。它被上面兩種顯示的兩種 action 方法用來顯示初始化表單並且在錯誤事件中重新顯示。

<form asp-action="Create">
    <div class="form-horizontal">
        <h4>Movie</h4>
        <hr />
        <div asp-validation-summary="ModelOnly" class="text-danger"></div>
        <div class="form-group">
            <label asp-for="Genre" class="col-md-2 control-label"></label>
            <div class="col-md-10">
                <input asp-for="Genre" class="form-control" /> <!--手工高亮-->
                <span asp-validation-for="Genre" class="text-danger" /> <!--手工高亮-->
            </div>
        </div>
        @*Markup removed for brevity.*@ <!--手工高亮-->
        <div class="form-group">
            <label asp-for="Rating" class="col-md-2 control-label"></label>
            <div class="col-md-10">
                <input asp-for="Rating" class="form-control" /> <!--手工高亮-->
                <span asp-validation-for="Rating" class="text-danger" /> <!--手工高亮-->
            </div>
        </div>
        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Create" class="btn btn-default" />
            </div>
        </div>
    </div>
</form>

Input Tag Helper 消費 DataAnnotations 屬性和產生jQuery驗證所需要在客戶端生成的HTML屬性。Validation Tag Helper 負責顯示錯誤信息。更多請參考:Validation

非常棒的是,控制器和 Create 視圖模板不知道實際執行的驗證規則或顯示的具體錯誤消息。只需要在 Movie 類里指定驗證規則和錯誤字元串,同樣的驗證規則會自動應用到 Edit 視圖和任何其他視圖模板,你可以創建、編輯您的模型。

如果你想更改驗證邏輯,你可以限定在一處地方(在本例中,是指 Movie 類),為模型添加驗證屬性。你不需要擔心應用程式的不同部分執行的規則不一致, 在應用在各個處的所有的驗證邏輯將被定義在一個地方。這樣可以使得代碼很乾凈,而且易於維護和改進。這意味著,你會充分遵循了 DRY 原則。

使用 DataType 屬性

打開 Movie.cs 文件,並查看 Movie 類。System.ComponentModel.DataAnnotations 命名空間提供了除了內置的驗證屬性以外的一套格式化屬性。我們已經應用了 DataType 枚舉值的到發佈日期和價格欄位。下麵的代碼顯示了 ReleaseDatePrice 欄位如何使用 DataType 屬性。

[Display(Name = "Release Date")]
[DataType(DataType.Date)] //手工高亮
public DateTime ReleaseDate { get; set; }

[Range(1, 100)]
[DataType(DataType.Currency)] //手工高亮
public decimal Price { get; set; }

DataType 屬性只用於視圖引擎對數據進行格式化(或者提供給諸如 <A> 標簽 的Url或者 <a href="mailto:EmailAddress.com"> 提供的電子郵件),你可以使用 RegularExpression 屬性來驗證數據的格式,DataType 屬性用於指定比資料庫的自帶類型更為具體的數據類型,它們不驗證屬性,在本示例中我們只想跟蹤日期,而不需要具體時間。在 DataType 枚舉提供了許多數據類型,如日期、時間、手機號碼、貨幣、電子郵件地址等。DataType 屬性一樣可以讓應用程式具備自動提供特定數據類型的功能。例如,一個 mailto: 鏈接可以使用 DataType.EmailAddress 數據類型創建,在支持 Html5 的瀏覽器中並且日期選擇器可以提供 DataType.Date 的值。DataType 屬性迴向瀏覽器發送 HTML 5 標簽 data- (pronounced data dash)。DataType 屬性 無法 提供任何驗證提供任何驗證。

DataType.Date 不指定日期的顯示格式。預設情況下,數據欄位的預設的顯示格式基於伺服器的 CultureInfo 設置來決定的。

DisplayFormat 屬性被用來格式化日期:

[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime ReleaseDate { get; set; }

ApplyFormatInEditMode 用來指定格式是否應用到文本框編輯。(你可能不希望在某些欄位中使用這個功能——例如,對於貨幣值,您可能不希望在文本框中對貨幣符號進行編輯。)

你可以直接使用 DisplayFormat 屬性本身,但是更好的方式是建議使用 DataTypeDataType 屬性僅僅傳遞數據的語義,並不會通知瀏覽器如何呈現,如果不使用 DisplayFormat 有以下好處:

  • 瀏覽器可以啟用 HTML5 特性(例如顯示日曆控制項,設置本地化的貨幣符號,電子郵件中的鏈接,等等)。
  • 預設情況下,瀏覽器將基於你的 本地環境 使用正確的格式渲染數據。
  • DataType 屬性可以使 MVC 選擇正確的欄位模板來呈現數據(比如 DisplayFormat 如果單獨使用使用string模板)。更多信息,請參考 Brad Wilson 的 `ASP.NET MVC 2 模版。 (儘管是為 MVC 2編寫的, 文章依然適用於當前的 ASP.NET MVC 版本。)

註意
jQuery驗證當 Range 屬性和 DateTime 屬性同時使用的時候無法生效。例如,下麵的代碼將始終顯示客戶端驗證錯誤,即使日期在指定範圍內:

[Range(typeof(DateTime), "1/1/1966", "1/1/2020")]

你需要禁用jQuery數據驗證日期驗證在 Range 屬性中使用 DateTime。在編譯你的模型的具體日期的時候這通常不是一個好的做法,所以不建議在 Range 屬性中使用 DateTime

下麵的代碼展示瞭如何將各種驗證屬性合併在一行顯示:

public class Movie
{
    public int ID { get; set; }

    [StringLength(60, MinimumLength = 3)] //手工高亮
    public string Title { get; set; }

    [Display(Name = "Release Date"), DataType(DataType.Date)] //手工高亮
    public DateTime ReleaseDate { get; set; }

    [RegularExpression(@"^[A-Z]+[a-zA-Z''-'\s]*$"), Required, StringLength(30)] //手工高亮
    public string Genre { get; set; }

    [Range(1, 100), DataType(DataType.Currency)] //手工高亮
    public decimal Price { get; set; }

    [RegularExpression(@"^[A-Z]+[a-zA-Z''-'\s]*$"), StringLength(5)] //手工高亮
    public string Rating { get; set; }
}

在下一個系列裡面, 我們會重新審視應用程式,為自動生成的 Details 以及 Delete 方法做一些提升。

附錄資源

返回目錄


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一、Linux用戶管理 : 不同的用戶的文件都是放在同一個物理磁碟上的甚至同一個邏輯分區或者目錄里,但是由於Linux的用戶管理和許可權機制,不同用戶不能輕易查看、修改彼此的文件。 1. 查看用戶 : 只顯示用戶: pts表示偽終端,偽是相對於/dev/tty而言的,當使用/dev/tty7時每打開一 ...
  • linux系統中通過write命令給線上的其他用戶發送消息。 ...
  • 1.上傳zookeeper-3.4.6.tar.gz安裝包 2.解壓tar -xzf zookeeper-3.4.6.tar.gz 3.配置(先在一臺節點上配置) 3.1添加一個zoo.cfg配置文件 $ZOOKEEPER/conf mv zoo_sample.cfg zoo.cfg 3.2修改配置 ...
  • <html> <head> <meta name="viewport" content="width=device-width" /> <title>創建二維碼</title> <script src="~/Content/uploadify/jquery-2.1.1.min.js"></scrip ...
  • Winform中Treeview控制項失去焦點,將選擇的節點設置為高亮顯示 (2012-07-16 13:47:07)轉載▼標簽: winform treeview drawnode Treeview控制項--Name:tVtypeList將tVtypeList的HideSelection屬性設置為Fa ...
  • 前言 繼之前發的帖子【ORM-Dapper+DapperExtensions】,對Dapper的擴展代碼也進行了改進,同時加入Dapper 對Lambda表達式的支持。 由於之前缺乏對Lambda的知識,還是使用了拿來主義。研究了些案例,總歸有些問題: 1、只能生成sql、不能將值進行參數化。 2、 ...
  • 天創恆達UB530高清視頻採集卡USB游戲PS4視頻翻錄電影網路直播錄播會議HDMI採集盒 http://item.jd.com/1567495458.html 天創恆達UB5A0 USB採集卡HDMI 分量 網路會議ps4游戲視頻高清採集盒1080p http://item.jd.com/1542 ...
  • 我們在前面章節中講了寄宿,在前面的實例中也用到了配置文件,這一篇主要講講如何在應用配置文件,提高WCF程式的靈活性。在編寫WCF服務應用程式時,編寫配置項也是其中一項主要工作,在前面的幾個示例中我也使用過配置文件,通過配置文件來簡化代碼。WCF通過公開終結點,向客戶端公開服務,包括服務的地址、服務用... ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...