Управление версиями Web-API не работает с версией по умолчанию - PullRequest
0 голосов
/ 02 января 2019

Я создал одно приложение веб-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:

После обсуждений и небольшой помощи я могу подтвердить, что эта версия по умолчанию работает с обычной маршрутизацией.

Проблема воспроизводится при использовании атрибута маршрутизации. Пожалуйста, проверьте мой обновленный код.

  1. У меня нет никакой стандартной API-маршрутизации в файле WebAPIConfig.
  2. Я обновляю 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, он будет работать нормально.

Ответы [ 3 ]

0 голосов
/ 02 января 2019

Вы можете попытаться установить номер версии по умолчанию и настроить промежуточное ПО для его использования, когда номер версии не указан.

Ссылка: Блог Скотта о маршрутизации

services.AddApiVersioning(
    o =>
    {
        o.AssumeDefaultVersionWhenUnspecified = true );
        o.DefaultApiVersion = new ApiVersion("1.0");
    } );
0 голосов
/ 04 января 2019

Это подтвержденная ошибка, которая возникает только при размещении на ванильной реализации IIS (например, не OWIN).Несмотря на то, что HttpRouteCollection имеет индексатор, HostedHttpRouteCollection , определенный System.Web, не поддерживает его.Вместо NotSupportedException генерируется универсальное ArgumentOutOfRangeException .

Подробнее см .: https://github.com/Microsoft/aspnet-api-versioning/issues/428.

Исправление включено и теперь доступно в версии пакета 3.0.1 .

0 голосов
/ 02 января 2019

Если вы не укажете версию, она считается неверсионной.В этом случае вы должны установить свойство AssumeDefaultVersionWhenUnspecified, которое, если не указано иное, предполагает версию по умолчанию "1.0", если ничего не указано:

config.AddApiVersioning(o => {
    o.AssumeDefaultVersionWhenUnspecified = true;
});

Эта функциональность документирована здесь: https://github.com/Microsoft/aspnet-api-versioning/wiki/Existing-Services-Quick-Start

...