使用aspnet-api-versioning持续触发AmbiguousMatchException问题求助
问题原因与修复方案
核心问题
你的代码中API版本配置不完整,AddApiVersioning().AddMvc()的写法不适用于最新的Asp.Versioning包,导致版本识别逻辑未正确生效,路由系统无法区分两个版本的/v{version}/hello端点,从而抛出AmbiguousMatchException。
具体修复步骤
1. 修正服务配置
替换原有的API版本配置,补充版本读取规则与MVC版本支持逻辑:
builder.Services.AddControllers(); builder.Services.AddApiVersioning(options => { // 指定从URL路径提取版本号(匹配路由中的v{version:apiVersion}) options.ApiVersionReader = new UrlSegmentApiVersionReader(); // 允许未指定版本的请求使用默认版本 options.AssumeDefaultVersionWhenUnspecified = true; options.DefaultApiVersion = new ApiVersion(1, 0); }) .AddMvc(options => { // 确保版本约束被路由系统正确识别 options.Conventions.Add(new VersionByNamespaceConvention()); }) .AddApiExplorer(options => { // 可选:为API文档生成规范版本分组(推荐配置) options.GroupNameFormat = "'v'VVV"; options.SubstituteApiVersionInUrl = true; });
2. 控制器代码无需修改
你现有的控制器路由写法是正确的,保留即可:
[ApiVersion("1.0"), Route("v{version:apiVersion}/hello")] public class HelloV1Controller : ControllerBase { [HttpGet] public string Get() => "v1"; } [ApiVersion("2.0"), Route("v{version:apiVersion}/hello")] public class HelloV2Controller : ControllerBase { [HttpGet] public string Get() => "v2"; }
3. 完整修正后的代码
using Asp.Versioning; using Asp.Versioning.Conventions; using Microsoft.AspNetCore.Mvc; internal class Program { private static void Main(string[] args) { var builder = WebApplication.CreateBuilder(args); builder.Services.AddControllers(); builder.Services.AddApiVersioning(options => { options.ApiVersionReader = new UrlSegmentApiVersionReader(); options.AssumeDefaultVersionWhenUnspecified = true; options.DefaultApiVersion = new ApiVersion(1, 0); }) .AddMvc(options => { options.Conventions.Add(new VersionByNamespaceConvention()); }) .AddApiExplorer(options => { options.GroupNameFormat = "'v'VVV"; options.SubstituteApiVersionInUrl = true; }); var app = builder.Build(); app.MapControllers(); app.Run(); } } [ApiVersion("1.0"), Route("v{version:apiVersion}/hello")] public class HelloV1Controller : ControllerBase { [HttpGet] public string Get() => "v1"; } [ApiVersion("2.0"), Route("v{version:apiVersion}/hello")] public class HelloV2Controller : ControllerBase { [HttpGet] public string Get() => "v2"; }
修复原理
UrlSegmentApiVersionReader明确告知版本服务从URL路径中提取版本标识,让路由系统能区分不同版本的端点。VersionByNamespaceConvention确保MVC框架正确关联控制器与对应版本,避免路由歧义。- 完整的配置让API版本服务与MVC路由系统协同工作,不会再将两个版本的控制器路由判定为重复端点。
内容的提问来源于stack exchange,提问作者Joep Geevers
相关产品推荐
相关产品推荐

