天天看點

學習ASP.NET Core Razor 程式設計系列十二——在頁面中增加校驗

原文: 學習ASP.NET Core Razor 程式設計系列十二——在頁面中增加校驗 學習ASP.NET Core Razor 程式設計系列目錄 學習ASP.NET Core Razor 程式設計系列一 學習ASP.NET Core Razor 程式設計系列二——添加一個實體 學習ASP.NET Core Razor 程式設計系列三——建立資料表及建立項目基本頁面 學習ASP.NET Core Razor 程式設計系列四——Asp.Net Core Razor清單模闆頁面 學習ASP.NET Core Razor 程式設計系列五——Asp.Net Core Razor建立模闆頁面 學習ASP.NET Core Razor 程式設計系列六——資料庫初始化 學習ASP.NET Core Razor 程式設計系列七——修改清單頁面 學習ASP.NET Core Razor 程式設計系列八——并發處理 學習ASP.NET Core Razor 程式設計系列九——增加查詢功能 學習ASP.NET Core Razor 程式設計系列十——添加新字段 學習ASP.NET Core Razor 程式設計系列十一——把新字段更新到資料庫

        本篇文章我們學習如何給 Book實體類添加校驗規則。當使用者進行建立或編輯書籍資訊時,都會觸發校驗規則。

一、校驗

       軟體開發中有一個主要原則被稱為 DRY(即“不要自我重複”)。 Razor 頁面鼓勵進行隻需要開發一次,這個功能就能在整個應用中使用,不需要重複開發,或複制粘貼。 DRY 有助于減少應用中的代碼量。 DRY 使代碼更加不易出錯,且更易于測試和維護。

       Razor 頁面和 Entity Framework架構提供的校驗是支援DRY 原則的極佳示例。 校驗規則在實體類中的某處以聲明方式指定,且在應用程式的所有位置強制執行。

二、在書籍實體類中添加校驗規則

       在Visual Studio 2017的解決方案資料總管中,打開 Models\Book.cs 檔案。 DataAnnotations 提供一組内置的校驗規則特性,我們可以通過聲明的方式應用于類或屬性之上。 DataAnnotations 還包含 DataType 等格式特性,有助于格式設定但不提供驗證。

        現在我們來給Book 類使用 Required、StringLength、RegularExpression 和 Range 校驗規則特性,代碼如下所示。

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks; 

namespace RazorMvcBooks.Models
{

    public class Book
    {  

        public int ID { get; set; }
  [Required]
        [StringLength(50, MinimumLength = 2)]
        public string Name { get; set; }
        [Display(Name = "出版日期")]
        [DataType(DataType.Date)] 

        public DateTime ReleaseDate { get; set; }
        [Range(1,200)]
        [DataType(DataType.Currency)]
        public decimal Price { get; set; }
        [RegularExpression(@"^[A-Z]+[a-zA-Z""'\s-]*$"), Required, StringLength(30)]

        public string Author { get; set; }
        [Required]
        public string Publishing { get; set; }

    }
}      

       校驗特性用在實體類的屬性上,并且将前端強制執行。

       Required 和 MinimumLength 特性表示屬性必須具有一個值。 但是,使用者可以随時輸入空格對可以為 null 的類型進行校驗限制。 從本質上來說,對于不能為 null 的值類型(如 decimal、int、float 和 DateTime),可以不添加 Required 特性。

        RegularExpression 特性限制使用者可以輸入的字元。 在上述代碼中, Rating 隻能輸入字母(禁用空格、數字和特殊字元)。

        Range 特性将值限制在指定範圍内。

        StringLength 特性設定字元串的最大長度,且可視情況設定最小長度。

       讓 ASP.NET Core 強制自動執行校驗規則有助于提升應用程式的可靠性。 在實體類上進行自動校驗助于保護應用程式,因為添加新代碼時無需手動修改舊代碼。

三、檢視面中的校驗資訊

        在Visual Studio 2017中按F5運作應用程式,并在浏覽器中浏覽到書籍清單頁面。

        在書籍清單頁面,使用滑鼠左鍵點選“Create”連結。在建立頁面中的輸入框中輸入一些無效值。當jQuery用戶端校驗檢測到錯誤時,它會顯示一條錯誤消息。 如下圖。

學習ASP.NET Core Razor 程式設計系列十二——在頁面中增加校驗

備注

       你可能無法在 Price 字段中輸入小數點或逗号。 若要使 jQuery 校驗支援非英英語環境中使用逗号(“,”)表替小數點,以及使用非美式英語日期格式,你必須采取應用全球化設定來改變你的應用程式。

         請注意,表單在包含無效值的每個字段下自動呈現一個适當的校驗錯誤消息。錯誤包括用戶端(使用 JavaScript 和 jQuery )和伺服器端(當使用者禁用JavaScript時)。

         一項重要好處是,無需在“建立”或“編輯”頁面中更改代碼。 一量在在實體類上應用 DataAnnotations 後,即已啟用校驗UI。 本教程中自動建立的 Razor 頁面自動選取了校驗規則(使用Book類的屬性上的校驗特性)。 使用“編輯”頁面測試驗證後,所有應用這個Book類的頁面都應用了相同校驗規則。

        存在用戶端驗證錯誤時,不會将表單資料送出到背景伺服器。 你可以使用以下一種或多種方法驗證是否未釋出表單資料:

        1) 在 OnPostAsync 方法中放置一個斷點。 送出表單(選擇“Create”或“Save”)。 從未命中斷點。

        2) 使用 Fiddler 工具。

        3)  使用浏覽器開發人員工具監視網絡流量。

