![屬性路徑解析魔法:Blazored.FluentValidation 如何遍歷 MyCollection[123].ChildProp 深層路徑](http://pic.xiahunao.cn/yaotu/屬性路徑解析魔法:Blazored.FluentValidation 如何遍歷 MyCollection[123].ChildProp 深層路徑)
屬性路徑解析魔法Blazored.FluentValidation 如何遍歷 MyCollection[123].ChildProp 深層路徑【免費下載鏈接】FluentValidationA library for using FluentValidation with Blazor項目地址: https://gitcode.com/gh_mirrors/flue/FluentValidation 摘要Blazored.FluentValidation 是一個讓 Blazor 表單無縫接入 FluentValidation 的驗證庫。當你的表單模型里藏著集合與嵌套子對象時它憑什么能精確鎖定MyCollection[123].ChildProp這樣的深層屬性路徑做到改哪個字段、只驗哪個字段本文為你拆解這套屬性路徑解析的完整魔法讓新手也能看懂底層原理。為什么 Blazor 表單驗證需要一個路徑翻譯官用過 BlazorEditForm的朋友都知道表單綁定依賴FieldIdentifier——它由對象實例 字段名組成。當用戶修改嵌套模型中的字段時Blazor 只告訴你某個Item 對象的ChildProp變了至于這個 Item 到底藏在MyCollection的第幾個位置、從根模型怎么走過去它一概不知。而 FluentValidation 的校驗規(guī)則是按完整屬性路徑組織的比如MyCollection[123].ChildProp。一邊給對象字段名一邊要完整路徑兩邊語言不通——這正是 Blazored.FluentValidation 要解決的深層屬性路徑解析難題。一個會迷路的真實場景 假設你的訂單表單是這樣的嵌套模型public class Person { public ListOrder Orders { get; set; } // 訂單集合 } public class Order { public ListItem Items { get; set; } // 商品集合 } public class Item { public decimal Price { get; set; } // 第 124 個訂單里的第 46 件商品 }當用戶修改Orders[123].Items[45].Price時Blazor 只知道某個 Item 的 Price 變了但 FluentValidation 需要完整的Orders[123].Items[45].Price路徑才能命中那條GreaterThan(0)規(guī)則。路徑一旦丟失校驗就會迷路。屬性路徑解析魔法就是在這條迷宮里為兩者搭橋。魔法一正向解析把路徑拆回 FieldIdentifier 當完整校驗提交表單時FluentValidation 返回的錯誤里帶的是字符串路徑Blazored.FluentValidation 需要把它翻譯回FieldIdentifier才能掛到ValidationMessageStore上。這個功能由ToFieldIdentifier完成源碼位于 EditContextFluentValidationExtensions.cs。它的解析思路非常樸素卻暗藏細節(jié)路徑片段處理方式MyCollection當作普通屬性用反射GetProperty取值[123]識別為索引器優(yōu)先走 C# 約定的Item索引器數(shù)組 /IReadOnlyList沒有Item屬性時直接按下標取值遇到null立即停止能走到哪算哪返回當前位置有趣的是代碼里還藏著一個C# 12 專屬補丁集合表達式生成的z__ReadOnlyArray既沒有Item屬性、也轉(zhuǎn)不成object[]所以單獨走IReadOnlyList索引分支——這個細節(jié)讓新手能直觀看到魔法背后也有版本兼容的苦功夫。魔法二反向追溯從 FieldIdentifier 找回完整路徑 如果說正向解析是查字典那么字段級校驗時用到的PropertyPathHelper.ToFluentPropertyPath就是真正的魔法核心。源碼位于 PropertyPathHelper.cs。它的工作方式堪稱優(yōu)雅從根模型出發(fā)做深度優(yōu)先遍歷DFS用一個棧記錄沿途每個節(jié)點的屬性名 索引一旦找到與FieldIdentifier.Model相同的對象就沿Parent鏈回溯把路徑片段反向拼接得到MyCollection[123].ChildProp這樣的完整字符串。整個過程用一張圖可以看得很清楚根模型 (Person) │ ├── MyCollection (屬性) → 節(jié)點記錄: MyCollection │ │ │ ├── 元素[0] ... 元素[122] │ │ │ └── 元素[123] (找到目標!) → 節(jié)點記錄: MyCollection[123] │ │ │ └── ChildProp → 拼出 MyCollection[123].ChildProp每個節(jié)點就是代碼里的Node類帶著PropertyName屬性名、Index集合索引和Parent父指針三件套。正是這三件套讓路徑在迷宮里每一步都不迷路。魔法三交集選擇器只驗證變了的那一個 拿到完整路徑后還有一個巧妙設計IntersectingCompositeValidatorSelector源碼見 IntersectingCompositeValidatorSelector.cs。字段級校驗時庫會構(gòu)造兩個選擇器并取交集原有選擇器按你配置的 RuleSet、規(guī)則條件執(zhí)行變更字段選擇器IncludeProperties(propertyPath)只包含當前變更的那一條路徑。只有兩個選擇器都放行的規(guī)則才會真正執(zhí)行校驗。結(jié)果再按propertyPath精確過濾錯誤消息映射回對應的FieldIdentifier。這樣既避免了改一個字段、全校驗一遍的性能浪費也防止其它字段的錯誤被誤報到你正在輸入的這個輸入框上。改哪個、驗哪個精準到位 ?。三個魔法如何串聯(lián)成一次完整校驗??以用戶修改MyCollection[123].ChildProp為例完整鏈路如下步驟發(fā)生什么關(guān)鍵代碼1?? 字段變更Blazor 觸發(fā)OnFieldChangedEditContext.OnFieldChanged2?? 反向追溯從根模型 DFS 找回完整路徑PropertyPathHelper.cs3?? 交集篩選只執(zhí)行與路徑相關(guān)的規(guī)則IntersectingCompositeValidatorSelector.cs4?? 錯誤映射過濾錯誤并綁定到對應字段ValidateField方法5?? 界面刷新NotifyValidationStateChanged通知組件EditContext內(nèi)置機制小結(jié)給普通用戶的三個啟示 嵌套集合表單也能絲滑驗證無論模型嵌套多深、集合多大屬性路徑解析都能精確定位到Orders[123].Items[45].Price這一層你無需編寫任何路徑解析代碼。性能與體驗兼得字段級驗證 交集選擇器的組合讓 Blazor 表單在深層模型上依然響應迅速、不誤報。源碼是絕佳的學習教材如果你想深入理解反射、深度優(yōu)先遍歷、索引器解析等技巧PropertyPathHelper.cs 和 EditContextFluentValidationExtensions.cs 兩個文件加起來不過三百行卻濃縮了讓兩個框架握手言和的全部智慧。下次當你在 Blazor 里為嵌套集合寫校驗規(guī)則時不妨想想背后那位默默遍歷MyCollection[123].ChildProp的路徑翻譯官——正是它讓深層屬性路徑的魔法在每一次按鍵間悄然發(fā)生。?【免費下載鏈接】FluentValidationA library for using FluentValidation with Blazor項目地址: https://gitcode.com/gh_mirrors/flue/FluentValidation創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考