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

Blazor FluentEditForm报错:需提供Model或EditContext参数

解决Blazor中FluentEditForm提示缺少Model/EditContext的问题

问题背景

正在学习Blazor,因Blazor与Fluent UI均由微软开发,遂尝试改用Fluent UI组件。将原有正常运行的EditForm替换为FluentEditForm后,点击登录按钮时出现错误:

InvalidOperationException: EditForm requires either a Model parameter, or an EditContext parameter, please provide one of these.

原有正常运行代码

<EditForm Model="@loginModel" OnValidSubmit="Authenticate" FormName="LoginForm">
    <DataAnnotationsValidator />
    <div class="mb-3 text-center flex-cloumn">
        <h3>LOGIN</h3>
    </div>
    <div class="mb-3">
        <label for="userName" class="form-label">User Name:</label>
        <InputText id="userName" @bind-Value="loginModel.UserName" class="form-control" />
        <ValidationMessage For="() => loginModel.UserName" class="text-danger" />
    </div>
    <div class="mb-3">
        <label for="password" class="form-label">Password:</label>
        <InputText id="password" @bind-Value="loginModel.Password" class="form-control" />
        <ValidationMessage For="() => loginModel.Password" class="text-danger" />
    </div>
    <div class="mb-3 text-center">
        <span class="text-danger">@errorMessage</span>
    </div>
    <button type="submit" class="btn btn-primary">Login</button>
</EditForm>

@code {
    [SupplyParameterFromForm]
    public LoginViewModel loginModel { get; set; } = new();

    private string? errorMessage;

    private async Task Authenticate()
    {
        Console.WriteLine("Authenticate called");
    }
}

替换后的异常代码

<FluentEditForm Model="@loginModel" OnValidSubmit="Authenticate" FormName="LoginForm" novalidate>
    <DataAnnotationsValidator />
    
    <FluentStack Orientation="Orientation.Vertical">
        <h3>LOGIN</h3>
        <div>
            <FluentTextField Name="userName" @bind-Value="loginModel.UserName" Label="User Name" Required />
            <FluentValidationMessage For="@(() => loginModel.UserName)"/>
        </div>
        <div>
            <FluentTextField Name="password" @bind-Value="loginModel.Password" TextFieldType="TextFieldType.Password" Label="Password" Required />
            <FluentValidationMessage For="@(() => loginModel.Password)"/>
        </div>
        <FluentButton Type="ButtonType.Submit" Appearance="Appearance.Accent">Login</FluentButton>
    </FluentStack>
</FluentEditForm>

@code {
    [SupplyParameterFromForm]
    public LoginViewModel loginModel { get; set; } = new();

    private string? errorMessage;

    private async Task Authenticate()
    {
        Console.WriteLine("Authenticate called");
    }
}

错误堆栈信息

Microsoft.AspNetCore.Components.Forms.EditForm.OnParametersSet()
Microsoft.AspNetCore.Components.ComponentBase.RunInitAndSetParametersAsync()
Microsoft.AspNetCore.Components.Rendering.ComponentState.SupplyCombinedParameters(ParameterView directAndCascadingParameters)
Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.InitializeNewSubtree(ref DiffContext diffContext, int frameIndex)
Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.InsertNewFrame(ref DiffContext diffContext, int newFrameIndex)
Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.AppendDiffEntriesForRange(ref DiffContext diffContext, int oldStartIndex, int oldEndIndexExcl, int newStartIndex, int newEndIndexExcl)
Microsoft.AspNetCore.Components.Rendering.ComponentState.RenderIntoBatch(RenderBatchBuilder batchBuilder, RenderFragment renderFragment, out Exception renderFragmentException)
Microsoft.AspNetCore.Components.RenderTree.Renderer.ProcessRenderQueue()
Microsoft.AspNetCore.Components.RenderTree.Renderer.ProcessRenderQueue()
Microsoft.AspNetCore.Components.ComponentBase.StateHasChanged()
Microsoft.AspNetCore.Components.ComponentBase.RunInitAndSetParametersAsync()
Microsoft.AspNetCore.Components.Rendering.ComponentState.SupplyCombinedParameters(ParameterView directAndCascadingParameters)
Microsoft.AspNetCore.Components.Rendering.ComponentState.SetDirectParameters(ParameterView parameters)
Microsoft.AspNetCore.Components.RenderTree.Renderer.RenderRootComponentAsync(int componentId, ParameterView initialParameters)
Microsoft.AspNetCore.Components.HtmlRendering.Infrastructure.StaticHtmlRenderer.BeginRenderingComponent(IComponent component, ParameterView initialParameters)
Microsoft.AspNetCore.Components.Endpoints.EndpointHtmlRenderer.RenderEndpointComponent(HttpContext httpContext, Type rootComponentType, ParameterView parameters, bool waitForQuiescence)
System.Threading.Tasks.ValueTask<TResult>.get_Result()
Microsoft.AspNetCore.Components.Endpoints.RazorComponentEndpointInvoker.RenderComponentCore(HttpContext context)
Microsoft.AspNetCore.Components.Endpoints.RazorComponentEndpointInvoker.RenderComponentCore(HttpContext context)
Microsoft.AspNetCore.Components.Rendering.RendererSynchronizationContext+<>c+<<InvokeAsync>b__10_0>d.MoveNext()
Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
Microsoft.AspNetCore.Antiforgery.Internal.AntiforgeryMiddleware.InvokeAwaited(HttpContext context)
Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)

解决方案

1. 手动创建并传递EditContext

问题根源在于[SupplyParameterFromForm]与FluentEditForm的参数传递逻辑不兼容,手动初始化EditContext可以确保底层EditForm能正确获取到模型:

<FluentEditForm EditContext="@_editContext" OnValidSubmit="Authenticate" FormName="LoginForm" novalidate>
    <DataAnnotationsValidator />
    
    <FluentStack Orientation="Orientation.Vertical">
        <h3>LOGIN</h3>
        <div>
            <FluentTextField Name="userName" @bind-Value="loginModel.UserName" Label="User Name" Required />
            <FluentValidationMessage For="@(() => loginModel.UserName)"/>
        </div>
        <div>
            <FluentTextField Name="password" @bind-Value="loginModel.Password" TextFieldType="TextFieldType.Password" Label="Password" Required />
            <FluentValidationMessage For="@(() => loginModel.Password)"/>
        </div>
        <FluentButton Type="ButtonType.Submit" Appearance="Appearance.Accent">Login</FluentButton>
    </FluentStack>
</FluentEditForm>

@code {
    [SupplyParameterFromForm]
    public LoginViewModel loginModel { get; set; } = new();
    private EditContext? _editContext;
    private string? errorMessage;

    protected override void OnInitialized()
    {
        _editContext = new EditContext(loginModel);
    }

    private async Task Authenticate()
    {
        Console.WriteLine("Authenticate called");
    }
}

2. 移除[SupplyParameterFromForm]属性(适用于交互式组件)

如果你的组件是交互式模式(如InteractiveServer/InteractiveWebAssembly),可以直接移除该属性,确保模型始终有实例:

@code {
    public LoginViewModel loginModel { get; set; } = new();

    private string? errorMessage;

    private async Task Authenticate()
    {
        Console.WriteLine("Authenticate called");
    }
}

3. 更新Fluent UI Blazor到最新版本

部分旧版本的Fluent UI Blazor存在与Blazor SSR表单参数绑定的兼容性问题,更新到最新稳定版可以解决这类bug。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 15:24:57