.NET 8 Blazor入門 - 4
作者:許薰尹 精誠資訊/恆逸教育訓練中心資深講師
本篇文章將延續本站《.NET 8 Blazor入門 - 1》、《.NET 8 Blazor入門 - 2》、《.NET 8 Blazor入門 - 3》系列文章的情境,介紹如何使用Visual Studio 2022開發工具,一步、步帶領你建立一個.NET 8 Blazor的員工系統,使用SPA架構來進行資料的新增、刪除、修改與查詢作業。
回顧我們在此系列文章建立的Blazor Web App專案,目前可以利用「EditEmployee.razor」元件新增員工資料,若使用者亂輸資料,我們就會取得無意義的資料,此外若使用者沒有填員工類型(JobTypeId)便進行新增作業,將得到一個例外錯誤,請參考下圖所示:
圖 1:未提供資料產生例外錯誤。
為了避免未提供員工類型(JobTypeId)資料產生例外錯誤這個問題,我們應該適當地加入表單資料驗證的功能,來擋掉有問題的資料。
使用DataAnnotations進行驗證
ASP.NET Core Web應用程式,不管採用MVC框架、Razor Page或Blazor,都可以使用「System.ComponentModel.DataAnnotations」命名空間下的類別來進行資料驗證。
修改「EmployeeDetails.cs」檔案,加上以下程式碼:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | using System.ComponentModel.DataAnnotations; namespace HRApp.Models { public class EmployeeDetails { public int Id { get ; set ; } [Required] [StringLength( 50 )] public required string EmployeeName { get ; set ; } public DateOnly BirthDay { get ; set ; } public bool IsMarried { get ; set ; } [Required] public string ? JobTypeId { get ; set ; } } } |
一開始先引用了「System.ComponentModel.DataAnnotations」命名空間;[Required]:這個Attribute表示「EmployeeName」與「JobTypeId」是必填的;[StringLength(50)]限制「EmployeeName」的最大長度為 50 個字。
修改「EditEmployee.razor」元件程式碼,將「EditForm」元件的「OnSubmit」屬性改為「OnValidSubmit」屬性,使用「OnValidSubmit」屬性可以確保只有在表單資料通過驗證時才會提交,這樣可以提高資料的完整性和可靠性。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | @page "/editemployee" @ using HRApp.Services @ using Models @inject NavigationManager NavigationManager @inject EmployeesService EmployeesService @inject JobTypeService JobTypeService <PageTitle> New Employee </PageTitle> <h3> New Employee </h3> @ if ( jobTypes is null ) { <p> <em> Loading... </em> </p> } else { <div class = "row" > <div class = "col-md-8 col-lg-12" > <EditForm Model = "@employee" FormName = "editEmployee" OnValidSubmit = "HandleSubmit" > <DataAnnotationsValidator /> <div class = "mb-3" > <label for = "employeeName" class = "form-label" > Employee Name : </label> <InputText id = "employeeName" @bind-Value = "employee.EmployeeName" class = "form-control" /> </div> <div class = "mb-3" > <label for = "birthDay" class = "form-label" > Birth Day : </label> <InputDate id = "birthDay" @bind-Value = "employee.BirthDay" class = "form-control" /> </div> <div class = "mb-3" > <label for = "isMarried" class = "form-label" > Is Married : </label> <InputCheckbox id = "isMarried" @bind-Value = "employee.IsMarried" class = "form-check-input" /> </div> <div class = "mb-3" > <label for = "jobType" class = "form-label" > Job Type : </label> <InputSelect id = "jobType" @bind-Value = "employee.JobTypeId" class = "form-select" > <option value = "" > Select Job Type </option> @ foreach ( var jobType in jobTypes! ) { <option value = "@jobType.Id" > @jobType.Type </option> } </InputSelect> </div> <button type = "submit" class = "btn btn-primary" > Submit </button> <a class = "btn btn-secondary" href = "/" > Cancel </a> </EditForm> </div> </div> } @code { [SupplyParameterFromForm] private EmployeeDetails employee { get ; set ; } = new EmployeeDetails( ) { EmployeeName = string .Empty , BirthDay = new DateOnly( 2000 , 1 , 1 ) }; private JobType[]? jobTypes; protected override void OnInitialized( ) { jobTypes = JobTypeService.GetJobTypes( ); } private void HandleSubmit( ) { EmployeesService.AddEmployee( employee ); NavigationManager.NavigateTo( "/" ); } } |
然後在「EditForm」元件中放一個「DataAnnotationsValidator」元件,當使用者提交表單時,「DataAnnotationsValidator」元件會自動檢查資料是否符合需求。同時設定「InputSelect」元件預設選項的值是空白。
現在測試「EditEmployee.razor」元件資料新增功能,若「EmployeeName」、「JobTypeId」資料有問題,文字方塊與下拉清單方塊會使用紅色的框線來提示錯誤,請參考下圖所示:
圖 2:資料驗證錯誤。
使用ValidationMessage元件
「ValidationMessage」是內建的元件,可以顯示特定屬性的驗證錯誤訊息,它的「For」屬性指定要顯示驗證錯誤訊息的屬性。修改「EditEmployee.razor」元件程式如下,在「EmployeeName」、「BirthDay」、「IsMarried」和「JobTypeId」屬性加上「ValidationMessage」元件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | @page "/editemployee" @ using HRApp.Services @ using Models @inject NavigationManager NavigationManager @inject EmployeesService EmployeesService @inject JobTypeService JobTypeService <PageTitle> New Employee </PageTitle> <h3> New Employee </h3> @ if ( jobTypes is null ) { <p> <em> Loading... </em> </p> } else { <div class = "row" > <div class = "col-md-8 col-lg-12" > <EditForm Model = "@employee" FormName = "editEmployee" OnValidSubmit = "HandleSubmit" > <DataAnnotationsValidator /> <div class = "mb-3" > <label for = "employeeName" class = "form-label" > Employee Name : </label> <InputText id = "employeeName" @bind-Value = "employee.EmployeeName" class = "form-control" /> <ValidationMessage For = "@(() => employee.EmployeeName)" /> </div> <div class = "mb-3" > <label for = "birthDay" class = "form-label" > Birth Day : </label> <InputDate id = "birthDay" @bind-Value = "employee.BirthDay" class = "form-control" /> <ValidationMessage For = "@(() => employee.BirthDay)" /> </div> <div class = "mb-3" > <label for = "isMarried" class = "form-label" > Is Married : </label> <InputCheckbox id = "isMarried" @bind-Value = "employee.IsMarried" class = "form-check-input" /> <ValidationMessage For = "@(() => employee.IsMarried)" /> </div> <div class = "mb-3" > <label for = "jobType" class = "form-label" > Job Type : </label> <InputSelect id = "jobType" @bind-Value = "employee.JobTypeId" class = "form-select" > <option value = "" > Select Job Type </option> @ foreach ( var jobType in jobTypes! ) { <option value = "@jobType.Id" > @jobType.Type </option> } </InputSelect> <ValidationMessage For = "@(() => employee.JobTypeId)" /> </div> <button type = "submit" class = "btn btn-primary" > Submit </button> <a class = "btn btn-secondary" href = "/" > Cancel </a> </EditForm> </div> </div> } @code { [SupplyParameterFromForm] private EmployeeDetails employee { get ; set ; } = new EmployeeDetails( ) { EmployeeName = string .Empty , BirthDay = new DateOnly( 2000 , 1 , 1 ) }; private JobType[]? jobTypes; protected override void OnInitialized( ) { jobTypes = JobTypeService.GetJobTypes( ); } private void HandleSubmit( ) { EmployeesService.AddEmployee( employee ); NavigationManager.NavigateTo( "/" ); } } |
這樣當資料輸入有誤時,輸入方塊的下方就會顯示錯誤訊息,請參考下圖所示:
圖 3:顯示個別屬性的錯誤訊息。
使用ValidationSummary元件
「ValidationSummary」元件也是一個 Blazor 內建的元件,用於顯示表單中所有驗證錯誤的摘要。它會使用清單的方式列出所有未通過驗證的屬性及其錯誤訊息。修改「EditEmployee.razor」程式碼,在「EditForm」元件之中加入「ValidationSummary」元件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | @page "/editemployee" @ using HRApp.Services @ using Models @inject NavigationManager NavigationManager @inject EmployeesService EmployeesService @inject JobTypeService JobTypeService <PageTitle> New Employee </PageTitle> <h3> New Employee </h3> @ if ( jobTypes is null ) { <p> <em> Loading... </em> </p> } else { <div class = "row" > <div class = "col-md-8 col-lg-12" > <EditForm Model = "@employee" FormName = "editEmployee" OnValidSubmit = "HandleSubmit" > <DataAnnotationsValidator /> <ValidationSummary /> <div class = "mb-3" > <label for = "employeeName" class = "form-label" > Employee Name : </label> <InputText id = "employeeName" @bind-Value = "employee.EmployeeName" class = "form-control" /> <ValidationMessage For = "@(() => employee.EmployeeName)" /> </div> <div class = "mb-3" > <label for = "birthDay" class = "form-label" > Birth Day : </label> <InputDate id = "birthDay" @bind-Value = "employee.BirthDay" class = "form-control" /> <ValidationMessage For = "@(() => employee.BirthDay)" /> </div> <div class = "mb-3" > <label for = "isMarried" class = "form-label" > Is Married : </label> <InputCheckbox id = "isMarried" @bind-Value = "employee.IsMarried" class = "form-check-input" /> <ValidationMessage For = "@(() => employee.IsMarried)" /> </div> <div class = "mb-3" > <label for = "jobType" class = "form-label" > Job Type : </label> <InputSelect id = "jobType" @bind-Value = "employee.JobTypeId" class = "form-select" > <option value = "" > Select Job Type </option> @ foreach ( var jobType in jobTypes! ) { <option value = "@jobType.Id" > @jobType.Type </option> } </InputSelect> <ValidationMessage For = "@(() => employee.JobTypeId)" /> </div> <button type = "submit" class = "btn btn-primary" > Submit </button> <a class = "btn btn-secondary" href = "/" > Cancel </a> </EditForm> </div> </div> } @code { [SupplyParameterFromForm] private EmployeeDetails employee { get ; set ; } = new EmployeeDetails( ) { EmployeeName = string .Empty , BirthDay = new DateOnly( 2000 , 1 , 1 ) }; private JobType[]? jobTypes; protected override void OnInitialized( ) { jobTypes = JobTypeService.GetJobTypes( ); } private void HandleSubmit( ) { EmployeesService.AddEmployee( employee ); NavigationManager.NavigateTo( "/" ); } } |
當使用者在表單中輸入資料並提交時,「DataAnnotationsValidator」元件會檢查「EmployeeDetails」類別中的屬性所套用的驗證Attribute,如果資料不符合這些驗證規則,「ValidationSummary」元件所在位置便會顯示所有的驗證錯誤訊息,請參考下圖所示:
圖 4:「ValidationSummary」元件會顯示所有的驗證錯誤訊息。
切記「ValidationSummary」元件需要放在「EditForm」元件開頭與結尾的標籤之中,否則會有例外錯誤,請參考下圖所示:
圖 5:「ValidationSummary」元件需要放在「EditForm」元件開頭與結尾的標籤之中。
0 意見:
張貼留言