巨集觀上理解blazor中的表單驗證

来源:https://www.cnblogs.com/jionsoft/archive/2023/09/24/17726550.html
-Advertisement-
Play Games

概述 表單驗證的最終效果大家都懂,這裡不闡述了,主要從巨集觀角度說說blazor中表單驗證框架涉及到的類,以及它們是如何協作的,看完這個,再看官方文檔也許能更輕鬆點。 blazor中的驗證框架分為兩部分:基礎驗證框架 和 基於數據註釋Atrrbute的驗證器,當然也提供了很多擴展點。註意我們通常使用數 ...


概述

表單驗證的最終效果大家都懂,這裡不闡述了,主要從巨集觀角度說說blazor中表單驗證框架涉及到的類,以及它們是如何協作的,看完這個,再看官方文檔也許能更輕鬆點。

blazor中的驗證框架分為兩部分:基礎驗證框架 和 基於數據註釋Atrrbute的驗證器,當然也提供了很多擴展點。註意我們通常使用數據註釋Atrrbute的驗證器,但它僅僅是在基礎驗證框架上擴展而來的,並不是核心,我們下麵先分析基礎驗證框架,後續再說基於數據註釋的驗證。

表單驗證是圍繞表單,往往一個表單綁定到一個對象,我這裡稱為編輯模型,表單中的輸入框與這個對象屬性綁定。

我們先把基礎驗證框架看作一個整體,從幾個角度分析:

 

  1. 產生驗證消息,這個不屬於驗證框架的核心部分,驗證框架只需要提供一個方法,當框架外部產生驗證時,調用此方法,讓驗證框架去記錄即可
  2. 存儲驗證消息是驗證框架的核心工作之一,我們可以想象使用一個Dictionary<欄位,List<驗證消息>>來存儲,key對應編輯模型的一個欄位,value是驗證消息集合,一個欄位可能有多個驗證消息。
  3. 我們可以定義兩個組件用於展示驗證消息,一個用於彙總展示,一個用戶展示指定指定的驗證消息,它們從驗證框架獲取驗證信息進行顯示。
  4. 清空驗證消息,驗證框架內部從存儲中清空即可,可以向外暴露個事件,還可以留個方法允許外部主動調用清空驗證消息,最好再允許外部清空指定欄位的驗證消息。
  5.  下麵說明下blazor中表單驗證的關鍵類,以及它們之間的關係。

基礎驗證框架先是定義幾個零散的類,各自負責處理自己的部分,然後通過引用、方法調用把幾個類串聯起來。

欄位標識FieldIdentifier

前面說存儲驗證消息時,類似這麼個類型:Dictionary<欄位,List<驗證消息>>,簡單的情況“欄位”可以用個string類型,但我們是在記憶體中,可以用更直接的方式。

FieldIdentifier = 編輯模型的引用 + 欄位名,它就代表編輯模型的某個欄位。後續我們要操作某個欄位,往往都是用這個參數。

驗證消息存儲器ValidationMessageStore

ValidationMessageStore是用這樣一個欄位Dictionary<FieldIdentifier, List<string>> _messages來存儲驗證消息的。key是欄位,value是此欄位的多個驗證消息。也提供了插入、刪除等驗證消息等方法。

它一般是有我們自己的代碼new出來的,或者有擴展的驗證器,如 基於數據註釋的驗證器new出來的。new它的時候會把editContext對象傳進來,後面會用。

當調用這個對象添加驗證消息時,它會存儲此欄位的驗證消息,並且調用editContext獲取欄位狀態FieldState,將自身的引用傳遞給它,以便FieldState將來反向通過存儲器來查詢驗證狀態。

欄位狀態FieldState

FieldState表示欄位的狀態,所謂的狀態就是 這個欄位是否修改過、以及獲取它關聯的驗證消息(本質上是從ValidationMessageStore獲取,後面會說)。

為啥不跟欄位標識FieldIdentifier合併為一個類呢?
欄位標識只是代表某個欄位,在很多方法參數時都會用到,它比較輕量;而欄位狀態是存儲了欄位是否修改和驗證消息列表的,相對來說比較重,那些方法可能僅僅是想通過欄位標識做查找,並不關心內部的狀態

它包含一個ValidationMessageStore的列表,獲取此欄位的驗證消息時,就是遍歷這個列表獲取的。但FieldState不負責向存儲器添加驗證消息。這個列表如何來的,驗證消息存儲器ValidationMessageStore已經說明瞭。

表單編輯上下文EditContext

可以把EditContext理解為 :欄位狀態FieldState列表 + 編輯模型實例,註意它不引用ValidationMessageStore,之所以這樣設計是想保持EditContext輕量。

那主要關心的就是FieldState列表的crud操作
創建FieldState,則是外部想通過EditContext獲取欄位狀態時,若有就返回,否則創建並記錄下來。
讀取就直接遍歷FieldState咯。
刪除:好像木有,也沒有必要
改:找到欄位狀態,直接改咯。

