Я создал одно приложение веб-API с контролем версий. Я собираюсь использовать пакет Microsoft.AspNet.WebApi.Versioning
для этого.
Конфигурация Webapi:
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 в качестве кода состояния.
{
«Сообщение»: «Произошла ошибка.»,
«ExceptionMessage»: «Индекс не может быть меньше 0 или равен или больше количества элементов в коллекции. \ R \ n
Параметр
name: index \ r \ nАктуальное значение было 0. ",
"ExceptionType": "System.ArgumentOutOfRangeException",
"StackTrace": "в
System.Web.Http.WebHost.Routing.HostedHttpRouteCollection.get_Item (Int32
индекс) \ r \ n в
Microsoft.Web.Http.Dispatcher.ApiVersionControllerSelector.GetControllerName (HttpRequestMessage
запрос) \ r \ n в
Microsoft.Web.Http.Dispatcher.ControllerSelectionContext. <> C__DisplayClass6_0. <. Т е р> b__0 () \ г \ п
в System.Lazy 1.CreateValue()\r\n at
System.Lazy
1.LazyInitValue () \ r \ n в System.Lazy`1.get_Value () \ r \ n
в
Microsoft.Web.Http.Dispatcher.ConventionRouteControllerSelector.SelectController (ControllerSelectionContext
контекст) \ r \ n в
Microsoft.Web.Http.Dispatcher.ApiVersionControllerSelector.SelectController (HttpRequestMessage
запрос) \ r \ n в
System.Web.Http.Dispatcher.HttpControllerDispatcher.d__15.MoveNext ()»
}
Обновление 1:
После обсуждений и небольшой помощи я могу подтвердить, что эта версия по умолчанию работает с обычной маршрутизацией.
Проблема воспроизводится при использовании атрибута маршрутизации. Пожалуйста, проверьте мой обновленный код.
- У меня нет никакой стандартной API-маршрутизации в файле WebAPIConfig.
- Я обновляю Route Prefix и Route в контроллере
Теперь вопрос воспроизведен.
Вы также можете воспроизвести проблему с сочетанием обычного и атрибута.
Обновление 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. Так что я не знаю, может ли это повлиять на любые другие функции
Так что, если я настрою Овина для использования webaPI вместо GlobalConfiguration.Configure (WebApiConfig.Register) в Global.asax, он будет работать нормально.