Вот обходной путь, который работает для меня:
<b>// if the route matches this pattern, let's say:</b>
app.UseMvc(routeBuilder => {
routeBuilder.MapRoute("route1",template: "/{controller=Home}/{action=Index}");
});
<b>// else if the route matches `{culture=en-US}/{controller=Home}/{action=Index}`</b>
app.UseRouter(routeBuilder =>{
var template = "{culture=en-US}/{controller=Home}/{action=Index}";
routeBuilder.MapMiddlewareRoute(template, appBuilder =>{
appBuilder.Use(async(context, next)=>{
var routeData = context.GetRouteData();
var controller = routeData.Values["controller"] as string;
var action= routeData.Values["action"] as string;
var culture= routeData.Values["culture"] as string;
// get the real backing path according to current route data
context.Request.Path = getNormalizedPath(routeData);
await next();
});
appBuilder.UseRequestLocalization();
appBuilder.UseMvc(rb=>{
rb.MapRoute(name:"cultureRoute",template:template);
});
});
<strike>// if you have other MVC routes, add them below:</strike>
<strike>// routeBuilder.MapRoute(name:"mvcRoutes",template: "{area:exists}/{controller=Home}/{action=Index}");</strike>
});
<b>// else if doesn't match the above pattern, let's say:</b>
app.UseMvc(routeBuilder => {
routeBuilder.MapRoute("route3",template: "/test/mvc/{controller=Home}/{action=Index}");
});
private string getNormalizedPath(RouteData routeData)
{
var culture= routeData.Values["culture"] as string;
var controller = routeData.Values["controller"] as string;
var action= routeData.Values["action"] as string;
controller = ... real controller according to current culture & controller string
action = ... real action according to current culture & controller string
return $"/{culture}/{controller}/{action}";
}
Вам нужно настроить getNormalizedPath(routeData)
, чтобы получить реальный путь, который будет перенаправлен на резервный контроллер / действие.
Чтобы автоматически настроить функцию запроса локализации в соответствии с текущим путем маршрута, вам необходимо вставить RouteDataRequestCultureProvider
:
services.Configure<RequestLocalizationOptions>(options =>
{
var supportedCultures = new[]{
new CultureInfo("en"),
new CultureInfo("fr"),
new CultureInfo("de"),
new CultureInfo("it"),
};
options.SupportedCultures = supportedCultures;
options.SupportedUICultures = supportedCultures;
options.RequestCultureProviders.Insert(0, new RouteDataRequestCultureProvider());
});
Как обнаружил @ ʞᴉɯ в комментариях, первый UseMvc()
не работает хорошо для 2.2. Нам нужно изменить MVC-совместимость на CompatibilityVersion.Version_2_1
:
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);