iT邦幫忙

2021 iThome 鐵人賽

DAY 6
0
自我挑戰組

ASP.NET Core & Blazor系列 第 6

Day 06 抽離C#程式碼

  • 分享至 

  • xImage
  •  

昨天看到FetchData.razor的程式太長了,截圖都要兩次,為求方便,我們把@code的部分擷取出來另成一個檔案。

Blazor提供了兩個方法:partial classComponentBase,同樣兩者各有優缺點,筆者偏好ComponentBase,端看個人使用習慣。

先來看partial class,我們打開FetchData.razor,把前面提到的@using BlazorServer.Data移到_Imports.razor,再建立一個class叫做FetchData.razor.cs,在publicclass中間加上partial修飾詞,接著把FetchData.razor的@code區塊剪下貼到FetchData.razor.cs後稍作修改,可以看出跟舊的C#程式沒什麼差別。我們按下F5,一樣看到10筆天氣資料。
https://ithelp.ithome.com.tw/upload/images/20210906/20140893EsdlPOlaqT.png
https://ithelp.ithome.com.tw/upload/images/20210906/201408936GuVa31ssx.png
https://ithelp.ithome.com.tw/upload/images/20210906/201408939r92PSfFzf.png

接著來看ComponentBase,先把partial class裡面的程式複製下來,接著建立一個新class取名為FetchDataBase.cs,將剛剛的程式貼上後稍做修改,再刪除FetchData.razor.cs這個partial class,因為兩種模式不能並存。可以看到除了繼承ComponentBase跟加上[Inject]外,幾乎沒有差別,這裡的[Inject]相當於在FetchData.razor.cs使用@inject WeatherForecastService ForecastService,我們按下F5啟動偵錯模式,在20行左邊按一下設定中斷點,可以看到一樣取得了天氣資料。
https://ithelp.ithome.com.tw/upload/images/20210906/201408932rrbHtxNQP.png
https://ithelp.ithome.com.tw/upload/images/20210906/20140893gzBNseVh8v.png

接著開始做自己的Component吧!先將不必要的Component刪除,Startup.cs_Import.razor裡面跟天氣有關的using及註冊同樣刪除,如果忘記這兩個檔案在哪裡,可以在刪除Component後將滑鼠移到專案BlazorServer點右鍵,選取重建專案,Visual Studio就會告訴你哪裡出錯了。
https://ithelp.ithome.com.tw/upload/images/20210906/20140893q5ZQ401wSW.png

之前說過要完成讓使用者寫日誌的網站,所以需要最基本的輸入框,而日誌的單位就以一篇計算。首先建立Models資料夾,建立PostModel類別,裡面很簡單只有3個屬性,接著在Pages資料夾建立Post.razorPostBase.razor.cs,最後將NavMenu.razor的連結留下一個,href屬性的值改為Post
https://ithelp.ithome.com.tw/upload/images/20210906/20140893jDwwQxJynJ.png

PostModel是用來承接資料的容器,目前沒有Service,所以在PostBase.razor.cs放一筆假資料,這邊可以看到一個方法OnInitializedAsync(),代表當這個Component生命週期伊始,裡面的事情就會先做,其他還有OnAfterRenderAsyncOnParametersSetAsync等等,只要先輸入override再按一下空白鍵,就可以看到這些方法,且也有同步跟非同步兩種模式,這些方法有機會再說明。
https://ithelp.ithome.com.tw/upload/images/20210906/20140893HbFSeYANaz.png
https://ithelp.ithome.com.tw/upload/images/20210906/20140893FwTKkUVHBb.png

Post.razor用了EditForm這個Component,編譯過後相當於html的form元素,裡面還有3個input元素,Blazor也有提供相對應的Input Component,可以從官方文件看到分別編譯後的html元素。
https://ithelp.ithome.com.tw/upload/images/20210906/20140893xJTQ4iPLP4.png
https://ithelp.ithome.com.tw/upload/images/20210906/20140893ORHFU4dgH1.png
https://ithelp.ithome.com.tw/upload/images/20210906/20140893dDQipT6IWx.png

