Blazor SSR页面使用MudBlazor提交表单时出现EditForm参数缺失错误的解决方法
Blazor SSR页面使用MudBlazor提交表单时出现EditForm参数缺失错误的解决方法
问题原因分析
你遇到的错误是因为在Blazor SSR页面中,EditForm配置了传统HTML表单的method="post"属性,这会触发浏览器的原生表单提交流程,而非Blazor的交互式表单处理逻辑。在这个过程中Blazor组件上下文无法正确传递,导致EditForm找不到指定的Model参数。另外你绑定了仅在表单验证失败时触发的OnInvalidSubmit事件,却未处理验证通过后的提交逻辑,进一步加剧了流程混乱。
具体修复步骤
1. 移除EditForm的method="post"属性
Blazor SSR的EditForm不需要传统的method="post",它会通过内置的交互式机制处理表单提交。移除该属性后,表单会遵循Blazor的组件逻辑运行,避免上下文丢失。
2. 绑定正确的提交事件
将OnInvalidSubmit替换为OnValidSubmit,因为你需要在表单验证通过后执行登录逻辑。OnInvalidSubmit仅在输入不符合验证规则时触发,不是处理正常登录的正确事件。
3. 修复登录逻辑中的硬编码密码
你的SubmitDetails方法里硬编码了密码"admin@123",完全忽略了用户输入的密码,这会导致登录逻辑失效,需要改为使用用户输入的Input.Password。
4. 完善密码显示/隐藏功能(可选)
你之前定义了ButtonTestclick方法但未绑定到任何按钮,导致密码框的显示/隐藏功能无法使用,我们可以补全这部分交互提升体验。
修改后的完整代码
页面渲染部分
@layout EmptyLayout @page "/Account/login" @using System.ComponentModel.DataAnnotations @using Microsoft.AspNetCore.Authentication @using Microsoft.AspNetCore.Identity @inject UserManager<User> UserManager @inject SignInManager<User> SignInManager @inject ISnackbar _snackbar @inject NavigationManager _navigation @inject IdentityRedirectManager RedirectManager <PageTitle>Log in</PageTitle> <div class="d-flex flex-grow-1 mud-width-full align-center justify-center" style="min-height:100vh"> <EditForm Model="Input" OnValidSubmit="SubmitDetails" FormName="login"> <DataAnnotationsValidator /> <MudText Typo="Typo.h2" Align="Align.Center" Class="mb-3" Color="Color.Primary">Rosui</MudText> <MudStack Spacing="3" AlignItems="AlignItems.Center" Justify="Justify.Center"> <MudTextField @bind-Value="Input.Email" Variant="Variant.Outlined" For="(() => Input.Email)" Style="min-width:300px"> </MudTextField> <MudStack Spacing="0" Justify="Justify.Center" AlignItems="AlignItems.End"> <MudTextField @bind-Value="Input.Password" For="(() => Input.Password)" Variant="Variant.Outlined" Style="min-width:300px" InputType="@PasswordInput" Adornment="Adornment.End" AdornmentIcon="@PasswordInputIcon" OnAdornmentClick="ButtonTestclick"> </MudTextField> <MudButton Variant="Variant.Text" Color="Color.Dark" Size="Size.Small" Class="pa-0 ma-0"> <MudText Typo="Typo.caption">Forgot Password?</MudText> </MudButton> </MudStack> <MudButton Variant="Variant.Filled" Color="Color.Primary" Disabled="@_processing" ButtonType="ButtonType.Submit" Style="width:200px" Class="mb-6"> @if (_processing) { <MudProgressCircular Class="ms-n1" Size="Size.Small" Indeterminate="true"></MudProgressCircular> } else { <MudText>Login</MudText> } </MudButton> </MudStack> </EditForm> </div>
逻辑处理部分
@code { [CascadingParameter] private HttpContext HttpContext { get; set; } = default!; protected override async Task OnInitializedAsync() { if (HttpMethods.IsGet(HttpContext.Request.Method)) { // 清除现有外部Cookie,确保登录流程干净 await HttpContext.SignOutAsync(IdentityConstants.ExternalScheme); } } InputType PasswordInput = InputType.Password; string PasswordInputIcon = Icons.Material.Filled.VisibilityOff; bool isShow; void ButtonTestclick() { if (isShow) { isShow = false; PasswordInputIcon = Icons.Material.Filled.VisibilityOff; PasswordInput = InputType.Password; } else { isShow = true; PasswordInputIcon = Icons.Material.Filled.Visibility; PasswordInput = InputType.Text; } } [SupplyParameterFromQuery] private string? ReturnUrl { get; set; } [SupplyParameterFromForm] private InputModel Input { get; set; } = new(); bool _processing = false; async Task SubmitDetails() { try { _processing = true; var user = await UserManager.FindByEmailAsync(Input.Email) ?? throw new Exception("Login Credentials Not Found"); // 使用用户输入的密码执行登录 var result = await SignInManager.PasswordSignInAsync( user, Input.Password, Input.RememberMe, lockoutOnFailure: false); if (!result.Succeeded) { throw new Exception("Login Credentials Are Wrong"); } RedirectManager.RedirectTo(ReturnUrl); } catch (Exception ex) { _snackbar.Add(ex.Message, Severity.Error); } finally { _processing = false; } } public async Task Enter(KeyboardEventArgs e) { if (e.Key == "Enter" || e.Key == "NumpadEnter") { await SubmitDetails(); } } private sealed class InputModel { [Required] [EmailAddress] public string Email { get; set; } = ""; [Required] [DataType(DataType.Password)] public string Password { get; set; } = ""; [Display(Name = "Remember me?")] public bool RememberMe { get; set; } } }
额外说明
- 我们给密码输入框添加了
Adornment相关属性,绑定到你之前定义的ButtonTestclick方法,实现了密码显示/隐藏的交互。 - 完善了登录结果的判断逻辑,之前的代码直接假设
result不为空,现在会检查result.Succeeded来确认登录是否成功。 - 改用
OnValidSubmit确保只有验证通过的表单才会触发登录流程,避免无效提交。
备注:内容来源于stack exchange,提问作者Muheeb
相关产品推荐
相关产品推荐

