我正在从事支持多语言的 Blazor Web Assembly 项目。要求是将语言添加到 URL 作为第一段。
我添加了本地化和资源文件,一切似乎都工作正常,但我必须向每个页面上的每个路由添加前缀才能识别该页面。
@page "/{lang}/counter"
@code {
[Parameter]
public string Lang { get; set; }
}
有没有办法全局添加前缀
/{lang}
,默认情况下将应用于所有路由,并且可以将该值设置为可注入服务?
谢谢,编码愉快
在我的项目中,我还需要在 URL 的第一段中使用语言前缀。经过很长时间的搜索,通过 URL 中的第一段来简化多语言支持的路由组件的创建,我找到了唯一的解决方案 - 使用 T4 为路由组件生成 Route 属性。
下面是这个T4文件。其中只需要填写输入数据即可:
更改输入数据后,需要重新生成T4文件以获得一个.cs文件,其中包含路由组件的分部类及其Route属性。
为了方便起见,我建议将 T4 文件放在 Pages 文件夹中,所有可路由组件都位于该文件夹中。
附注要通过第一个 URL 段在 Blazor 服务器中提供多语言支持,我建议您阅读这篇文章: https://plbonneville.com/blog/url-based-localization-scheme-for-blazor-server/
<#@ template debug="false" hostspecific="true" language="C#" #>
<#@ assembly name="System.Core" #>
<#@ import namespace="System" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ output extension=".cs" #>
<# // Input data
/// <summary>List of prefix language segments for all routes</summary>
string[] languages = new string[] { "ru", "uz", "en" };
/// <summary>Name for project namespace</summary>
string nameSpace = "Manager.Pages";
/// <summary>Data for generating routable components</summary>
RoutableComponents[] routableComponents = new RoutableComponents[] {
new RoutableComponents {
Name = "Index",
FixedRoutes = new string[] {
"/"
},
Routes = new string[] {
""
}
},
new RoutableComponents {
Name = "Counter",
FixedRoutes = new string[] {
"/counter"
},
Routes = new string[] {
"/counter",
"/counter/{Segment1?}",
"/counter/{Segment1}/{Segment2?}/{*Segments}",
}
},
new RoutableComponents {
Name = "FetchData",
FixedRoutes = new string[] {
"/fetchdata"
},
Routes = new string[] {
"/fetchdata",
"/fetchdata/{Segment1?}",
"/fetchdata/{Segment1}/{Segment2?}/{*Segments}",
}
}
};
#>
<# // The code generation
Write("using Microsoft.AspNetCore.Components;\n\n");
Write("namespace {0};\n\n", nameSpace);
foreach(var component in routableComponents) {
foreach(var route in component.FixedRoutes) {
Write("[Route(\"{0}\")]\n", route);
}
foreach(var route in component.Routes) {
foreach(var language in languages) {
Write("[Route(\"/{0}{1}\")]\n", language, route);
}
}
Write("public partial class {0} : ComponentBase {{ }}\n\n", component.Name);
}
#>
<#+
public struct RoutableComponents {
public string Name;
public string[] FixedRoutes;
public string[] Routes;
}
#>
结果是以下 .cs 文件:
using Microsoft.AspNetCore.Components;
namespace Manager.Pages;
[Route("/")]
[Route("/ru")]
[Route("/uz")]
[Route("/en")]
public partial class Index : ComponentBase { }
[Route("/counter")]
[Route("/ru/counter")]
[Route("/uz/counter")]
[Route("/en/counter")]
[Route("/ru/counter/{Segment1?}")]
[Route("/uz/counter/{Segment1?}")]
[Route("/en/counter/{Segment1?}")]
[Route("/ru/counter/{Segment1}/{Segment2?}/{*Segments}")]
[Route("/uz/counter/{Segment1}/{Segment2?}/{*Segments}")]
[Route("/en/counter/{Segment1}/{Segment2?}/{*Segments}")]
public partial class Counter : ComponentBase { }
[Route("/fetchdata")]
[Route("/ru/fetchdata")]
[Route("/uz/fetchdata")]
[Route("/en/fetchdata")]
[Route("/ru/fetchdata/{Segment1?}")]
[Route("/uz/fetchdata/{Segment1?}")]
[Route("/en/fetchdata/{Segment1?}")]
[Route("/ru/fetchdata/{Segment1}/{Segment2?}/{*Segments}")]
[Route("/uz/fetchdata/{Segment1}/{Segment2?}/{*Segments}")]
[Route("/en/fetchdata/{Segment1}/{Segment2?}/{*Segments}")]
public partial class FetchData : ComponentBase { }