巨集觀上理解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
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...