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

如何在.NET 9.0 Razor组件中通过表单POST传递数据并保留防伪验证?

如何在.NET 9.0 Razor组件中通过表单POST传递数据并保留防伪验证?

首先咱们先理清楚你当前的问题:你想用Blazor WASM组件的表单POST到服务器端Razor组件,既不想把参数暴露在地址栏,又遇到了防伪验证的报错——哪怕加了@formname和[IgnoreAntiforgeryToken]也没解决。其实这个需求完全可以实现,只是有些配置细节需要调整,下面一步步来解决:

第一步:修正防伪服务的错误配置

你之前设置了options.Cookie.Expiration = TimeSpan.Zero,这会让防伪Cookie直接过期,导致服务器根本无法完成验证,先把这个配置删掉,用默认的防伪服务配置就行:

builder.Services.AddAntiforgery(); // 去掉自定义的Cookie过期时间设置

app.UseAntiforgery();这个保留,但要确保它在中间件管道的正确位置——放在app.UseRouting()之后、app.UseAuthorization()之前就可以。

第二步:在Blazor WASM组件中正确获取并传递防伪令牌

Blazor WASM是客户端应用,不会像服务器端Razor页面那样自动生成防伪令牌,所以得手动从服务器获取令牌,再添加到表单里:

  1. 服务器端新增获取防伪令牌的端点
    在服务器的Program.cs里加一个允许匿名访问的端点,用来返回防伪令牌:
app.MapGet("/antiforgery/token", (IAntiforgery antiforgery, HttpContext context) =>
{
    var tokens = antiforgery.GetAndStoreTokens(context);
    return Results.Ok(new
    {
        RequestToken = tokens.RequestToken
    });
}).AllowAnonymous();
  1. 完善Blazor WASM组件的表单
    注入HttpClient和NavigationManager,在组件初始化时获取防伪令牌,把令牌作为隐藏字段加到表单里,同时确保@formname属性正确设置:
@inject HttpClient Http
@inject NavigationManager NavManager

<form @formname="myawesomeform" method="post" action="/myawesomereceivingpage">
    <!-- 防伪令牌隐藏字段 -->
    <input type="hidden" name="__RequestVerificationToken" value="@_requestToken" />
    <!-- 你要传递的私密参数 -->
    <input type="hidden" name="SecretValue" value="你需要传递的内容" />
    <button type="submit">提交并跳转</button>
</form>

@code {
    private string _requestToken = string.Empty;

    protected override async Task OnInitializedAsync()
    {
        // 从服务器获取防伪令牌
        var tokenResponse = await Http.GetFromJsonAsync<AntiforgeryToken>("/antiforgery/token");
        if (tokenResponse != null)
        {
            _requestToken = tokenResponse.RequestToken;
        }
    }

    // 用于接收令牌的模型类
    private class AntiforgeryToken
    {
        public string RequestToken { get; set; } = string.Empty;
    }
}

第三步:服务器端接收组件正确处理表单

现在把[IgnoreAntiforgeryToken]删掉,让防伪验证正常生效,同时给处理方法加上[FormName]属性关联你的表单名,解决“未指定提交表单”的报错:

如果接收端是Razor Pages页面(比如MyAwesomeReceivingPage.cshtml.cs):

public class MyAwesomeReceivingPageModel : PageModel
{
    // 绑定表单传递的参数
    [BindProperty]
    public string SecretValue { get; set; } = string.Empty;

    // 关联表单名,让服务器识别对应的表单提交
    [FormName("myawesomeform")]
    public IActionResult OnPost()
    {
        // 这里已经自动完成防伪验证,验证失败会直接返回400错误
        // 处理参数,比如存到TempData再跳转到目标组件
        TempData["SecretValue"] = SecretValue;
        return RedirectToPage("/YourTargetComponent");
    }
}

如果接收端是Blazor Server组件,更推荐用Razor Pages做中转(因为Blazor组件本身更适合交互式操作),或者直接用API端点接收POST后再跳转。

为什么之前的方法行不通?

  1. 你设置了防伪Cookie立即过期,导致服务器无法验证令牌;
  2. Blazor WASM表单没有手动添加防伪令牌,服务器端验证失败;
  3. 服务器端的处理方法没有关联@formname,所以识别不到对应的表单提交。

这样调整后,就能实现通过POST传递私密参数、不暴露在地址栏,同时保留防伪验证的需求啦。

备注:内容来源于stack exchange,提问作者sanepete

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 11:49:33