這時候打開網頁來看,可以看到上面出現了我們定義在PostBase.razor.cs的值,但這是怎麼連結起來的呢?原因就是EditForm的Model屬性及3個<Input> Component的屬性@bind-Value,這裡在告訴Blazor:我的Model跟裡面的值要跟這個EditForm綁在一起,如果這裡有跟後端程式連結,網頁上輸入的內容經過事件觸發後,就會送到後端處理。
https://ithelp.ithome.com.tw/upload/images/20210906/201408935Ubl5EphCa.png

不過<Input>預設的CSS樣式不太好看,我們先套用基本的boostrap樣式;因為Id通常不會讓使用者輸入,所以這邊先註解,然後再加入表格驗證機制,畢竟不能讓使用者隨便輸入就送出表格,但如果不想自己寫一堆驗證機制呢?可以試試看Blazor的DataAnnotationsValidatorValidationSummary兩個Component。
https://ithelp.ithome.com.tw/upload/images/20210906/20140893tHRrhMffCJ.png
https://ithelp.ithome.com.tw/upload/images/20210906/20140893zzYfGSum4o.png

我們先在PostModelTitleContent加上兩個AttributeRequired代表必填,MaxLengthMinLength則是限制最大及最小字數,還可以自訂錯誤訊息。接著在EditForm裡面加上那兩個Component DataAnnotationsValidatorValidationSummary,第一個是驗證個別Input,第二個則是將錯誤訊息顯示在表格上方。
https://ithelp.ithome.com.tw/upload/images/20210906/20140893kIgO8Oe0tc.png
https://ithelp.ithome.com.tw/upload/images/20210906/20140893r2usnA9Gl7.png
https://ithelp.ithome.com.tw/upload/images/20210906/20140893KBSOVLJXw5.png

但如果不喜歡驗證機制預設的CSS樣式呢?Blazor也提供客製化的方法。先建立一個class名為CustomFieldClassProvider且繼承FieldCssClassProvider,覆寫方法GetFieldCssClass,裡面的內容待會再說。
https://ithelp.ithome.com.tw/upload/images/20210906/20140893ev1K5n3h9c.png

接著在PostBase.razor.cs加入一個類別為EditContext的屬性editContext,初始化產生物件editContext,將原本的Post物件丟進去建構子,然後呼叫editContext的方法SetFieldCssClassProvider,在建構子產生新CustomFieldClassProvider 物件。
https://ithelp.ithome.com.tw/upload/images/20210906/20140893Rz6fcsbio9.png

最後最重要的一步,在Post.razorEditForm的Model參數移除,改為EditContext參數,裡面的值就是剛剛的editContext 物件。
https://ithelp.ithome.com.tw/upload/images/20210906/20140893eVu7xbjko1.png

這時候再送出表格一次,可以看到textarea的紅色外框消失了,字體也變成text-danger的紅色,而正確的欄位則是變成text-primary的藍色。我們再回頭看CustomFieldClassProvider,原來editContext指的就是EditForm的內容,fieldIdentifier則是個別Input,如果editContext呼叫的方法GetValidationMessages有在fieldIdentifier取得任何訊息,代表這是錯誤的欄位,沒有則是正確欄位,這就是Blazor幫我們客製化Form的作法。
https://ithelp.ithome.com.tw/upload/images/20210906/20140893MPQlMPzxNB.png

Ref: Split HTML And C# Code In Blazor Using Either Partial Class Or ComponentBase Class
https://www.learmoreseekmore.com/2020/06/blazor-paratial-class-or-componentbase-class.html

Ref: ASP.NET Core Blazor forms and validation
https://docs.microsoft.com/en-us/aspnet/core/blazor/forms-validation?view=aspnetcore-5.0#binding-a-form

Ref: Custom validation CSS class attributes
https://docs.microsoft.com/en-us/aspnet/core/blazor/forms-validation?view=aspnetcore-5.0#custom-validation-css-class-attributes-1


上一篇
Day 05 依賴注入(Dependency Injection)
下一篇
Day 07 生命週期(Lifetime)
系列文
ASP.NET Core & Blazor30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言