2024年12月10日 星期二

.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」元件開頭與結尾的標籤之中。


  • Currently 5.0/5 Stars.
  • 1
  • 2
  • 3
  • 4


0 意見:

張貼留言