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

Blazor下拉选择框未触发Required验证错误消息的问题

Blazor下拉框Required验证不触发的解决方案

核心问题分析

  1. HTML值映射错误:原生<option value=null>会将值设为字符串"null"而非C#的null,而[Required]特性仅对字符串null或空串触发验证,导致验证规则不生效。
  2. EditContext未感知变化:手动使用@onchange修改模型属性时,Blazor的表单上下文(EditContext)不会自动检测属性变更,因此不会触发验证逻辑。

解决方案1:使用Blazor双向绑定(推荐)

替换手动@onchange为Blazor原生双向绑定,自动处理属性变更通知和验证触发:

修改下拉框代码

<ContentTemplate>
    <EditForm Model="@_bid" OnValidSubmit="@SaveBid" class="animate-fade" Context="editFrmBidConfirmation">
        <DataAnnotationsValidator />
        <ServerValidator @ref="serverValidator" />
        <ValidationSummary />
        <BSContainer>
            <BSRow>
                <BSCol MD="2" Class="form-label">Product Line:</BSCol>
                <BSCol MD="4">
                    <!-- 使用双向绑定,@bind-value:after处理变更后的逻辑 -->
                    <select id="ProductLine" 
                            @bind-value="@_bid.ProductLineId" 
                            @bind-value:after="ProductLineChanged">
                        <!-- 默认选项设为空串,绑定后会映射为C# null -->
                        <option value="">Select a Product Line</option>
                        @foreach (ProductLine a in _productLines)
                        {
                            <option value="@a.Id">@a.Name</option>
                        }
                    </select>
                </BSCol>
            </BSRow>
        </BSContainer>
    </EditForm>
</ContentTemplate>

修改ProductLineChanged方法

无需手动赋值,直接处理业务逻辑即可:

private async Task ProductLineChanged()
{
    _productLineSelected = !string.IsNullOrEmpty(_bid.ProductLineId);
    
    if (!string.IsNullOrEmpty(_bid.ProductLineId))
    {
        _bidClasses = await processor.ProcessObject<List<Bid_Class>>(await apiClient.GetBidClassesAsync(_bid.ProductLineId));
        _bidStatuses = await processor.ProcessObject<List<Bid_StatusViewModel>>(await apiClient.GetBidStatusesAsync(_bid.ProductLineId));
        _bidTypes = await processor.ProcessObject<List<Bid_Type>>(await apiClient.GetBidTypesAsync(_bid.ProductLineId));
        _distributorGroups = new();
        _distributors = await processor.ProcessObject<List<DistributorViewModel>>(await apiClient.GetDistributorsByProductLineAsync(_bid.ProductLineId));
    } 
    // 双向绑定自动触发StateHasChanged,无需手动调用
}

解决方案2:手动触发EditContext验证(保留@onchange场景)

若必须使用手动@onchange,需手动通知EditContext执行验证:

步骤1:注入并初始化EditContext

private BidViewModel _bid { get; set; }
private EditContext _editContext; // 添加EditContext字段

protected override void OnInitialized()
{
    _editContext = new EditContext(_bid);
    base.OnInitialized();
}

步骤2:绑定EditContext到EditForm

<EditForm EditContext="@_editContext" OnValidSubmit="@SaveBid" class="animate-fade" Context="editFrmBidConfirmation">

步骤3:修改ProductLineChange方法

处理值映射并手动触发验证:

private async Task ProductLineChange(ChangeEventArgs e)
{
    // 将HTML值映射为C# null(空串或"null"字符串都转为null)
    var selectedValue = e.Value?.ToString();
    _bid.ProductLineId = string.IsNullOrEmpty(selectedValue) || selectedValue.Equals("null", StringComparison.OrdinalIgnoreCase) 
        ? null 
        : selectedValue;

    _productLineSelected = !string.IsNullOrEmpty(_bid.ProductLineId);
    
    if (!string.IsNullOrEmpty(_bid.ProductLineId))
    {
        _bidClasses = await processor.ProcessObject<List<Bid_Class>>(await apiClient.GetBidClassesAsync(_bid.ProductLineId));
        _bidStatuses = await processor.ProcessObject<List<Bid_StatusViewModel>>(await apiClient.GetBidStatusesAsync(_bid.ProductLineId));
        _bidTypes = await processor.ProcessObject<List<Bid_Type>>(await apiClient.GetBidTypesAsync(_bid.ProductLineId));
        _distributorGroups = new();
        _distributors = await processor.ProcessObject<List<DistributorViewModel>>(await apiClient.GetDistributorsByProductLineAsync(_bid.ProductLineId));
    } 

    // 手动触发表单验证
    _editContext.Validate();
    RefreshScreen(null);
}

步骤4:修正默认选项值

<option value="">Select a Product Line</option>

内容的提问来源于stack exchange,提问作者Paul T. Rykiel

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 14:15:49