另外:一個EditForm與一個EditContext關聯,EditForm內部的組件會通過級聯方式獲得editContext的引用

額外的,它還提供欄位變化時、請求驗證時的相關事件。

小結

  1. 保持EditContext輕量,它不引用具體的驗證存儲器,而是只包含 欄位狀態 + 編輯模型實例,通過EditContext遍歷裡面的欄位狀態FieldState,獲取驗證消息,欄位狀態內部是遍歷存儲器列表獲取驗證消息。
  2. 將驗證狀態存儲器抽離出來,哪裡想向編輯上下文添加欄位驗證,就new ValidationMessageStore(editContext);然後Add驗證消息即可。
  3. 便於擴展,比如後面的基於數據註解的驗證器,它就是自己new ValidationMessageStore(editContext),然後使用註解驗證方式向其添加驗證。

驗證消息的展示

展示就比較簡單了,EditForm與EditContext關聯的,它會級聯傳遞到表單的子組件,子組件通過EditContext遍歷欄位就能拿到驗證消息。

ValidationSummary

它是彙總顯示所有驗證消息,它通過級聯參數獲取EditContext引用,遍歷然後顯示驗證消息。

ValidationMessage

原理類似,它顯示指定欄位的驗證消息。

基於數據註釋驗證器擴展

所謂的驗證器,無非是定義一個類,讓它持有EditContext的引用,然後它內部new ValidationMessageStore(editContext),然後通過自己的方式驗證後,Add驗證消息到ValidationMessageStore即可。

DataAnnotationsValidator

組件是個空殼,它通過級聯參數拿到EditContext對象,然後調用EditContextDataAnnotationsExtensions中定義的擴展方法,創建了一個實現IDispose的對象,組件釋放時會釋放這個對象

這個核心對象內部new ValidationMessageStore(editContext),用來存儲驗證消息。

它在初始化時會註冊:

_editContext.OnFieldChanged += OnFieldChanged;
_editContext.OnValidationRequested += OnValidationRequested;

欄位變化時,驗證,或者外部向editContext請求驗證時,觸發驗證。然後將驗證消息Add到存儲器中。


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

-Advertisement-
Play Games
更多相關文章
  • Vue-router路由 什麼是vue-router? 服務端路由指的是伺服器根據用戶訪問的 URL 路徑返回不同的響應結果。當我們在一個傳統的服務端渲染的 web 應用中點擊一個鏈接時,瀏覽器會從服務端獲得全新的 HTML,然後重新載入整個頁面。 然而,在單頁面應用中,客戶端的 JavaScrip ...
  • React和Vue是前端開發中的兩大熱門框架,各自都有著強大的功能和豐富的生態系統。然而,你有沒有想過,在一個項目中同時使用React和Vue?是的,你沒有聽錯,可以在同一個項目中混用這兩個框架!本文就來分享 3 個用於混合使用 React 和 Vue 的工具! Veaury Veaury 是一個基 ...
  • UI組件庫提供了各種常見的 UI 元素,比如按鈕、輸入框、菜單等,只需要調用相應的組件並按照需求進行配置,就能夠快速構建出一個功能完善的 UI。 雖然市面上有許多不同的UI組件庫可供選擇,但在2023年底也並沒有出現一兩個明確的解決方案能夠適用於所有情況。因為不同的前端框架(例如React、Angu ...
  • 背景介紹 我們存在著大量在PC頁面通過表格看數據業務場景,表格又分為兩種,一種是 antd / fusion 這種基於 dom 元素的表格,另一種是通過 canvas 繪製的類似 excel 的表格。 基於 dom 的表格功能豐富較為美觀,能實現多表頭、合併單元格和各種自定義渲染(如表格中渲染圖形 ...
  • 在現代的Web開發中,優化用戶體驗至關重要。一種常見的方法是在頁面載入時預載入圖片,並展示一個載入進度條,讓用戶瞭解載入進度。在本文中,我們將深入探討如何實現這兩個關鍵功能,以提高網站性能和用戶滿意度 ...
  • 9 月 16 日,全棧 Web 框架 Remix 正式發佈了 2.0 版本,Remix 團隊在發佈 1.0 版本後經過近 2 年的持續努力,發佈了 19 個次要版本、100 多個補丁版本,並解決了數千個問題和拉取請求,終於迎來了第二個主要版本! Remix 具有以下特性: 追求速度、用戶體驗(UX) ...
  • Uber公司技術棧介紹 Uber(Uber Technologies,Inc.)中文譯作“優步”,是一家美國矽谷的科技公司。Uber在2009年,由加利福尼亞大學洛杉磯分校輟學生特拉維斯·卡蘭尼克和好友加勒特·坎普(Garrett Camp)創立。因旗下同名打車APP而名聲大噪。Uber已經進入中國 ...
  • 實踐環境 python 3.6.2 scikit-build-0.16.7 win10 opencv_python-4.5.4.60-cp36-cp36m-win_amd64.whl 下載地址: https://pypi.org/project/opencv-python/4.5.4.60/#fil ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...