You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

子组件如何将验证问题传递给父组件的<DataAnnotationsValidator>

解决Blazor子组件验证信息传递到父组件的问题

核心问题分析

你当前用的DataAnnotationsValidator默认只验证顶层模型,不会递归处理嵌套的子模型(比如Model.AddressForm),所以子组件里的[Required]验证错误没法传递到父级的ValidationSummary中。

方案一:使用ObjectGraphDataAnnotationsValidator(最简单)

直接把父组件里的DataAnnotationsValidator替换成ObjectGraphDataAnnotationsValidator,它会自动递归验证所有嵌套的模型属性,包括子组件绑定的子模型。

修改后的父级Razor页面代码:

<EditForm Model="@Model">
  <ObjectGraphDataAnnotationsValidator />
  <AddressForm @ref="_addressElement"
       Value="@Model.AddressForm"
       ValueChanged="OnAddressSelected">
  </AddressForm>
  <ValidationSummary />
</EditForm>

注:.NET 5及以上版本默认包含Microsoft.AspNetCore.Components.DataAnnotations.Validation包,低版本可能需要手动安装。

方案二:手动关联子模型到父级验证上下文

如果不想用递归验证器,可以在子组件中手动把子模型注册到父级的EditContext中:

  1. 修改子组件AddressForm.razor,注入父组件传递的EditContext,并在初始化时将子模型纳入验证体系:
@inject EditContext EditContext
@implements IDisposable

<DxTextBox @bind-Text="@Model.StreetNumberAndName" ShowValidationIcon="true" />

@code {
    [Parameter, Required]
    public AddressFormModel Value { get; set; } = default!;

    [Parameter]
    public EventCallback<AddressFormModel> ValueChanged { get; set; }

    private ValidationMessageStore? _messageStore;

    protected override void OnInitialized()
    {
        if (EditContext == null)
            throw new InvalidOperationException("AddressForm必须在EditForm内部使用。");

        // 创建验证消息存储,关联子模型
        _messageStore = new ValidationMessageStore(EditContext);
        // 监听子模型属性变化,触发验证
        EditContext.OnFieldChanged += HandleFieldChanged;
        // 执行初始验证
        ValidateModel();
    }

    private void HandleFieldChanged(object? sender, FieldChangedEventArgs e)
    {
        if (e.FieldIdentifier.Model == Value)
        {
            ValidateModel();
        }
    }

    private void ValidateModel()
    {
        _messageStore?.Clear();
        var validationContext = new ValidationContext(Value);
        var validationResults = new List<ValidationResult>();
        Validator.TryValidateObject(Value, validationContext, validationResults, validateAllProperties: true);

        foreach (var validationResult in validationResults)
        {
            foreach (var memberName in validationResult.MemberNames)
            {
                _messageStore?.Add(EditContext.Field(Value, memberName), validationResult.ErrorMessage!);
            }
        }

        EditContext.NotifyValidationStateChanged();
    }

    public void Dispose()
    {
        if (EditContext != null)
        {
            EditContext.OnFieldChanged -= HandleFieldChanged;
        }
    }
}
  1. 父组件保持原DataAnnotationsValidator即可,子组件会主动将验证错误添加到父级EditContext,ValidationSummary就能显示这些错误提示。

验证效果

两种方案都能让父组件的ValidationSummary显示子组件中StreetNumberAndName字段的[Required]错误,同时子组件的DxTextBox也会正常展示验证图标。

内容的提问来源于stack exchange,提问作者David Thielen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 21:15:15