15

Я пытаюсь включить управление версиями в REST API, где версия указана в заголовке, как "api-version":2.Реализация атрибута VersionedRoute для MVC6

По this tutorial мне просто нужно создать

VersionConstraint : IHttpRouteConstraint

и

VersionedRoute: RouteFactoryAttribute

Использование было бы применить [VersionedRoute("api/controllerName", 2)] атрибут для контроллеров, которые предназначены для конкретных версий (например, версия 2 в этом случае).

Это все хорошо и хорошо, но, к сожалению, все это в MVC5, и я использую MVC6. Поэтому RouteFactoryAttribute и IHttpRouteConstraint не работают.

Мне удалось найти IRouteConstraint на замену IHttpRouteConstraint (надеюсь, что это сработает), но я не могу найти замену для RouteFactoryAttribute.

Если кто-либо может предоставить образец этого с использованием MVC 6 или, по крайней мере, указать правильные классы (в идеале, с пространствами имен), мне нужно наследовать?

+1

Взгляните на это и посмотреть, если она соответствует вашим потребностям: https://github.com/aspnet/Mvc/blob/dev/test/WebSites/VersioningWebSite/VersionRoute.cs # L11 –

+0

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

+0

Поскольку это новая структура, не может быть взаимно однозначного сопоставления между apis. Конечно, вы можете попробовать выяснить, есть ли более простой подход с новым api. –

ответ

8

Вот минимальный объем работы, в которой вы нуждаетесь.

Во-первых, идти there и скопировать код для 3 следующих файлов:

После того как вы это, мы изменим GetVersion метод VersionRangeValidator для:

public static string GetVersion(HttpRequest request) 
{ 
    if (!string.IsNullOrWhiteSpace(request.Headers["api-version"])) 
     return request.Headers["api-version"]; 

    return "1"; 
} 

Это будет читать заголовок и возвращать версию API. В этом случае по умолчанию будет v1.

Вот как использовать его на контроллерах (или это может быть тот же контроллер с 2 действия:

[Route("api/data")] 
public class DataController 
{ 
    [VersionGet("", versionRange: "[1]")] 
    public string GetData() 
    { 
     return "v1 data"; 
    } 
} 

[Route("api/data")] 
public class DataV2Controller 
{ 
    [VersionGet("", versionRange: "[2]")] 
    public string GetData() 
    { 
     return "v2 data"; 
    } 
} 

Так что теперь вам просто нужно дать ему правильный заголовок, и это хорошо Этот код был. протестирована с JQuery, как это:

$(document).ready(function(){ 
    $.ajax({url: '/api/Data/', headers: { 'api-version': 1 }}) 
    .then(function(data){ 
      alert(data); 
      }); 
    $.ajax({url: '/api/Data/', headers: { 'api-version': 2 }}) 
    .then(function(data){ 
      alert(data); 
      }); 
}); 
+0

В вашем примере вы упомянули, что один и тот же контроллер может иметь 2 действия для разных версий. Я тестировал это, и он работает хорошо, но если '' 'api-version''' не соответствует никаким, например:' '' api-version: 3''', маршрутизация найдет двусмысленный маршрут, так как есть 2 HttpGet Actions с той же сигнатурой, и она выдает ошибку: '' 'AmbiguousActionException: несколько действий согласованы. Следующие действия соответствовали данным маршрута и были выполнены все ограничения '' '. Любые рекомендации относительно того, как справиться с этим сценарием? Параметр '' 'Order''' не имеет никакого значения для определения того, какое действие является предпочтительным. Thx – iberodev

+0

Вам нужно будет изменить код, который был указан в примере, но для меня это будет всегда предоставление обработчика по умолчанию. Я, к сожалению, не пробовал этот сценарий, и я не смогу дать вам ответ до 2016 года. В настоящее время у меня нет VS2015, установленного на этом компьютере. :( –

+0

Если мой ответ, однако, соответствует вашему первоначальному вопросу, пожалуйста, найдите время, чтобы отметить его как ответ. :) –