ASP.NET Core 2.0路由集成API版本控制与本地化遇404问题求助
解决ASP.NET Core 2.0中API版本控制与本地化路由共存的404问题
你的问题根源在于路由中间件的嵌套配置和Mvc路由系统的冲突:外层的UseRouter捕获了api/{culture}开头的请求,但内部用UseMvcWithDefaultRoute加载的是默认路由模板,和你控制器上带版本号的路由完全不匹配;同时API版本控制的apiVersion参数也没被外层中间件正确传递给Mvc,自然就返回404了。
下面是修正后的完整方案:
1. 调整服务配置(ConfigureServices)
把本地化选项和API版本控制直接集成到Mvc的服务体系中,不需要额外的外层路由中间件:
public void ConfigureServices(IServiceCollection services) { // 配置本地化资源路径 services.AddLocalization(x => x.ResourcesPath = "Resources"); // 配置API版本控制 services.AddApiVersioning(opt => { opt.ReportApiVersions = true; opt.AssumeDefaultVersionWhenUnspecified = true; opt.DefaultApiVersion = new ApiVersion(1, 0); }); // 配置请求本地化选项,指定支持的文化并添加路由数据提供者 services.Configure<RequestLocalizationOptions>(options => { var supportedCultures = new[] { new CultureInfo("en"), new CultureInfo("ru"), new CultureInfo("en-US") // 匹配控制器默认的culture值 }; options.DefaultRequestCulture = new RequestCulture("en-US"); options.SupportedCultures = supportedCultures; options.SupportedUICultures = supportedCultures; // 优先从路由的{culture}参数获取请求文化 options.RequestCultureProviders.Insert(0, new RouteDataRequestCultureProvider { RouteDataStringKey = "culture", Options = options }); }); // 添加Mvc并启用本地化支持 services.AddMvc() .AddViewLocalization() .AddDataAnnotationsLocalization(); }
2. 调整请求管道配置(Configure)
移除多余的UseRouter中间件,先启用请求本地化,再配置Mvc路由模板,让它同时支持culture和apiVersion参数:
public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } // 先应用请求本地化配置 var localizationOptions = app.ApplicationServices.GetRequiredService<IOptions<RequestLocalizationOptions>>().Value; app.UseRequestLocalization(localizationOptions); // 配置Mvc路由,整合culture和API版本参数 app.UseMvc(routes => { routes.MapRoute( name: "versioned-local-api", template: "api/{culture=en-US}/v{version:apiVersion}/{controller}/{action=Get}/{id?}"); }); }
3. 保持控制器路由不变(可选)
你的控制器路由可以继续使用原来的模板,它会和全局路由模板兼容:
[ApiVersion("1")] [Route("api/{culture=en-US}/v{version:apiVersion}/[controller]")] public class ValuesController : Controller { private readonly IStringLocalizer<ValuesController> _localizer; public ValuesController(IStringLocalizer<ValuesController> localizer) { _localizer = localizer; } [HttpGet] public IActionResult Get() { var result = $"{_localizer["Title"].Value}"; return Ok(result); } }
关键修正点说明
- 移除嵌套路由中间件:原来的
UseRouter会拦截请求并重新转发,导致Mvc无法正确解析API版本控制的路由参数,直接用Mvc的路由系统就能同时处理culture和apiVersion。 - 路由优先的文化提供者:通过
RouteDataRequestCultureProvider让系统优先从路由的{culture}参数获取语言设置,而不是默认的Cookie/Header等方式。 - 统一路由参数:确保全局路由模板和控制器路由的参数名称、默认值一致,避免匹配偏差。
现在你可以测试这些请求:
GET /api/en-US/v1/values:返回en-US本地化内容GET /api/ru/v1/values:返回俄语本地化内容GET /api/v1/values:因为culture有默认值en-US,所以会自动匹配到默认文化
内容的提问来源于stack exchange,提问作者SetSun
相关产品推荐
相关产品推荐

