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

Blazor数组元素表单绑定异常:提交时获取旧值

问题描述

熟悉C#但刚接触Blazor,需开发从数据库加载数据并支持编辑的页面。按自身思路实现后出现问题:修改输入字段内容并点击提交按钮,控制台输出的仍是旧值,尝试多种方法未解决。疑惑是遗漏关键配置还是实现思路错误?

相关代码

AppVersion类

using System.ComponentModel.DataAnnotations;

namespace Domain.Entities;

public class AppVersion: BaseEntity
{
    [Required]
    public string? VersionNumber { get; set; }
}

页面代码

@page "/version"
@using Service
@using Domain.Entities
@inject AppVersionService AppVersionService

<PageTitle>App Versions</PageTitle>
<div>
    @if (Appversions == null)
    {
        <p>Loading...</p>
    }
    else
    {
        @foreach (var appVersion in Appversions)
        {
            var formName = appVersion.Id.ToString();
            <EditForm Model="appVersion" OnValidSubmit="@ValidUpdateFormSubmitted" OnInvalidSubmit="@InvalidFormSubmitted" FormName="@formName">
                <DataAnnotationsValidator/>
                <ValidationSummary/>
                <span>VersionNumber</span>
                <input
                    type="text"
                    placeholder=""
                    @bind="appVersion.VersionNumber"/>
                <button type="submit">
                    Save
                </button>
            </EditForm>
        }
    }
</div>

@code {
    private AppVersion NewAppVersion { get; set; } = new();
    private IList<AppVersion>? Appversions { get; set; }
    
    protected override async Task OnInitializedAsync()
    {
        Appversions = await AppVersionService.GetAllAsync();
    }
    
    private async Task ValidUpdateFormSubmitted(EditContext editContext)
    {
        var appVersion = editContext.Model as AppVersion;
        
        Console.WriteLine($"Appversion number in Blazor page: {appVersion.VersionNumber}");
        await AppVersionService.UpdateAsync(appVersion);
    }
}

补充排查信息

经排查发现仅开启@rendermode InteractiveServer时才生效,但仍不理解原因,打算在GitHub提交bug报告。另外即使开启该模式,bind-value也完全无法工作。测试代码如下:

@page "/test"

@* @rendermode InteractiveServer *@
@using System.ComponentModel.DataAnnotations

<PageTitle>App Versions</PageTitle>
<div>
    @foreach (var appVersion in Appversions)
    {
        var formName = appVersion.Id.ToString();
        @appVersion.VersionNumber
        <EditForm Model="appVersion" OnValidSubmit="@ValidUpdateFormSubmitted" FormName="@formName">
            <DataAnnotationsValidator/>
            <ValidationSummary/>
            <span>VersionNumber</span>
            <input type="text"
                   placeholder=""
                   class="bg-slate-700"
                   @bind="appVersion.VersionNumber"/>
            <button type="submit">
                Save
            </button>
        </EditForm>
    }
</div>

@code {

    public class AppVersion //: BaseEntity
    {
        public int Id { get; set; }

        [Required]
        public string? VersionNumber { get; set; }
    }
    
    private IList<AppVersion>? Appversions { get; set; }

    protected override void OnInitialized()
    {
        Appversions = new List<AppVersion>
        {
            new() { Id = 1, VersionNumber = "1.0.0" },
            new() { Id = 2, VersionNumber = "1.0.1" },
            new() { Id = 3, VersionNumber = "1.0.2" }
        };
    }

    private void ValidUpdateFormSubmitted(EditContext editContext)
    {
        var appVersion = editContext.Model as AppVersion;
        Console.WriteLine($"Appversion number in Blazor page: {appVersion?.VersionNumber}");
    }
}

解决方案与原因分析

核心原因:渲染模式差异

Blazor的静态服务器渲染(SSR)模式下,页面仅在服务器端渲染一次,发送给浏览器的是纯静态HTML,没有交互逻辑。用户修改输入框内容时,不会同步更新服务器端的组件状态,提交表单时只会发送初始渲染的旧值,因此控制台输出旧数据。

而开启@rendermode InteractiveServer后,页面会通过SignalR建立服务器与浏览器的实时连接,所有交互操作都会同步到服务器端的组件实例,双向绑定功能才会正常生效,提交时能获取到最新的输入值。

关于bind-value失效的问题

bind-value写法错误,Blazor双向绑定的正确语法是@bind(简写)或@bind-Value(注意Value首字母大写),正确代码应为:

<input type="text" @bind-Value="appVersion.VersionNumber" />

优化实现建议

  1. 指定交互式渲染模式:对于需要交互的页面,必须在页面顶部添加:
    @rendermode InteractiveServer
    
    也可在项目全局配置中设置默认交互式渲染模式。
  2. 隔离编辑状态:循环中直接绑定集合元素可能引发状态跟踪问题,建议为每个编辑项创建独立的视图模型,或使用独立的EditContext实例确保状态隔离。
  3. 完善验证逻辑:提交前调用editContext.Validate(),确保模型验证通过后再执行更新操作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 05:25:13