如何在ASP.NET Core 8的Startup.cs中替换路由以支持多语言?
实现外部控制器多语言路由替换方案
针对你引用外部AccountController并需要替换路由支持多语言的需求,以下是ASP.NET Core 8的具体配置方案:
1. 先配置请求本地化
首先需要设置项目支持指定的语言文化,并从路由中识别文化标识:
若使用Program.cs(ASP.NET Core 8默认结构)
var builder = WebApplication.CreateBuilder(args); // 注册本地化服务 builder.Services.AddLocalization(options => options.ResourcesPath = "Resources"); // 配置支持的语言文化 builder.Services.Configure<RequestLocalizationOptions>(options => { var supportedCultures = new[] { new CultureInfo("en"), new CultureInfo("it") }; options.DefaultRequestCulture = new RequestCulture("en"); options.SupportedCultures = supportedCultures; options.SupportedUICultures = supportedCultures; // 从路由的{culture}段读取文化信息(优先级最高) options.RequestCultureProviders.Insert(0, new RouteDataRequestCultureProvider { RouteDataStringKey = "culture", UIRouteDataStringKey = "culture", Options = options }); });
若使用传统Startup.cs结构
在ConfigureServices方法中添加上述本地化配置代码。
2. 替换外部控制器路由
由于无法修改外部项目的控制器代码,我们可以通过两种方式覆盖原有路由:
方式一:直接映射多语言路由(简单场景首选)
在路由配置中直接指定带文化前缀的路由,优先级高于原有路由:
Program.cs版本
var app = builder.Build(); // 应用本地化中间件 app.UseRequestLocalization(); // 映射Login的多语言路由 app.MapControllerRoute( name: "LocalizedLogin", pattern: "{culture:culture=en|it}/login", defaults: new { controller = "Account", action = "Login" }); // 映射ChangePassword的多语言路由(区分英文/意大利语路径) app.MapControllerRoute( name: "LocalizedChangePasswordEn", pattern: "en/change-password", defaults: new { controller = "Account", action = "ChangePassword", culture = "en" }); app.MapControllerRoute( name: "LocalizedChangePasswordIt", pattern: "it/cambia-password", defaults: new { controller = "Account", action = "ChangePassword", culture = "it" }); // 可选:若不需要保留原有路由(如/Login),可注释掉默认路由 // app.MapControllerRoute(name: "Default", pattern: "{controller=Home}/{action=Index}/{id?}"); app.Run();
Startup.cs版本
在Configure方法的UseEndpoints中添加上述路由映射代码。
方式二:自定义路由约定(批量/复杂场景)
创建自定义路由约定类,批量修改外部控制器的路由规则:
- 定义路由约定类
public class LocalizedAccountRouteConvention : IControllerModelConvention { public void Apply(ControllerModel controller) { // 仅处理外部的AccountController if (controller.ControllerType.Name != "AccountController") return; // 清除原有路由规则(避免与新路由冲突) controller.Selectors.Clear(); // 为Login方法添加多语言路由 var loginAction = controller.Actions.First(a => a.ActionName == "Login"); loginAction.Selectors.Add(new SelectorModel { AttributeRouteModel = new AttributeRouteModel { Template = "{culture:culture=en|it}/login" } }); // 为ChangePassword方法添加分语言路由 var changePwdAction = controller.Actions.First(a => a.ActionName == "ChangePassword"); // 英文路由 changePwdAction.Selectors.Add(new SelectorModel { AttributeRouteModel = new AttributeRouteModel { Template = "en/change-password" }, RouteValues = new Dictionary<string, string> { { "culture", "en" } } }); // 意大利语路由 changePwdAction.Selectors.Add(new SelectorModel { AttributeRouteModel = new AttributeRouteModel { Template = "it/cambia-password" }, RouteValues = new Dictionary<string, string> { { "culture", "it" } } }); } }
- 注册路由约定
Program.cs版本
builder.Services.AddControllers(options => { // 添加自定义路由约定 options.Conventions.Add(new LocalizedAccountRouteConvention()); });
Startup.cs版本
在ConfigureServices的AddControllers中添加上述约定注册代码。
- 启用路由
最后在中间件管道中启用本地化和控制器路由:
// Program.cs var app = builder.Build(); app.UseRequestLocalization(); app.MapControllers(); app.Run(); // Startup.cs Configure方法 app.UseRequestLocalization(); app.UseRouting(); app.UseAuthorization(); app.UseEndpoints(endpoints => endpoints.MapControllers());
3. 验证路由效果
配置完成后,以下路由将正确映射到目标控制器方法:
/en/login、/it/login→AccountController.Login/en/change-password→AccountController.ChangePassword(文化为en)/it/cambia-password→AccountController.ChangePassword(文化为it)
内容的提问来源于stack exchange,提问作者DotCat1985
相关产品推荐
相关产品推荐

