Blazor中ObjectGraphDataAnnotationsValidator失焦验证异常求助
Blazor表单失焦验证异常原因及解决方案
核心问题原因
- EditContext缓存旧实例引用:你的
EditContext在OnInitialized阶段创建,此时绑定的是ViewModel中初始化的TestDto Instance1。ObjectGraphDataAnnotationsValidator会在EditContext初始化时,为当前ViewModel及嵌套对象生成验证元数据并缓存。 - 实例替换未同步验证上下文:当你在
OnAfterRender中替换为TestDto Instance2后,EditContext并未更新内部缓存的验证目标引用。InputText失焦触发的字段级验证,仍然会读取旧实例(Instance1)的Name值(空字符串),因此触发Required错误。 - 手动验证的特殊性:调用
EditContext.Validate()时,会重新遍历当前ViewModel的所有属性,直接读取新实例(Instance2)的当前值,因此验证结果符合预期。
解决方案
方案1:替换实例后重新创建EditContext
在更新TestDto实例后,重新初始化EditContext,让验证系统绑定到最新的ViewModel状态:
protected override void OnAfterRender(bool firstRender) { if(firstRender){ ViewModel.LoadTestDto(); // 重新创建EditContext以关联新的TestDto实例 EditContext = new EditContext(ViewModel); StateHasChanged(); } base.OnAfterRender(firstRender); }
方案2:更新现有实例属性而非替换对象
避免直接替换TestDto实例,而是修改已有实例的属性值,保持EditContext绑定的实例引用不变:
public class TestViewModel { // ... 其他代码 ... public void LoadTestDto() { if (TestDto != null) { // 更新现有实例的属性 TestDto.Name = "Loaded name"; } else { TestDto = new TestDto(InstanceId) { Name = "Loaded name" }; } } }
方案3:手动通知EditContext字段变更
如果必须替换实例,在替换后手动触发字段变更通知,让验证系统更新缓存的引用:
protected override void OnAfterRender(bool firstRender) { if(firstRender){ ViewModel.LoadTestDto(); // 通知EditContext,TestDto及其Name属性已变更 var testDtoField = FieldIdentifier.Create(() => ViewModel.TestDto); EditContext.NotifyFieldChanged(testDtoField); var nameField = FieldIdentifier.Create(() => ViewModel.TestDto.Name); EditContext.NotifyFieldChanged(nameField); StateHasChanged(); } base.OnAfterRender(firstRender); }
内容的提问来源于stack exchange,提问作者cash_hr
相关产品推荐
相关产品推荐

