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

.NET 6升级至.NET 8后Blazor NavigateTo跳转失效问题

问题:.NET 8 SSR模式下Blazor NavigateTo跳转登录页出现404错误

我把正常运行的.NET 6纯WebAssembly项目升级到.NET 8,保留原有架构并开启首页服务器端渲染(SSR)优化体验。需求是用户点击页面元素后跳转登录页,登录后返回原页面(通过本地存储记录元素),但用NavigateTo跳转至带ReturnUrl="/"的登录页时出现「Not Found」错误,代码在OnAfterRender方法中执行,确认是浏览器端操作。


当前配置代码

Routes.Razor配置

<Router AppAssembly="typeof(Program).Assembly">
    <Found Context="routeData">
        <AuthorizeRouteView RouteData="routeData" DefaultLayout="typeof(Layout.MainLayout)">
            <NotAuthorized>
                <RedirectToLogin />
            </NotAuthorized>
        </AuthorizeRouteView>
        <FocusOnNavigate RouteData="routeData" Selector="h1" />
    </Found>
</Router>

App.razor渲染模式配置

<HeadOutlet @rendermode="RenderModeForPage" /> 

对应后台逻辑:

public partial class App
{
    [CascadingParameter]
    private HttpContext HttpContext { get; set; } = default!;

    private IComponentRenderMode? RenderModeForPage => HttpContext.Request.Path.StartsWithSegments("/Account")
                    ? null
                    : RenderMode.InteractiveWebAssembly;
}

跳转测试代码

尝试用GetUriWithQueryParameters生成链接返回null:

string reg = _navigationManager.GetUriWithQueryParameters("Account/Login", new Dictionary<string, object?> { ["ReturnUrl"] = "/" });
_navigationManager.NavigateTo(reg);

简化测试:按钮直接跳转正常,但NavigateTo触发404:

<div class="ctr">
    <div class="clnk">
        @* <Button Size="Size.Small" Color="Color.Primary" Type="ButtonType.Link" To="Account/Login">Login/Sign Up</Button> *@
        <Button Size="Size.Small" Color="Color.Primary" Clicked="Login">Login/Sign Up</Button>
    </div>
</div>
public void Login()
{
    _navigationManager.NavigateTo("Account/Login");
}

登录页路由配置

@page "/Account/Login"

完整App.razor代码

<!DOCTYPE html>
<html lang="en">

<head>

    <!-- Google tag (gtag.js) -->
    GOOGLE STUFF
    <!-- END of Google tag (gtag.js) -->

    <meta charset="utf-8" />
    <!--Google Fonts-->
    GOOGLE FONTS STUFF
    <title>WMAP</title>
    <base href="/" />

    <!--OTHER SCRIPTS inside of head section -->
    LINKS TO OTHER SCRIPTS
    <!-- END OF OTHER SCRIPTS head section -->

    LINKS TO STYLESHEETS

    <link rel="icon" sizes="512x512" href="icon-512.png" />
    <link rel="icon" sizes="192x192" href="icon-192.png" />


        <!-- Meta Pixel Code -->
    META (FACEBOOK/INSTA) Code
    <!-- End Meta Pixel Code -->


    <HeadOutlet @rendermode="RenderModeForPage" />
</head>

<body>
    <Routes @rendermode="RenderModeForPage" />
    <script src="_framework/blazor.web.js"></script>

    PAYMENT PROVIDER SCRIPTS
    
    <!-- WMAP JS-->
    <script src="/js/WMAP.js" asp-append-version="true"></script>
    <!-- /WMAP JS-->
</body>

</html>
public partial class App
{
    [CascadingParameter]
    private HttpContext HttpContext { get; set; } = default!;

    private IComponentRenderMode? RenderModeForPage => HttpContext.Request.Path.StartsWithSegments("/Account")
        ? null
        : RenderMode.InteractiveWebAssembly;
}

问题原因与解决方案

核心原因

你遇到的404是因为浏览器端的Blazor WASM路由器无法识别服务器端渲染(SSR)的路由。当在InteractiveWebAssembly模式下使用NavigateTo("Account/Login")时,客户端路由器会尝试在WASM组件中匹配该路由,但你的登录页是SSR模式(RenderModeForPage对Account路径返回null,使用服务器端渲染),客户端找不到对应组件,就触发404。

而<Button Type="Link">能正常跳转,是因为它生成的是标准HTML锚点链接,浏览器会直接向服务器发请求,由服务器处理SSR路由匹配,因此能正常访问。

解决办法

1. 使用绝对路径触发硬导航

在NavigateTo中给路径加上/前缀,强制浏览器向服务器发送请求,跳过客户端路由匹配:

// 基础跳转
_navigationManager.NavigateTo("/Account/Login");

// 带ReturnUrl的正确写法(编码避免特殊字符问题)
var currentUrl = _navigationManager.Uri;
_navigationManager.NavigateTo($"/Account/Login?ReturnUrl={Uri.EscapeDataString(currentUrl)}");

2. 修复GetUriWithQueryParameters的使用

该方法第一个参数需要绝对路径(或基于当前页面的相对路径),加上前缀即可正常生成链接:

string reg = _navigationManager.GetUriWithQueryParameters("/Account/Login", new Dictionary<string, object?> { ["ReturnUrl"] = "/" });
_navigationManager.NavigateTo(reg);

3. 可选:客户端路由 fallback 配置

如果希望客户端路由器兼容SSR路由,可在Routes.Razor中添加<NotFound>区块,当客户端找不到路由时触发硬导航:

<Router AppAssembly="typeof(Program).Assembly">
    <Found Context="routeData">
        <!-- 原有内容 -->
    </Found>
    <NotFound>
        <script>window.location.href = window.location.pathname + window.location.search;</script>
    </NotFound>
</Router>

优先推荐第一种方法,更直观且符合SSR路由的设计逻辑。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 20:27:11