asp.net web api route для контроллеров с таким же именем
Я интегрирую свой проект с другим
Multiple types were found that match the controller named 'XXXXX'.
This can happen if the route that services this request ('api/{controller}/{action}/{id}') found multiple controllers defined with the same name but differing namespaces, which is not supported.
The request for 'XXXXX' has found the following matching controllers:
COM.example.host.XXXXXController
COM.example.parasite.XXXXXController
Есть ли способ заставить это как-то работать с наименьшим количеством редактирования с любой стороны?
Я хотел бы избежать внесения изменений во все мои контроллеры.
Спасибо
2 ответа
К сожалению, это не очень просто, потому что селектор контроллера по умолчанию ( DefaultHttpControllerSelector) не ищет пространство имен в полном имени контроллера, когда выбирает контроллер для обработки запроса.
Итак, есть как минимум два возможных решения вашей проблемы:
- Написать свой
IHttpControllerSelector
который принимает во внимание пространство имен типа контроллера. Образец можно найти здесь. - Переименуйте один из типов контроллера, чтобы сделать его уникальным.
TL; DR Контроллер по умолчанию использует кеш типов контроллеров ( http://httpcontrollertypecache/), который содержит что-то вроде:
{
"Customers" : [
typeof(Foo.CustomersController),
typeof(Bar.CustomersController)
],
"Orders" : [
typeof(Foo.OrdersController)
]
}
Таким образом, он использует имя контроллера в качестве ключа словаря, но может содержать несколько типов, имеющих одинаковую часть имени контроллера. При получении запроса селектор контроллера получает имя контроллера из данных маршрута. Например, если у вас есть маршрут по умолчанию "api/{controller}/{id}"
тогда запрос api/customers/5
отобразит значение контроллера в "customers"
, Затем селектор контроллера получает типы контроллеров, которые зарегистрированы для этого имени:
- если есть 1 тип, то мы можем создать его экземпляр и обработать запрос
- если есть 0 типов, он бросает
NotFound
исключение - если есть 2 или более типов, он бросает
AmbiguousControllerException
исключение (ваш случай)
Итак, определение другого именованного маршрута вам не поможет, потому что вы можете указать только имя контроллера. Вы не можете указать пространство имен.
Даже если вы будете использовать маршрутизацию атрибутов и указать другой маршрут для одного из действий контроллера
[RoutePrefix("api/customers2")]
public class CustomersController : ApiController
{
[Route("")]
public IHttpActionResult Get()
//...
}
Вы по-прежнему столкнетесь с проблемой выбора контроллера, поскольку к действиям применяются атрибуты маршрутов - в данных маршрута для этих запросов не будет значения контроллера. Приписанные маршруты обрабатываются по-разному - они обрабатываются как под-маршруты "MS_attributerouteWebApi"
маршрут.
Самый простой путь для вас - добавить маршрутизацию на основе действий в ваш веб-интерфейс:
RouteTable.Routes.MapRoute(
"WithActionApi",
"api/{controller}/{action}/{id}"
);
В вашем WebApiConfig.cs обязательно поместите его выше правила по умолчанию. Затем измените способ вызова контроллеров, указав имя метода, которое на данный момент должно быть или должно быть уникальным.