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

如何在Blazor和Razor Page中实现非匹配路由的301永久重定向

解决方案

方案1:修改Catch-all路由页面直接返回301(推荐)

你之前通过NavigationManager.NavigateTo实现的是客户端侧跳转,自然无法返回301状态码,直接在Catch-all页面初始化阶段操作服务端HttpContext即可解决:

  1. 首先在Startup.cs/Program.cs中注册IHttpContextAccessor服务:
services.AddHttpContextAccessor();
  1. 修改Catch-all路由页面代码:
@page "/{*slug}"
@inject IHttpContextAccessor HttpContextAccessor
@inject NavigationManager NavigationManager

@code {
    protected override async Task OnInitializedAsync()
    {
        var httpContext = HttpContextAccessor.HttpContext;
        // 服务端渲染场景直接返回301
        if (httpContext != null && !httpContext.Response.HasStarted)
        {
            httpContext.Response.Redirect("/", permanent: true);
            return;
        }
        // 兼容客户端跳转场景,强制刷新触发服务端301
        NavigationManager.NavigateTo("/", forceLoad: true);
    }
}

该方案完全依赖Razor Pages原生的路由优先级规则,不会出现路由匹配贪婪的问题,已存在的/page/{slug}、/{slug}精确路由会优先匹配,只有未命中任何规则的请求才会进入该Catch-all页面返回301。

方案2:调整端点配置优化匹配优先级

如果你希望通过中间件/端点配置实现,需要修正两个错误:

  1. 调整端点注册顺序,Catch-all路由必须放在所有精确路由之后,同时设置最低优先级
  2. 正确调用重定向方法避免302状态码被覆盖
    修改后的Startup.cs配置如下:
app.UseEndpoints(endpoints =>
{
    endpoints.MapBlazorHub();
    // 优先注册精确Razor页面路由
    endpoints.MapRazorPages();
    endpoints.MapFallbackToPage("/_Host");
    // 最后注册Catch-all路由,设置最低优先级
    endpoints.Map("/{*slug}", HandleApiFallback)
        .WithOrder(int.MaxValue);
});

Task HandleApiFallback(HttpContext context)
{
    // 直接用permanent参数返回301,无需手动修改状态码
    context.Response.Redirect("/", permanent: true);
    return Task.CompletedTask;
}

注意:.NET 5及更早版本可以用.WithMetadata(new RouteOrderMetadata(int.MaxValue))替代WithOrder方法。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 01:06:03