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

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";
    }
}

关键注意点

  1. 状态管理:IsLoading在提交时设为true,服务器会返回按钮禁用、文本变为“登录中...”的HTML;认证完成(无论成功失败)再把IsLoading设为false,恢复按钮状态。
  2. 依赖注册:确保在Program.cs中注册IHttpContextAccessor和Cookie认证:
    builder.Services.AddHttpContextAccessor();
    builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
        .AddCookie(options =>
        {
            options.LoginPath = "/login";
            // 其他Cookie配置,比如过期时间、SameSite等
        });
    
  3. 表单提交:用method="post"确保表单提交到服务器端处理,静态渲染下只有服务器端能修改状态并返回新的渲染结果。

这个方案完全避开了JS互操作的限制,纯靠Blazor的服务器端渲染就能实现按钮禁用和加载状态显示,完美适配你的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 05:30:12