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

如何在Blazor的EditForm只读模式下关闭验证功能?

问题描述

我用同一个EditForm实现对象的创建、读取和更新操作。创建和更新时需要验证,但读取模式下,如果对象是批量导入的(可能存在验证失败的情况),我希望关闭验证——毕竟此时所有字段都是只读状态,错误值没法修改,验证只会带来糟糕的体验,甚至陷入无法修正的困境。请问该如何关闭读取模式下的验证?

我的Razor页面代码如下:

<EditForm EditContext="EditContext"
          OnValidSubmit="HandleValidSubmitAsync"
          OnInvalidSubmit="HandleInvalidSubmitAsync"
          Context="EditFormContext">
    <ObjectGraphDataAnnotationsValidator />
    <CustomValidation @ref="_customValidation" />
    <DxFormLayout>
        <DxFormLayoutItem Caption="Region:" ColSpanMd="4">
            <DxComboBox @bind-Value="@Model.Region"
                        ReadOnly="@(ModeState == Mode.Read)"
                        Data="@AllRegions"
                        TextFieldName="Name"
                        AllowUserInput="false"
                        ListRenderMode="ListRenderMode.Entire"
                        FilteringMode="@(ModeState == Mode.Read ? DataGridFilteringMode.None : DataGridFilteringMode.Contains)"
                        ShowValidationIcon="true" />
        </DxFormLayoutItem>
        <DxFormLayoutItem Caption="Name:" Field="@nameof(Model.Name)" ColSpanMd="4">
            <DxTextBox @bind-Text="@Model.Name"
                       ReadOnly="@(ModeState == Mode.Read)"
                       ShowValidationIcon="true" />
        </DxFormLayoutItem>
        <DxFormLayoutItem Caption="Unique Id:" Field="@nameof(Model.UniqueId)" ColSpanMd="4">
            <DxTextBox @bind-Text="@Model.UniqueId"
                       ReadOnly="@(ModeState != Mode.Create)"
                       ShowValidationIcon="true" />
        </DxFormLayoutItem>

        <AddressForm @ref="_addressElement"
                     Context="@EditContext"
                     ReadOnly="@(ModeState == Mode.Read)"
                     OnValidated="OnAddressValidated"
                     ValueChanged="@OnAddressChanged" />

        @* Read & Update modes only - the booleans *@
        <DxFormLayoutItem Visible="@(ModeState != Mode.Create)" ColSpanMd="4">
            <DxCheckBox @bind-Checked="@Model.Enabled"
                        ReadOnly="@(ModeState == Mode.Read)">Enabled</DxCheckBox>
        </DxFormLayoutItem>
        <DxFormLayoutItem Visible="@(ModeState != Mode.Create)" ColSpanMd="4">
            <DxCheckBox @bind-Checked="@Model.Closed"
                        ReadOnly="@(ModeState == Mode.Read)">Closed</DxCheckBox>
        </DxFormLayoutItem>
        <DxFormLayoutItem Visible="@(ModeState != Mode.Create)" ColSpanMd="4">
            <DxCheckBox @bind-Checked="@Model.Deleted"
                        ReadOnly="true">Deleted</DxCheckBox>
        </DxFormLayoutItem>
        
        <DxFormLayoutItem ColSpanMd="12">
            <ValidationSummary />
        </DxFormLayoutItem>
        <DxFormLayoutItem ColSpanMd="12">
            <DxButton Enabled="@SubmitEnabled"
                      Text="@SubmitButtonText"
                      SubmitFormOnClick="true"
                      RenderStyle="@ButtonRenderStyle.Secondary" />
        </DxFormLayoutItem>

    </DxFormLayout>
</EditForm>
解决方案

1. 条件渲染验证组件(推荐)

直接在读取模式下不加载验证相关组件,从根源上关闭验证逻辑:

<EditForm EditContext="EditContext"
          OnValidSubmit="HandleValidSubmitAsync"
          OnInvalidSubmit="HandleInvalidSubmitAsync"
          Context="EditFormContext">
    @* 仅在非读取模式下渲染验证组件 *@
    @if (ModeState != Mode.Read)
    {
        <ObjectGraphDataAnnotationsValidator />
        <CustomValidation @ref="_customValidation" />
    }
    
    <!-- 原有表单内容保持不变 -->
    
    @* 同时把所有输入组件的验证图标也设置为条件显示 *@
    <DxComboBox @bind-Value="@Model.Region"
                ReadOnly="@(ModeState == Mode.Read)"
                ...
                ShowValidationIcon="@(ModeState != Mode.Read)" />
    
    <!-- 其他输入组件同理修改ShowValidationIcon属性 -->
    
    @* 条件隐藏验证摘要 *@
    <DxFormLayoutItem ColSpanMd="12" Visible="@(ModeState != Mode.Read)">
        <ValidationSummary />
    </DxFormLayoutItem>
</EditForm>

2. 手动控制EditContext验证状态

如果需要保留验证组件但临时禁用验证,可以在后台代码中手动清除验证消息并标记表单为有效:

protected override void OnParametersSet()
{
    base.OnParametersSet();
    if (ModeState == Mode.Read)
    {
        // 清除所有已存在的验证消息
        EditContext?.ClearValidationMessages();
        // 强制标记整个表单为已验证通过状态
        EditContext?.MarkAsModified();
    }
}

// 同时修改提交逻辑,读取模式下直接跳过验证检查
private async Task HandleValidSubmitAsync()
{
    if (ModeState == Mode.Read)
    {
        // 读取模式下无需执行提交逻辑,直接返回
        return;
    }
    // 正常执行创建/更新的业务逻辑
}

3. 条件禁用表单提交(补充)

读取模式下可以直接禁用提交按钮,避免用户误触发提交验证:

<DxButton Enabled="@(ModeState != Mode.Read && SubmitEnabled)"
          Text="@SubmitButtonText"
          SubmitFormOnClick="true"
          RenderStyle="@ButtonRenderStyle.Secondary" />

内容的提问来源于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.17 17:30:39