一日,想做多语言的站点,使用.net core 3.1,目前最新的东西^_^。
希望使用的地址是这样的:https://localhost:6001/zh-cn/home/index
1. 在 ConfigureServices 里加如下代码:
services.AddLocalization(options => options.ResourcesPath = "Resources");//多语言的资源文件放在 Resources 文件夹下,是一些 resx 文件 var builder = services.AddControllersWithViews() .AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix) .AddDataAnnotationsLocalization(); var supportedCultures = new[] { new CultureInfo("zh-cn"), new CultureInfo("en"), }; services.Configure<RequestLocalizationOptions>(options => { options.DefaultRequestCulture = new RequestCulture(culture: "zh-cn", uiCulture: "zh-cn"); options.SupportedCultures = supportedCultures; options.SupportedUICultures = supportedCultures; options.RequestCultureProviders.Clear(); options.AddInitialRequestCultureProvider(new RouteDataRequestCultureProvider()//url里的地址参数是 lang,特别注意该参数不是存在于 querystring 里的而是在 path 里的。这个比较重要,下面会用到。 { Options = options, RouteDataStringKey = "lang", UIRouteDataStringKey = "lang" }); });
2. 在 Configure 里加如下代码:
app.UseRequestLocalization(); //因为上面使用了 RouteDataRequestCultureProvider,所以本行代码一定要加在 app.UseRouting() 下面!!!否则将不生效!
3. 接2,同样在 Configure 里加代码。在 UseEndpoints 里加入如下一节:
endpoints.MapControllerRoute( name: "en", pattern: "{lang=zh-cn}/{controller=Home}/{action=Index}/{id?}");
4. 在项目下建 Resources 文件夹,里面再建 Controllers.HomeController.en.resx 类似的资源文件。
5. 在 HomeController 里加:
private readonly IStringLocalizer<AboutController> _localizer;
并从构造函数里注入,不表。
6. 使用多言语:
ViewBag.TestTitle = _localizer["关于标题"];
7. 还可以在 View 里使用:
@inject IViewLocalizer Localizer @{ ViewData["Title"] = Localizer["About"]; } <h2>@ViewData["Title"].</h2> <h3>@ViewData["Message"]</h3> <p>@Localizer["Use this area to provide additional information."]</p>
碰到的问题就是一开始并没有把 app.UseRequestLocalization() 放到 app.UseRouting() 的后面而是放到了 Configure 里的第一行,所以一直死活不生效,为什么?
仔细想想,我使用的是 RouteDataRequestCultureProvider,看看这名字吧:RouteDataXXX,是不是和 Route 有关?而 Configure 里不就是配置所有中间件的地方吗?中间件执行是不是有先后顺序啊?那是不是先配置的先执行啊?一上来就想执行 UseRequestLocalization 这个中间件,还没有经过 Route 这一步,显然是 RouteData 还没解析好啊!
还去看了下 RouteDataRequestCultureProvider 的源码:https://github.com/dotnet/aspnetcore/blob/master/src/Middleware/Localization.Routing/src/RouteDataRequestCultureProvider.cs,非常简单,实在没有出错的理由,那只能是自己用错了。
所以就去看 Routing 的文档了:https://docs.microsoft.com/en-us/aspnet/core/fundamentals/routing?view=aspnetcore-3.1,很官方!仔细看还是有收获的。
备忘,以上。