2015-05-06 2 views
2

У меня есть существующий API. Я перехожу к WebAPI, поэтому я не могу изменять URL. Нарушение существующих клиентов не является для меня вариантом.Методы контроллера WebAPI, которые различаются по типам значений

Зная, что исходный API будет принимать либо Guid (идентификатор), либо строку (имя) для данного метода действий. Старый обработчик API расшифрует параметр URL и отправит запрос на действие контроллера, предназначенное для принятия данного типа параметра.

В качестве примера:

Get(Guid id) 

против

Get(string name) 

С WebAPI, параметр связывания жаден по типам значений, так что в зависимости от того, который первый в исходном контроллере файла, что действие тот, который вызывается. Для моих нужд это не работает. Я надеялся, что связующее будет понимать, что преобразование в Guid приведет к ошибке для имени, а затем выберите более общее строковое действие. Нет кубиков. Guid просто встречается как нулевое значение (интересно, так как это тип значения, но это то, что я получаю в отладчике в определенный момент обработки).

Так что мой вопрос в том, как лучше всего справиться с этим? Нужно ли мне дорабатывать пользовательский IHttpActionSelector? Я пробовал подход маршрутизации атрибутов (с ограничениями), но это не работает совершенно правильно (облом, как это выглядит круто). Есть ли в WebAPI механизм, который объясняет это, о котором я еще не знаю? (Я знаю, что я могу взломать его, проверив строку для Guidness и вызвав другой метод контроллера, но я надеюсь на более элегантное решение на основе WebAPI ...)

+0

'Guid' переворачивается' null'? Звучит мне подозрительно. 'string' не является типом значения. Как вы публикуете эти данные? –

+0

На самом деле это вызывает null в атрибуте, который я написал для обработки ETags, который находится в стадии разработки. Атрибут рассматривает аргументы действия маршрута для именованного параметра и не находит его. (Вы правы в том, что Guid не может на самом деле быть пустым ... Я просто не дал вам всех подробностей.) – Kenn

ответ

0

Я потратил много времени, пытаясь адаптировать маршрутизацию на основе атрибутов, но у меня нет этого для работы. Однако я решил решить эту проблему с использованием ограничений маршрута. Если вы сначала зарегистрируете более ограниченный маршрут, WebAPI (например, MVC) применит ограничения и пропустит более ограниченные маршруты до тех пор, пока не найдет тот, который он может выбрать, если таковой имеется.

Таким образом, используя мой пример, я бы настроить маршруты, как так:

_config.Routes.MapHttpRoute(name: "ById", 
    routeTemplate: "product/{id}", 
    defaults: new { controller = "ProductDetails" }, 
    constraints: new { id = @"^\{?[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12}\}?$" }); 
_config.Routes.MapHttpRoute(name: "ByName", 
    routeTemplate: "product/{name}", 
    defaults: new { controller = "ProductDetails" }); 

Первый маршрут принимает ограничение в виде регулярного выражения для Guid. Второй принимает все другие значения, а контроллер будет обрабатывать имена, не связанные с продуктом (возвращает 404). Я тестировал это на собственном сервере WebAPI, и он работает фантастически.

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

Смежные вопросы