Blazor自定义Validator业务验证时复杂属性字段级校验不显示
问题根因
嵌套字段旁校验消息无法展示,本质是校验消息的匹配规则不兼容,叠加不规范的组件初始化写法共同导致:
- FieldIdentifier匹配规则错位
Blazor全链路的校验消息传递,完全依赖FieldIdentifier的严格双要素匹配——校验消息存储时关联的模型对象引用,必须和ValidationMessage组件生成的标识完全一致,同时对应的字段名字符串也必须完全匹配,才能将消息渲染到对应字段旁。
对于嵌套属性场景:<ValidationMessage For="@(() => starship.CaptainsName.Firstname)" />初始化时,会自动生成专属的匹配标识:- 模型引用:
starship.CaptainsName(即Firstname属性的直接所属对象,PersonsName类的实例) - 字段名:
"Firstname"(仅取属性本身的名称,不会拼接外层嵌套路径作为前缀)
- 模型引用:
- 自定义Validator存储错误时,通过
CurrentEditContext.Field("CaptainsName.Firstname")生成的标识:- 模型引用:
starship(即EditContext绑定的根模型实例) - 字段名:
"CaptainsName.Firstname"
两个标识的组成要素完全不一致,ValidationMessage自然无法读取到对应字段的错误消息。而ValidationSummary会全局读取所有存储的校验消息,不做字段级匹配,因此所有错误都能正常展示在汇总列表中。
简单属性的校验不受影响,是因为这类属性的直接所属对象就是根模型starship本身,生成的标识和自定义Validator生成的标识完全一致,可以正常匹配。
- 模型引用:
- 组件引用初始化不规范
在页面OnInitialized方法中手动new CustomValidator()赋值给字段的写法,不符合Blazor组件的使用规范:手动实例化的对象没有经过Blazor的组件生命周期管理,无法获得级联参数注入、事件绑定的逻辑支持,本质上是一个没有完成初始化的普通C#类实例。虽然页面渲染完成后,@ref标记会将真实渲染的CustomValidator组件实例覆盖掉这个临时对象,但这类写法本身会引入不可预期的逻辑异常。
补充说明:
ValidateComplexType、ObjectGraphDataAnnotationsValidator这类组件的作用,只是让框架在执行数据注解验证时,能自动遍历到复杂嵌套属性的校验规则,它们生成的错误消息依然遵循嵌套属性的标识匹配规则。而你的自定义Validator是手动拼接字段名生成的标识,和框架的规则天然不兼容,因此这类组件也无法解决问题。
内容的提问来源于stack exchange,提问作者richard
相关产品推荐
相关产品推荐

