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

如何在Blazor服务器端渲染应用中设置语言并更新组件

Blazor SSR 语言切换不生效的解决方案

你的问题核心在于:当前仅在客户端设置了文化信息,但未同步更新服务器端的本地化上下文,也没有触发已渲染组件的重新渲染。以下是具体解决步骤:

1. 完善服务器端本地化配置

首先在 Program.cs 中补充本地化服务和请求文化中间件,确保服务器能正确识别和应用客户端的文化设置:

// 添加本地化支持,指定资源文件路径
builder.Services.AddLocalization(options => options.ResourcesPath = "Resources");

// 配置支持的文化列表
var supportedCultures = new[]
{
    new CultureInfo("en-US"),
    new CultureInfo("pt-PT"),
    new CultureInfo("fr-FR")
};

// 配置请求本地化选项
builder.Services.Configure<RequestLocalizationOptions>(options =>
{
    options.DefaultRequestCulture = new RequestCulture("en-US");
    options.SupportedCultures = supportedCultures;
    options.SupportedUICultures = supportedCultures;
    // 使用Cookie持久化文化设置,确保SSR首次渲染能读取正确文化
    options.RequestCultureProviders.Insert(0, new CookieRequestCultureProvider());
});

// 注册HttpContext访问器
builder.Services.AddHttpContextAccessor();

// 添加全局文化状态服务,用于通知组件文化变化
builder.Services.AddScoped<CultureState>(sp =>
{
    var contextAccessor = sp.GetRequiredService<IHttpContextAccessor>();
    var requestCulture = contextAccessor.HttpContext?.Features.Get<IRequestCultureFeature>()?.RequestCulture.Culture 
                         ?? CultureInfo.GetCultureInfo("en-US");
    return new CultureState(requestCulture);
});

// 中间件顺序要注意,放在MapRazorComponents之前
app.UseRequestLocalization();

app.MapRazorComponents<App>()
    .AddInteractiveServerRenderMode();

2. 创建全局文化状态服务

这个服务用于广播文化变化事件,让所有需要本地化的组件感知到文化切换:

public class CultureState
{
    public event Action? CultureChanged;
    private CultureInfo _currentCulture;

    public CultureState(CultureInfo initialCulture)
    {
        _currentCulture = initialCulture;
    }

    public void SetCulture(CultureInfo culture)
    {
        if (_currentCulture.Name != culture.Name)
        {
            _currentCulture = culture;
            CultureChanged?.Invoke();
        }
    }

    public CultureInfo CurrentCulture => _currentCulture;
}

3. 修改语言切换组件逻辑

更新组件,实现客户端+服务器端的文化同步,并触发全局状态通知:

@using System.Globalization
@inject IJSRuntime JSRuntime
@inject IHttpContextAccessor HttpContextAccessor
@inject CultureState CultureState

<select class="form-control" @onchange="ChangeLanguage">
    @foreach (var language in supportedLanguages)
    {
        <option value="@language.Name" selected="@(CultureState.CurrentCulture.Name == language.Name)">
            @language.DisplayName
        </option>
    }
</select>

@code
{
    CultureInfo[] supportedLanguages = new[]
    {
        new CultureInfo("en-US"),
        new CultureInfo("pt-PT"),
        new CultureInfo("fr-FR"),
    };

    private async Task ChangeLanguage(ChangeEventArgs e)
    {
        var cultureName = e.Value?.ToString();
        if (string.IsNullOrEmpty(cultureName)) return;

        var targetCulture = new CultureInfo(cultureName);

        // 1. 更新服务器端Cookie和当前线程文化
        var httpContext = HttpContextAccessor.HttpContext;
        if (httpContext != null)
        {
            httpContext.Response.Cookies.Append(
                CookieRequestCultureProvider.DefaultCookieName,
                CookieRequestCultureProvider.MakeCookieValue(new RequestCulture(targetCulture)),
                new CookieOptions { Expires = DateTimeOffset.UtcNow.AddYears(1) }
            );
            CultureInfo.CurrentCulture = targetCulture;
            CultureInfo.CurrentUICulture = targetCulture;
        }

        // 2. 同步客户端存储(可选,确保页面刷新后保留文化设置)
        await JSRuntime.InvokeVoidAsync("localStorage.setItem", "blazor-culture", cultureName);

        // 3. 通知所有组件文化已更新
        CultureState.SetCulture(targetCulture);
    }
}

4. 让本地化组件响应文化变化

在使用 IStringLocalizer 的组件中,订阅文化变化事件并触发重新渲染:

@inject IStringLocalizer<App> _localize
@inject CultureState CultureState
@implements IDisposable

<h1>@_localize["Welcome"]</h1>
<p>@_localize["Description"]</p>

@code {
    protected override void OnInitialized()
    {
        CultureState.CultureChanged += RefreshLocalization;
    }

    private void RefreshLocalization()
    {
        // 触发组件重新渲染,更新本地化文本
        StateHasChanged();
    }

    public void Dispose()
    {
        // 取消订阅,避免内存泄漏
        CultureState.CultureChanged -= RefreshLocalization;
    }
}

关键说明

  • 原代码仅在客户端执行了JS操作,但Blazor SSR的本地化依赖服务器端的文化上下文,必须同步更新服务器端的Cookie和线程文化。
  • 通过全局 CultureState 服务的事件通知机制,无需刷新页面即可让所有已渲染组件重新读取本地化资源并更新UI。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 16:05:23