Web Api Routing: найдено несколько типов контроллеров, соответствующих URL-адресу для константных путей параметра VS - PullRequest
0 голосов
/ 12 января 2020

Моя проблема похожа на Маршрутизация веб-API: найдено несколько типов контроллеров, соответствующих URL-адресу , но я хочу сохранить их в отдельных контроллерах.

Из комментариев: 2 предыдущих ответа хорошие обходные пути, но не решают реальную проблему, которую я пытаюсь решить.

URL-адреса, которые я составляю, похожи на вложенные каталоги в файловой системе ИЛИ очень похожи на URL-адреса Firebase.

/BiggestSet/{BiggestSetCode}/Subset1/{Subset1Code}/SubsetOfSubset1/{SubsetOfSubset1}

... et c полностью вниз туда, где когда-либо дерево останавливается. Думайте об этом как о дереве данных.

/Collection/{Instance}/Collection/{Instance}

Проблема, с которой я столкнулся, заключается в том, что на уровне / Collection я также хочу предоставить определенные c операции уровня сбора. Например, Добавить, выполнить поиск и указать другие коллекции. c Операции Collection / ProccessData

Collection Controller:
/Collection/Add 
/Collection/ProcessDataOnTheColleciton

Instance Controller:
/Collection/{InstanceCode}
/Collection/{InstanceCode}/ProcessOnTheInstance

Проблема, с которой я столкнулся, заключается в столкновении Collection / ProcessData с экземпляром Collection / {InstanceCode}

ПРИМЕЧАНИЕ: 1 является параметром, а другой - константой.

Если вы настраиваете контроллеры так, чтобы набор и экземпляр находились в одном контроллере. / {InstanceCode} не обрабатывает sh с / ProcessData

НО

Если вы настроили так, чтобы контроллеры были разделены на логические функции, WebAPI выдает ошибку. Было найдено несколько типов контроллеров, которые сопоставьте URL.

Кто-нибудь знает, как изменить маршрутизацию атрибутов, чтобы они как-то вели себя так, как если бы они находились в одном контроллере, ИЛИ для определения приоритета константы над параметром на контроллерах?

1 Ответ

1 голос
/ 16 января 2020

Чтобы сохранить два отдельных контроллера и по-прежнему иметь такие маршруты, вы можете использовать ограничения маршрутов регулярных выражений. Таким образом, вы можете указать для instanceCode, что вы принимаете все, кроме действий от другого контроллера.

Вот пример того, как настроить такие маршруты:

public class CollectionController : ApiController
{
   [HttpGet]
   [Route("Collection/Add")]
   public string Add()
   {
      return $"CollectionController = Collection/Add";
   }

   [HttpGet]
   [Route("Collection/Process")]
   public string Process()
   {
      return $"CollectionController = Collection/Process";
   }
}

public class InstanceController : ApiController
{
   [HttpGet]
   [Route("Collection/{instanceCode:regex(^(?!Add$|Process$).*)}")]
   public string Get(string instanceCode)
   {
      return $"InstanceController = Collection/{instanceCode}";
   }

   [HttpGet]
   [Route("Collection/{instanceCode:regex(^(?!Add$|Process$).*)}/Process")]
   public string Process(string instanceCode)
   {
      return $"InstanceController = Collection/{instanceCode}/Process";
   }
}

Вот также ссылка на пост , в котором объясняется регулярное выражение , используемое в примере.

Еще лучшим вариантом будет наличие заданного формата c для instanceCode и установка регулярное выражение для принятия только этого указанного c формата. Тогда вам не нужно будет изменять регулярное выражение для каждого нового добавленного действия. Я также включил ссылку на документацию для всех доступных ограничений маршрута . Там вы можете увидеть все доступные варианты. Например, если ваш код экземпляра является числом, вам даже не нужно регулярное выражение, которое вы можете просто ограничить с помощью ограничения int, например: [Route("Collection/{instanceCode:int}")].

...