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

Blazor WebAssembly含URL锚点时本地化功能失效问题

问题描述

将基于HTML、CSS和JS模板开发的网站转为ASP.NET Core(MVC)项目运行正常,但转为Blazor WebAssembly项目后出现异常:通过锚点标签跳转到页面章节后,本地化组件失效,无法切换语言。

相关代码

CultureSelector.razor 组件

@using System.Globalization
@inject IJSRuntime JS
@inject NavigationManager Navigation

<ul class="list-inline s-header__action s-header__action--lb">
    <select class="localeSettings" @bind="Culture">
       @foreach (var culture in supportedCultures)
       {
            <option class="localeSettingsOption" value="@culture">@culture.DisplayName</option>
       }
   </select>
</ul>

@code
{
    private CultureInfo[] supportedCultures = new[]
    {
        new CultureInfo("en-US"),
        new CultureInfo("it-IT"),
        new CultureInfo("de-DE"),
    };

    private CultureInfo Culture
    {
        get => CultureInfo.CurrentCulture;
        set
        {
            if (CultureInfo.CurrentCulture != value)
            {
                var js = (IJSInProcessRuntime)JS;
                js.InvokeVoid("blazorCulture.set", value.Name);

                Navigation.NavigateTo(Navigation.Uri, forceLoad: true);
            }
        }
    }
}

Program.cs 配置

using myProject;
using System.Globalization;
using Microsoft.JSInterop;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;

var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("#app");
builder.RootComponents.Add<HeadOutlet>("head::after");

builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });

builder.Services.AddLocalization();

var host = builder.Build();

CultureInfo culture;
var js = host.Services.GetRequiredService<IJSRuntime>();
var result = await js.InvokeAsync<string>("blazorCulture.get");

if (result != null)
{
    culture = new CultureInfo(result);
}
else
{
    culture = new CultureInfo("en-US");
    await js.InvokeVoidAsync("blazorCulture.set", "en-US");
}

CultureInfo.DefaultThreadCurrentCulture = culture;
CultureInfo.DefaultThreadCurrentUICulture = culture;

await host.RunAsync();

Index.razor 中的锚点元素

<a href="#js__scroll-to-section" class="s-scroll-to-section-v1--bc g-margin-b-15--xs">
    <span class="g-font-size-18--xs g-color--white ti-angle-double-down"></span>
    <p class="text-uppercase g-color--white g-letter-spacing--3 g-margin-b-0--xs">@Loc["Learn More"]</p>
</a>

问题细节:原MVC项目中滚动脚本会移除URL中的锚点,但Blazor应用中锚点会保留(如https://localhost:7123/#js__scroll-to-section),此时语言选择下拉菜单无任何响应。


问题原因与解决方法

核心原因

当URL包含锚点时,Navigation.NavigateTo(Navigation.Uri, forceLoad: true)会带着锚点重载页面,导致Blazor初始化时的文化读取逻辑未正确触发,或重载后的页面因锚点存在引发组件状态更新异常,最终导致文化切换失效。

具体修复方案

1. 修正CultureSelector的导航逻辑:移除URL锚点

修改Culture属性的setter,跳转时剔除URL中的锚点部分,确保重载时使用干净的基础URL:

private CultureInfo Culture
{
    get => CultureInfo.CurrentCulture;
    set
    {
        if (CultureInfo.CurrentCulture != value)
        {
            var js = (IJSInProcessRuntime)JS;
            js.InvokeVoid("blazorCulture.set", value.Name);

            // 移除URL中的锚点,只保留基础路径
            var cleanUri = Navigation.Uri.Split('#')[0];
            Navigation.NavigateTo(cleanUri, forceLoad: true);
        }
    }
}

2. 替换原生锚点为Blazor+JS滚动

避免使用原生<a href="#xxx">(会残留锚点在URL),改用Blazor点击事件结合JS实现滚动,并手动移除URL锚点:

修改Index.razor中的元素

<button @onclick="() => ScrollToSection('js__scroll-to-section')" 
        class="s-scroll-to-section-v1--bc g-margin-b-15--xs"
        style="background: none; border: none; cursor: pointer;">
    <span class="g-font-size-18--xs g-color--white ti-angle-double-down"></span>
    <p class="text-uppercase g-color--white g-letter-spacing--3 g-margin-b-0--xs">@Loc["Learn More"]</p>
</button>

@code {
    [Inject]
    private IJSRuntime JS { get; set; }

    private async Task ScrollToSection(string sectionId)
    {
        // 调用JS实现平滑滚动
        await JS.InvokeVoidAsync("scrollToSection", sectionId);
        // 移除URL中的锚点
        await JS.InvokeVoidAsync("history.replaceState", null, "", Navigation.BaseUri);
    }
}

在index.html中添加滚动脚本

<script>
function scrollToSection(sectionId) {
    const element = document.getElementById(sectionId);
    if (element) {
        element.scrollIntoView({ behavior: 'smooth' });
    }
}
</script>

3. 确保blazorCulture脚本正常工作

确认你的全局JS脚本(如index.html中)正确实现了localStorage的读写:

<script>
window.blazorCulture = {
    get: () => localStorage.getItem('culture'),
    set: (culture) => localStorage.setItem('culture', culture)
};
</script>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 07:14:58