Blazor WASM组件通过路由实现请求级本地化配置咨询
Blazor WASM Widget 路由式本地化实现方案
1. 配置本地化服务与支持的文化
在Program.cs中注册本地化服务,指定资源文件路径和支持的文化列表:
var builder = WebAssemblyHostBuilder.CreateDefault(args); builder.RootComponents.Add<App>("#app"); builder.RootComponents.Add<HeadOutlet>("head::after"); // 注册本地化服务,指定资源文件存放目录 builder.Services.AddLocalization(options => options.ResourcesPath = "Resources"); // 定义支持的文化集合 var supportedCultures = new[] { new CultureInfo("en"), new CultureInfo("en-US"), new CultureInfo("zh-CN"), new CultureInfo("zh") }; // 配置本地化选项 builder.Services.Configure<RequestLocalizationOptions>(options => { options.DefaultRequestCulture = new RequestCulture("en-US"); options.SupportedCultures = supportedCultures; options.SupportedUICultures = supportedCultures; });
2. 实现路由段文化解析器
自定义RequestCultureProvider,从路由首段提取文化代码并验证是否在支持列表中:
public class RouteSegmentRequestCultureProvider : RequestCultureProvider { private readonly NavigationManager _navigationManager; private readonly IEnumerable<CultureInfo> _supportedCultures; public RouteSegmentRequestCultureProvider(NavigationManager navigationManager, IEnumerable<CultureInfo> supportedCultures) { _navigationManager = navigationManager; _supportedCultures = supportedCultures; } public override Task<ProviderCultureResult?> DetermineProviderCultureResult(HttpContext httpContext) { var relativePath = _navigationManager.ToBaseRelativePath(_navigationManager.Uri); var pathSegments = relativePath.Split('/', StringSplitOptions.RemoveEmptyEntries); if (pathSegments.Length == 0) return Task.FromResult<ProviderCultureResult?>(null); var cultureCode = pathSegments[0]; var matchedCulture = _supportedCultures.FirstOrDefault(c => c.Name.Equals(cultureCode, StringComparison.OrdinalIgnoreCase) || c.TwoLetterISOLanguageName.Equals(cultureCode, StringComparison.OrdinalIgnoreCase)); return Task.FromResult(matchedCulture != null ? new ProviderCultureResult(matchedCulture.Name) : null); } }
3. 注册自定义文化解析器
将自定义解析器加入本地化选项的提供器列表,并设置为最高优先级:
// 在Program.cs的本地化配置后添加 builder.Services.Configure<RequestLocalizationOptions>(options => { // 插入自定义解析器到最前面,优先使用路由文化 options.RequestCultureProviders.Insert(0, provider => new RouteSegmentRequestCultureProvider( provider.GetRequiredService<NavigationManager>(), supportedCultures)); });
4. 配置全局路由模板
修改App.razor中的Router组件,强制路由首段为文化代码,并处理无文化段的跳转:
@inject NavigationManager NavigationManager @inject IOptions<RequestLocalizationOptions> LocalizationOptions <Router AppAssembly="@typeof(App).Assembly" RouteTemplate="{culture:regex(^[a-z]{2}-[A-Z]{2}$|^[a-z]{2}$)}/{*route}"> <Found Context="routeData"> <RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" /> </Found> <NotFound> <LayoutView Layout="@typeof(MainLayout)"> @{ var supportedCultures = LocalizationOptions.Value.SupportedCultures; var relativePath = NavigationManager.ToBaseRelativePath(NavigationManager.Uri); var hasValidCulturePrefix = supportedCultures.Any(c => relativePath.StartsWith($"{c.Name}/", StringComparison.OrdinalIgnoreCase) || relativePath.StartsWith($"{c.TwoLetterISOLanguageName}/", StringComparison.OrdinalIgnoreCase)); if (!hasValidCulturePrefix) { // 无有效文化前缀时,跳转到默认文化路由 NavigationManager.NavigateTo($"/{LocalizationOptions.Value.DefaultRequestCulture.Culture.Name}/{relativePath}", forceLoad: true); } else { <p>页面不存在</p> } } </LayoutView> </NotFound> </Router>
5. 组件本地化实现
5.1 创建资源文件
在项目根目录创建Resources文件夹,添加对应组件的资源文件:
Widget1.resx(默认文化,如英文)Widget1.zh-CN.resx(中文简体)Widget1.en.resx(英文)
资源文件中添加键值对,例如:
| 键 | 英文值 | 中文值 |
|---|---|---|
| WidgetTitle | Widget 1 | 组件1 |
| WelcomeMessage | Welcome to Widget 1 | 欢迎使用组件1 |
5.2 组件中使用本地化
在Widget组件中注入IStringLocalizer并调用资源:
@page "/{culture}/widget1" @inject IStringLocalizer<Widget1> Localizer <h1>@Localizer["WidgetTitle"]</h1> <p>@Localizer["WelcomeMessage"]</p>
6. 测试与嵌入
- 访问
/en-US/widget1将显示英文内容,访问/zh-CN/widget1显示中文内容 - 嵌入iframe时直接使用带文化段的路由地址即可,例如:
<iframe src="https://your-widget-domain/zh-CN/widget1" width="300" height="200"></iframe>
内容的提问来源于stack exchange,提问作者KingKerosin
相关产品推荐
相关产品推荐

