我创建了一个版本化的Web API应用程序。我将使用Microsoft.AspNet.WebApi.Versioning
包来完成此操作。
Web API配置:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
config.AddApiVersioning(o => {
o.AssumeDefaultVersionWhenUnspecified = true;
});
// Web API routes
config.MapHttpAttributeRoutes();
}
}
我会尽力满足您的需要,以下为您翻译的内容:
我的假设是如果我没有传递版本信息,默认将选择版本1。
控制器代码:
[ApiVersion("1.0")]
[RoutePrefix("api/users")]
public class UserV1Controller : BaseController
{
public UserV1Controller()
{
}
[Route("all", Name = "UsersCollection")]
public async Task<IHttpActionResult> GetAll()
{
var items = await UnitOfWork.Users.GetPaged(x => x.OrderBy(y => y.Id), 1, 20);
//Add mapping to DTO
return Ok(items);
}
}
如果我使用
http://localhost:10280/api/users/all?api-version=1.0
URL进行测试,它可以正常工作。我将在现有项目中实现此功能。为了实现向后兼容性,我尝试了
http://localhost:10280/api/users/all
URL。
这会给我带来以下错误,状态代码为500。{ "Message": "发生错误。", "ExceptionMessage": "索引不能小于0或等于集合中的项目数,也不能大于该数。\r\n参数名称: 索引\r\n实际值为 0。", "ExceptionType": "System.ArgumentOutOfRangeException", "StackTrace": " at System.Web.Http.WebHost.Routing.HostedHttpRouteCollection.get_Item(Int32 index)\r\n at Microsoft.Web.Http.Dispatcher.ApiVersionControllerSelector.GetControllerName(HttpRequestMessage request)\r\n at Microsoft.Web.Http.Dispatcher.ControllerSelectionContext.<>c__DisplayClass6_0.<.ctor>b__0()\r\n at System.Lazy`1.CreateValue()\r\n at System.Lazy`1.LazyInitValue()\r\n at System.Lazy`1.get_Value()\r\n at Microsoft.Web.Http.Dispatcher.ConventionRouteControllerSelector.SelectController(ControllerSelectionContext context)\r\n at Microsoft.Web.Http.Dispatcher.ApiVersionControllerSelector.SelectController(HttpRequestMessage request)\r\n at System.Web.Http.Dispatcher.HttpControllerDispatcher.d__15.MoveNext()" }
更新1:
经过讨论和一些帮助,我确认这个默认版本适用于传统的路由方式。
在使用属性路由时出现了问题,请检查我的更新代码。
1.在WebAPIConfig文件中没有默认的API路由。 2.我更新了控制器中的路由前缀和路由。
现在问题已经复现。
您还可以通过结合传统路由和属性来复现此问题。
更新2:
现在我注意到该问题在配置中。如果我直接在Owin启动类中添加路由配置,则可以正常工作。
public partial class Startup
{
public void Configuration(IAppBuilder app)
{
ConfigureAuth(app);
var configuration = new System.Web.Http.HttpConfiguration();
var httpServer = new System.Web.Http.HttpServer(configuration);
// reporting api versions will return the headers "api-supported-versions" and "api-deprecated-versions"
configuration.AddApiVersioning(options =>
{
options.ReportApiVersions = true;
options.AssumeDefaultVersionWhenUnspecified = true;
});
configuration.MapHttpAttributeRoutes();
app.UseWebApi(httpServer);
}
}
它创建了一个新的HttpConfiugration,而不是使用我们现有的WebAPIConfig类。因此,我不知道它可能会影响其他功能。
所以,如果我在Global.asax中配置Owin使用webaPI,而不是使用GlobalConfiguration.Configure(WebApiConfig.Register),它可以正常工作。
[RoutePrefix("api/users")]
?因为这会导致我的本地项目出错。如果我删除第二个控制器或其路由前缀,则错误会消失。这是很自然的,因为对于两个不同的控制器,不能有两个相同的路由。 - Marco