@ Саджид был в основном правильно. При версии по сегменту URL необходимо использовать ограничение маршрута версии API. В игре есть пара вопросов. Похоже, вы переходите от неверсированного API к версионному API, что является поддерживаемым сценарием. Приведенные вами примеры значений не совпадают. Похоже, вы идете от v1
до v10
. Значения не имеют значения, но следует понимать, что ваш существующий API имеет некоторое логическое имя, даже если вы никогда ранее не присваивали ему значение.
Проблема 1
Вы не сделали Не указывайте настройки, но это должно быть что-то вроде:
var constraintResolver = new DefaultInlineConstraintResolver()
{
ConstraintMap = { ["apiVersion"] = typeof( ApiVersionRouteConstraint ) }
};
configuration.MapHttpAttributeRoutes( constraintResolver );
configuration.AddApiVersioning(
options =>
{
// required because the original API doesn't have a version in the URL
options.AssumeDefaultVersionWhenUnspecified = true;
// this is already the default value, but you might need to change it.
// this is the value that will be 'assumed' by the original, unversioned
// API. it is addressable by /api/products. if you meant to start at 1.0,
// then you can use a lower value such as 0.9
options.DefaultApiVersion = new ApiVersion(1, 0);
});
Проблема 2
Маркер [controller]
не поддерживается в Web API. Эта концепция, наряду с [action]
, была введена в ASP. NET Базовая маршрутизация.
Вы не полностью уяснили, как вы решили проблему, но Ваши изменения почти наверняка подскажут, как смешивание стилей может сбивать с толку. Неясно, соответствовал ли API маршруту атрибута или маршруту на основе соглашения.
Проблема 3
Ваш шаблон маршрута не включает ограничение маршрута версии API (для получения информации о регистрации см. Проблема 1) , Это необходимо для того, чтобы API Versioning знал , как извлечь версию API из URL. Управление версиями API не делает волхвы c строка парсинг с регулярными выражениями, et c.
Шаблон должен быть: [RoutePrefix("api/v{version:apiVersion}/products")]
, как указано @ Sajid. Имейте в виду, что литерал v
не является частью версии API, но распространен в методе управления версиями сегмента URL. version
- это имя параметра маршрута, но может быть любым желаемым значением. apiVersion
является ключом зарегистрированного ограничения маршрута, но вы можете изменить его в шаблоне, если вы также измените его в регистрации (см. Выпуск 1).
Выпуск 4
Аннотированный Версия API 1.0
, но шаблон маршрута, похоже, подразумевает, что вы имели в виду 10.0
. Вы можете использовать любое значение, которое хотите, но оно должно быть конгруэнтным. Если вы действительно хотите использовать 1.0
, не забудьте изменить options.DefaultApiVersion
, иначе вы получите исключение времени выполнения, потому что исходный API и ваш новый API будут считаться дубликатами, поскольку они имеют одинаковую версию API. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * [10] * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}}}}. не рекомендуется смешивать стили маршрутизации. Это поддерживается, но это может сбивать с толку устранение неполадок и для сопровождающих. Я бы выбрал либо Прямая маршрутизация (он же Маршрутизация с атрибутом ), либо Маршрутизация на основе конвенций . В некоторых случаях их смешивание не работает, но они редки.
Это означает, что следует выбрать один из следующих вариантов:
Маршрутизация атрибутов
// setup (see Issue 1)
configuration.MapHttpAttributeRoutes( constraintResolver );
// old controller
[RoutePrefix("api/products")]
public class ProductsController : ApiController { }
// new controller; ControllerNameAttribute isn't need because it's not used
[ApiVersion("10.0")]
[RoutePrefix("api/v{version:apiVersion}/products")]
public class ProductsV1Controller : ApiController { }
Маршрутизация на основе конвенций
// setup
httpConfig.Routes.MapHttpRoute(
name: "VersionedApi",
routeTemplate: "api/v{apiVersion}/{controller}/{id}",
defaults: new { id = RouteParameter.Optional },
constraints: new { apiVersion = new ApiVersionRouteConstraint() });
httpConfig.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional },
constraints: null);
// old controller
public class ProductsController : ApiController { }
// new controller
[ApiVersion("10.0")]
[ControllerName("Products")] // required because the convention-based name is "ProductsV1"
public class ProductsV1Controller : ApiController { }
Предупреждение. Вы можете смешивать эти стили, но устранение неполадок станет более сложным. Вам нужно обширное тестовое покрытие, чтобы убедиться, что все правильно. Одноразовое ручное тестирование может дать ложные срабатывания.
Надеюсь, это поможет