问题
I would like to use routed localization in my ASP.NET Core 3.0 Razor Pages application.
https://stackoverflow.com/a/52976625/107718 seems to have a solution for 2.2 but is there any better way of doing this in 3.0 now that it have routing/endpoints reworked?
回答1:
ASP.NET Core 3.0 introduces a new feature of Endpoint Routing by which we can get the culture from the route data before it goes into MVC. This allows us to localize content according to current route without too much effort.
How-to
Firstly, make sure the Localization Service is registered & you've configured supported culture as below:
services.AddLocalization(opts => opts.ResourcesPath = "Resources" );
services.Configure<RequestLocalizationOptions>(options =>
{
var supportedCultures = new[]{
new CultureInfo("en-US"),
new CultureInfo("de"),
new CultureInfo("it"),
// ... others
};
options.SupportedCultures = supportedCultures;
options.SupportedUICultures = supportedCultures;
options.RequestCultureProviders.Insert(0, new RouteDataRequestCultureProvider());
});
And then add an UseRequestLocalization
Middleware and configure a route for culture such that it can get the culture info correctly:
app.UseRouting(); app.UseRequestLocalization(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllerRoute(name: "culture-route", pattern:"{culture=en-US}/{controller=Home}/{action=Index}/{id?}"); endpoints.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); });
Note the above orders are important.
Demo:
[Edit]
Sorry, I didn't notice that you asked for the Razor Page. To work with Razor Page WebApp, create a custom IPageRouteModelConvention
to map the route:
public class CustomCultureRouteRouteModelConvention : IPageRouteModelConvention
{
public void Apply(PageRouteModel model)
{
List<SelectorModel> selectorModels = new List<SelectorModel>();
foreach (var selector in model.Selectors.ToList())
{
var template = selector.AttributeRouteModel.Template;
selectorModels.Add(new SelectorModel(){
AttributeRouteModel = new AttributeRouteModel
{
Template = "/{culture}" + "/" + template
}
});
}
foreach(var m in selectorModels){
model.Selectors.Add(m);
}
}
}
And add this page conventions :
services.AddRazorPages().AddRazorPagesOptions(opts =>
{
opts.Conventions.Add(new CustomCultureRouteRouteModelConvention());
});
services.AddLocalization(opts => opts.ResourcesPath = "Resources");
services.Configure<RequestLocalizationOptions>(options =>
{
var supportedCultures = new[]{
new CultureInfo("en-US"),
new CultureInfo("de"),
new CultureInfo("it"),
new CultureInfo("zh"),
};
options.SupportedCultures = supportedCultures;
options.SupportedUICultures = supportedCultures;
options.RequestCultureProviders.Insert(0, new RouteDataRequestCultureProvider());
});
The middlewares :
app.UseRouting();
app.UseRequestLocalization();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
//endpoints.MapControllerRoute(name: "culture-route", pattern:"{culture=en-US}/{controller=Home}/{action=Index}/{id?}");
//endpoints.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}");
});
来源:https://stackoverflow.com/questions/58721157/routed-localization-in-asp-net-core-3-0-razor-pages