四、伺服器端驗證

        首先我們在浏覽器中禁用 JavaScript,即不進行用戶端校驗,然後把有錯誤的資料送出到背景伺服器。

       測試伺服器端驗證:

        1. 在浏覽器中禁用 JavaScript。 如果你的浏覽器中無法禁用 JavaScript,請試試其他浏覽器。

        2. 在“建立”或“編輯”頁面的 OnPostAsync 方法中設定斷點。

        3. 送出帶有不符全校驗規則的表單資料。

        4. 檢視一下OnPostAsync方法中是否有以下代碼。

if (!ModelState.IsValid)
     {
        return Page();
     }      

        5. 結果如下圖。

學習ASP.NET Core Razor 程式設計系列十二——在頁面中增加校驗

        以下代碼顯示了之前在本教程中設定其基架的“Create.cshtml”的一部分。 它用于在“建立”和“編輯”頁面中顯示初始表單并在發生錯誤後重新顯示表單。

<form method="post">
            <div asp-validation-summary="ModelOnly" class="text-danger"></div>
            <div class="form-group">
                <label asp-for="Book.Name" class="control-label"></label>
                <input asp-for="Book.Name" class="form-control" />
                <span asp-validation-for="Book.Name" class="text-danger"></span>
            </div>      

        輸入輔助助手使用 DataAnnotations 特性并在用戶端生成 jQuery 校驗所需的 HTML 元素。 校驗輔助助手用于顯示校驗錯誤。

        “建立”和“編輯”頁面中沒有校驗規則。 校驗規則和錯誤字元串僅可在BOOK 類中指定。 這些校驗規則将自動應用于編輯頁面。

        當需要修改校驗邏輯時,也隻能在該Book實體類中修改。 校驗将始終在整個應用程式中應用(校驗邏輯在一處定義)。 在一個地方進行校驗有助于保持代碼幹淨,且更易于維護和更新。

五、使用DataType特性

         現在我們在Visual Studio 2017中修改Book類。 DataAnnotations除了提供一組内置的驗證特性,System.ComponentModel.DataAnnotations 命名空間還提供格式特性。 我們來看一下DataType 特性應用于 ReleaseDate 和 Price 屬性。代碼如下。

[Display(Name = "出版日期")]
        [DataType(DataType.Date)] 

        public DateTime ReleaseDate { get; set; }
        [Range(1,200)]

        [DataType(DataType.Currency)]
        public decimal Price { get; set; }      

        DataType 特性僅提供相關提示來幫助視圖引擎設定資料格式(例如向 URL 提供 <a> 和向電子郵件提供 <a href="mailto:[email protected]">)。 使用 正規表達式(RegularExpression)特性校驗資料的格式。 DataType 特性用于指定比資料庫内部類型更具體的資料類型。 DataType 特性不是校驗特性。 示例應用程式中“出版日期”僅顯示日期,不顯示時間。

        DtaType 枚舉提供了多種資料類型,例如日期、時間、電話号碼、貨币、電子郵件位址等。 DataType特性的使用能夠使應用程式自動提供特定資料類型的功能。 例如,可為 DataType.EmailAddress 建立 mailto: 連結。 如果浏覽器支援 HTML5 ,DataType.Date類型浏覽器将提供日期選擇器,如下圖。

學習ASP.NET Core Razor 程式設計系列十二——在頁面中增加校驗

      DataType 特性發出 HTML 5 特性供 支援HTML 5 浏覽器使用。 DataType 特性不提供任何校驗。

      DataType.Date 不指定顯示日期的格式。 預設情況下,日期資料格式基于伺服器的 CultureInfo 的預設格式進行顯示。

        DisplayFormat 特性用于顯式指定日期格式:例如   

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

         ApplyFormatInEditMode 設定用于指定在顯示值進行編輯時需要顯示的格式。 在某些場景中,您可能不希望某些字段具有此行為。 例如,在貨币值中,可能不希望編輯 UI 中使用貨币符号。

          可單獨使用 DisplayFormat 特性,但通常建議使用 DataType 特性。 DataType 特性傳遞資料的語義而不是傳遞如何在前端界面上呈現資料,DataType具體 DisplayFormat 不具備的以下優勢:

  • 浏覽器如果支援HTML5,則會自動顯示相應的一些控件與功能(例如顯示日期控件、區域設定适用的貨币符号、電子郵件連結等)。
  • 預設情況下,浏覽器将根據您在區域設定中設定的區域采用正确的格式呈現資料。
  • DataType特性可以使ASP.NET Core架構可選擇适當的字段模闆來呈現資料。如果單獨使用時,可以使用DisplayFormat 特性的顯式的指定資料格式。

          注:jQuery校驗不能校驗日期範圍與日期時間。例如,在Book類中添加下面的代碼,在浏覽器中輸入任何日期,都是顯示校驗錯誤,即使選擇的日期是在指定的範圍之内,如下圖:

[Display(Name = "出版日期")]
        [Range(typeof(DateTime), "1980/1/1", "2050/1/1")]
        public DateTime ReleaseDate { get; set; }      
學習ASP.NET Core Razor 程式設計系列十二——在頁面中增加校驗

         通常,在實體類中設定固定日期是不合适的,是以不推薦使用 Range 特性和 DateTime特性。

繼續閱讀