ASP.NET Core路由映射时默认获取当前路由culture值的问题咨询
问题根源
你的配置存在两个核心错误:
- 路由规则是应用启动时一次性注册的,你在
UseEndpoints中给自定义路由传入的culture = currentCulture是启动时读取的固定默认文化值,不会随每个请求动态更新 - 你自定义的文化赋值中间件修改的是全局变量
currentCulture,存在多请求并发下的线程安全问题,完全无法实现动态获取当前请求文化的效果
修复方案
1. 调整Startup路由配置
删掉自定义路由中固定的culture默认值
.NET Core路由生成逻辑会自动继承当前请求的环境路由值(Ambient Route Values),只要当前请求的路由中存在culture参数,Url.Action、标签助手生成路由时会自动复用当前的culture值,无需手动传参:
app.UseEndpoints(endpoints => { // 移除自定义路由的固定culture默认值 endpoints.MapControllerRoute("ContentList", "{culture}/content/{perma}/{id}", new { controller = "Content", action = "List" }); endpoints.MapControllerRoute("ContentDetails", "{culture}/page/{perma}/{id}",new { controller = "Content", action = "Details" }); endpoints.MapControllerRoute( name: "areas", pattern: "{culture:culture}/{area:exists}/{controller=Home}/{action=Index}/{id?}"); endpoints.MapControllerRoute( name: "default", pattern: "{culture:culture}/{controller=Home}/{action=Index}/{id?}"); endpoints.MapControllerRoute( name: "catchall", pattern: "{*catchall}", defaults: new { controller = "Home", action = "RedirectToDefaultLanguage", culture = defaultCulture }); });
2. 修正文化赋值中间件
将原自定义中间件移到UseRouting之后,同时移除全局变量赋值逻辑,直接给当前请求的线程设置文化:
app.UseRouting(); // 文化赋值中间件放在此处 app.Use(async (context, next) => { if (context.Request.RouteValues.TryGetValue("culture", out var routeCulture) && !string.IsNullOrEmpty(routeCulture?.ToString())) { var cultureInfo = new CultureInfo(routeCulture.ToString()); CultureInfo.CurrentCulture = cultureInfo; CultureInfo.CurrentUICulture = cultureInfo; } await next.Invoke(); }); app.UseAuthentication(); app.UseAuthorization();
效果验证
修改完成后无需调整页面代码,Url.Action会自动匹配当前请求的culture值:
- 当前访问
/en/content/pages/8时,生成的路由自动带/en/前缀 - 当前访问
/ar/content/pages/8时,生成的路由自动带/ar/前缀
内容的提问来源于stack exchange,提问作者Ahmad Alaa
相关产品推荐
相关产品推荐

