.NET Framework 4.8 Web API版本控制配置失效求助
.NET Framework 4.8 Web API版本控制故障排查
问题背景
开发.NET Framework 4.8 Web API项目时,尝试为REST API端点启用版本控制,但所有端点均无法正常响应,请求返回资源未找到或版本未指定的错误。
控制器代码
namespace Testproject1.Controllers { using Testproject.Controllers.Models; using Asp.Versioning; using System.Web.Http; [ApiVersion(1.0)] [Route("api/v{version:apiVersion}/[controller]")] public class AgreementsController: ApiController { [Route("{accountId}")] public IHttpActionResult Get(string accountId) => Ok(new Agreement(GetType().FullName, accountId, "1")); } } namespace Testproject1.Controllers { using Testproject.Controllers.Models; using Asp.Versioning; using System.Web.Http; [ApiVersion(2.0)] [Route("api/v{version:apiVersion}/[controller]")] public class AgreementsControllerv2 : ApiController { [Route("{accountId}")] public IHttpActionResult Get(string accountId) => Ok(new Agreement(GetType().FullName, accountId, "2")); } } namespace Testproject1.Controllers.V1 { using Testproject.Controllers.Models; using Asp.Versioning; using System.Web.Http; [ApiVersion(2.0)] [Route("api/v{version:apiVersion}/[controller]")] public class OrdersController : ApiController { // GET ~/v1/orders/{accountId} [Route("{accountId}")] public IHttpActionResult Get(string accountId) => Ok(new Order(GetType().FullName, accountId, "1")); } }
Startup配置代码
var configuration = new HttpConfiguration(); var httpServer = new HttpServer(configuration); configuration.MapHttpAttributeRoutes(); configuration.AddApiVersioning( options => { options.ReportApiVersions = true; options.DefaultApiVersion = new ApiVersion(1, 0); options.AssumeDefaultVersionWhenUnspecified = true; options.ApiVersionReader = new UrlSegmentApiVersionReader(); }); configuration.Routes.MapHttpRoute( name: "VersionedApi", routeTemplate: "api/v{version:apiVersion}/{controller}/{id}", defaults: new { id = RouteParameter.Optional, version = RouteParameter.Optional }); builder.UseWebApi(httpServer);
错误响应
- 版本1请求:
http://localhost:9999/api/v1.0/agreements/1
{ "消息": "未找到与请求URI 'http://localhost:9999/api/v2.0/agreements/1' 匹配的HTTP资源。", "消息详情": "在控制器 'Agreements' 上未找到与请求匹配的操作。" }
- 版本2请求:
http://localhost:9999/api/v2.0/agreements/1
{ "消息": "未找到与请求URI 'http://localhost:9999/api/v1.0/agreements/1' 匹配的HTTP资源。", "消息详情": "在控制器 'Agreements' 上未找到与请求匹配的操作。" }
- Orders请求:
http://localhost:9999/api/v2.0/orders/1
{ "代码": "ApiVersionUnspecified", "跟踪ID": "776cf174-79ab-4386-a856-2f385f5f51ca", "类型": "https://docs.api-versioning.org/problems#unspecified", "标题": "未指定API版本", "状态码": 400, "详情": "需要API版本,但未指定。" }
问题分析与修复方案
1. Startup配置顺序错误
API版本控制的配置必须在属性路由映射之前执行,否则版本读取器无法正确解析属性路由中的{version:apiVersion}参数。
修复:调整Startup代码顺序,先配置API版本控制,再映射属性路由:
var configuration = new HttpConfiguration(); var httpServer = new HttpServer(configuration); // 先配置API版本控制 configuration.AddApiVersioning( options => { options.ReportApiVersions = true; options.DefaultApiVersion = new ApiVersion(1, 0); options.AssumeDefaultVersionWhenUnspecified = true; options.ApiVersionReader = new UrlSegmentApiVersionReader(); }); // 再映射属性路由 configuration.MapHttpAttributeRoutes(); configuration.Routes.MapHttpRoute( name: "VersionedApi", routeTemplate: "api/v{version:apiVersion}/{controller}/{id}", defaults: new { id = RouteParameter.Optional, version = RouteParameter.Optional }); builder.UseWebApi(httpServer);
2. AgreementsControllerv2控制器路由解析错误
控制器类名为AgreementsControllerv2,路由中的[controller]会自动解析为AgreementsControllerv2,导致请求api/v2.0/agreements/1无法匹配到该控制器。
修复:给AgreementsControllerv2添加[ControllerName]属性,指定控制器的路由名称为Agreements:
[ApiVersion(2.0)] [ControllerName("Agreements")] // 添加此属性 [Route("api/v{version:apiVersion}/[controller]")] public class AgreementsControllerv2 : ApiController { [Route("{accountId}")] public IHttpActionResult Get(string accountId) => Ok(new Agreement(GetType().FullName, accountId, "2")); }
3. OrdersController版本与路由匹配问题
OrdersController标记了[ApiVersion(2.0)],但之前的Startup顺序错误导致版本读取器无法识别URL中的版本参数,修复Startup顺序后即可解决"未指定API版本"的错误。
验证修复
调整后重新运行项目,测试以下请求:
http://localhost:9999/api/v1.0/agreements/1:应返回AgreementsController的响应http://localhost:9999/api/v2.0/agreements/1:应返回AgreementsControllerv2的响应http://localhost:9999/api/v2.0/orders/1:应返回OrdersController的响应
内容的提问来源于stack exchange,提问作者user1258028
相关产品推荐
相关产品推荐

