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
相关产品推荐
相关产品推荐

