Странное поведение маршрутизации атрибутов в ApiController
-
22-12-2019 - |
Вопрос
Я использую маршрутизацию атрибутов, чтобы указать свои маршруты в контроллере, который наследуется от System.Web.Http.ApiController.У меня какое-то странное поведение.Вот пример кода:
[RoutePrefix("api/1/user")]
public class UserRestController : ApiController
{
UserService userService = new UserService();
[Route("{id}"), HttpGet]
public UserDTO Get(string id)
{
var user = userService.GetUserById(id);
return user;
}
}
Это работает абсолютно так, как я ожидал.Когда я посещаю ~/api/1/user/someId, я получаю обратно ожидаемую информацию.Когда я переключаюсь, чтобы не включать «1» в префикс маршрута, я получаю сообщение «Не найден HTTP-ресурс, соответствующий URI запроса «baseUrl/api/user/someId».
У меня есть маршруты mvc, маршруты веб-API и маршруты атрибутов, которые регистрируются при запуске приложения в этом проекте, но я думаю, что маршруты по умолчанию для этого контроллера будут ~/userrest/...поэтому я бы не думал, что их регистрация станет причиной этого, но я могу ошибаться.
Пример того, что я хочу:
[RoutePrefix("api/user")]
public class UserRestController : ApiController
{
UserService userService = new UserService();
[Route("{id}"), HttpGet]
public UserDTO Get(string id)
{
var user = userService.GetUserById(id);
return user;
}
}
Я ожидаю, что ~/api/user/someId будет работать, однако я получаю упомянутую выше ошибку («Не найден HTTP-ресурс, соответствующий URI запроса 'baseUrl/api/user/someId'»).
Полный XML-код ошибки:
<Error>
<Message>
No HTTP resource was found that matches the request URI
'baseUrl/api/user/someId';.
</Message>
<MessageDetail>
No type was found that matches the controller named 'user'.
</MessageDetail>
</Error>
Решение
Судя по описанию ошибки, вы, похоже, зарегистрировали обычные маршруты перед вызовом MapHttpAttributeRoutes.Например, у вас может быть маршрут типа config.Routes.MapHttpRoute("DefaultApi", "api/{controller}/{id}"...)
.В этом случае запрос типа api/user/someid
будет соответствовать этому маршруту, и веб-API будет искать контроллер типа UserController
.Обязательно позвоните MapHttpAttributeRoutes
перед этим обычным маршрутом.
Основное правило:более конкретные маршруты следует регистрировать перед менее конкретными или общими маршрутами.