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

Blazor Server应用点击下单按钮无法跳转至外部支付URL求助

问题解决:Blazor Server点击下单按钮在新标签页打开支付链接

核心问题分析

你的代码中页面刷新的根源是表单默认提交行为:点击type="submit"按钮会触发浏览器自带的表单提交,直接刷新页面,打断后续的JS跳转逻辑,即使ProcessCheckout方法被执行,页面刷新也会重置组件状态,导致OnAfterRenderAsync中的跳转代码无法生效。

最优解决方案

方案1:保留表单并阻止默认提交

修改表单的onsubmit事件,先阻止浏览器默认提交行为,再调用下单逻辑:

<form @onsubmit="async (e) => { e.PreventDefault(); await ProcessCheckout(); }">
    <div>
        <h2>Checkout</h2>
        <button type="submit" class="btn btn-primary">Place Order</button>
        <a href="/cart" class="btn btn-secondary">Back to Shopping Bag</a>
    </div>
</form>

方案2:移除表单,直接使用按钮点击事件

如果不需要表单的其他功能,直接用按钮的@onclick绑定方法,彻底避免表单提交问题:

<div>
    <h2>Checkout</h2>
    <button @onclick="ProcessCheckout" class="btn btn-primary">Place Order</button>
    <a href="/cart" class="btn btn-secondary">Back to Shopping Bag</a>
</div>

调整后端逻辑

同时需要修正组件初始化逻辑,移除页面加载时自动调用ProcessCheckout的代码(否则页面一打开就会触发支付流程,不符合点击按钮下单的需求):

@code {
    private bool shouldRedirect;
    private string authorizationUrl;
    @inject IJSRuntime JS // 确保已注入IJSRuntime

    protected override async Task OnInitializedAsync()
    {
        // 移除自动调用,仅在点击按钮时触发下单
        // await ProcessCheckout();
    }

    private async Task ProcessCheckout()
    {
        try
        {
            var userId = await GetUserIdAsync();
            var netTotal = await _cartService.GetBasketNetTotalAsync(userId);

            var authState = await _authStateProvider.GetAuthenticationStateAsync();
            var user = authState.User;
            string strEmail = user.FindFirst(System.Security.Claims.ClaimTypes.Email)?.Value;

            string token = _configuration["PayStackSettings:PayStackSecretKey"];
            var payStack = new PayStackApi(token);

            TransactionInitializeRequest request = new()
            {
                AmountInKobo = Convert.ToInt32(netTotal) * 100,
                Email = strEmail,
                Reference = Generate().ToString(),
                Currency = "GHS"
            };

            var response = payStack.Transactions.Initialize(request);
            if (response.Status)
            {
                authorizationUrl = response.Data.AuthorizationUrl;
                shouldRedirect = true;
                StateHasChanged(); // 触发组件重新渲染,执行OnAfterRenderAsync
            }
        }
        catch (Exception ex)
        {            
            throw new Exception(ex.Message);
        }
    }

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (shouldRedirect)
        {
            shouldRedirect = false; // 重置标记,避免重复执行
            await JS.InvokeVoidAsync("open", authorizationUrl, "_blank");
        }
    }

    private async Task<string> GetUserIdAsync()
    {
        var authState = await _authStateProvider.GetAuthenticationStateAsync();
        var user = authState.User;
        return user.FindFirst(System.Security.Claims.ClaimTypes.NameIdentifier)?.Value;
    }

    private static int Generate() => new Random((int)DateTime.Now.Ticks).Next(100000000, 999999999);
}

关键注意事项

  1. 确保组件已注入IJSRuntime(代码中需添加@inject IJSRuntime JS)
  2. 必须阻止表单默认提交或移除表单,否则页面刷新会破坏跳转逻辑
  3. 移除初始化时的自动下单调用,保证仅在用户点击按钮时触发流程

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 10:24:56