Blazor .NET 8:非InteractiveServer模式下禁用登录提交按钮
解决静态渲染Blazor登录页的按钮加载状态问题
因为你的登录页是静态渲染(无法使用InteractiveServer模式,需依赖HttpContext.SignInAsync),直接调用IJSRuntime必然报错——静态渲染阶段组件还在服务器端生成HTML,未到达客户端,根本无法执行JS。不用折腾JS,纯Blazor状态绑定就能解决问题:
核心思路
在组件内维护一个IsLoading布尔状态,绑定到按钮的禁用属性和显示文本,提交登录请求时切换状态,服务器端渲染不同的HTML内容,完全不需要JS介入。
实现代码示例
@page "/login" @rendermode Static @inject IHttpContextAccessor HttpContextAccessor @inject NavigationManager NavManager <h3>用户登录</h3> <form method="post" @onsubmit="HandleLogin"> <div class="mb-3"> <label class="form-label">用户名</label> <input type="text" class="form-control" @bind="Username" required /> </div> <div class="mb-3"> <label class="form-label">密码</label> <input type="password" class="form-control" @bind="Password" required /> </div> <button type="submit" disabled="@IsLoading" class="btn btn-primary"> @(IsLoading ? "登录中..." : "登录") </button> @if (!string.IsNullOrEmpty(ErrorMsg)) { <div class="text-danger mt-2">@ErrorMsg</div> } </form> @code { private string Username { get; set; } = string.Empty; private string Password { get; set; } = string.Empty; private bool IsLoading { get; set; } private string? ErrorMsg { get; set; } private async Task HandleLogin() { IsLoading = true; ErrorMsg = null; try { // 替换成你的自定义用户验证逻辑 var isValidUser = await ValidateUser(Username, Password); if (isValidUser) { // 创建用户声明 var claims = new List<Claim> { new Claim(ClaimTypes.Name, Username), // 按需添加其他声明,比如角色、邮箱等 }; var identity = new ClaimsIdentity(claims, "CustomDatabaseAuth"); var principal = new ClaimsPrincipal(identity); // 执行登录 await HttpContextAccessor.HttpContext!.SignInAsync( CookieAuthenticationDefaults.AuthenticationScheme, principal, new AuthenticationProperties { IsPersistent = true }); // 登录成功跳转首页 NavManager.NavigateTo("/"); } else { ErrorMsg = "用户名或密码错误"; } } catch { ErrorMsg = "登录失败,请稍后重试"; } finally { IsLoading = false; } } // 模拟自定义数据库验证方法 private async Task<bool> ValidateUser(string username, string password) { // 这里替换成你的数据库查询逻辑 await Task.Delay(1000); // 模拟网络/数据库延迟 return username == "admin" && password == "123456"; } }
关键注意点
- 状态管理:
IsLoading在提交时设为true,服务器会返回按钮禁用、文本变为“登录中...”的HTML;认证完成(无论成功失败)再把IsLoading设为false,恢复按钮状态。 - 依赖注册:确保在
Program.cs中注册IHttpContextAccessor和Cookie认证:builder.Services.AddHttpContextAccessor(); builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme) .AddCookie(options => { options.LoginPath = "/login"; // 其他Cookie配置,比如过期时间、SameSite等 }); - 表单提交:用
method="post"确保表单提交到服务器端处理,静态渲染下只有服务器端能修改状态并返回新的渲染结果。
这个方案完全避开了JS互操作的限制,纯靠Blazor的服务器端渲染就能实现按钮禁用和加载状态显示,完美适配你的场景。
内容的提问来源于stack exchange,提问作者Murtaza
相关产品推荐
相关产品推荐

