Как обрабатывать иерархические маршруты в ASP.NET Web API?
В настоящее время у меня есть два контроллера
1 - родительский контроллер
2 - Ребенок-контроллер
Я обращаюсь к своему родительскому контроллеру, как это
someurl\parentcontroller
Теперь я хочу получить доступ к моему контроллеру для детей, подобному этому
someurl\parentcontroller\1\childcontroller
Этот последний url должен возвращать все дочерние элементы определенного родителя.
У меня есть этот маршрут в моем файле global.asax
routes.MapHttpRoute ("Route1", "{controller}/{id}", new { id = RouteParameter.Optional });
Я не уверен, как я могу достичь своей иерархии parent\id\child
. Как мне настроить маршруты для этого? Идеи?
Ответы
Ответ 1
Настройте маршруты, как показано ниже. Параметр необязателен (используйте, если вам нужно):
routes.MapHttpRoute(
name: "childapi",
routeTemplate: "api/Parent/{id}/Child/{param}",
defaults: new { controller = "Child", param = RouteParameter.Optional }
);
routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
Затем вызовите дочернего APi как /api/Parent/ 1/child
Родитель можно называть простым как /api/Parent/
Детский контроллер:
public class ChildController : ApiController
{
public string Get(int id)
{
//the id is id between parent/{id}/child
return "value";
}
.......
}
Ответ 2
Так как Web API 2 теперь можно использовать атрибуты маршрута для определения настраиваемой маршрутизации для каждого метода,
[Route("api/customers/{id:guid}/orders")]
public IEnumerable<Order> GetCustomerOrders(Guid id) {
return new Order[0];
}
Вам также нужно добавить следующую строку в метод инициализации WebApiConfig.Register(),
config.MapHttpAttributeRoutes();
Полная статья,
http://www.asp.net/web-api/overview/web-api-routing-and-actions/attribute-routing-in-web-api-2
Ответ 3
Я хотел бы обработать это более общим способом, вместо того, чтобы подключать ChildController непосредственно к controller = "Child"
, как это сделал Абхижит Кадам. У меня есть несколько дочерних контроллеров и вам не нужно отображать конкретный маршрут для каждого из них с controller = "ChildX"
и controller = "ChildY"
снова и снова.
Мой WebApiConfig
выглядит следующим образом:
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
config.Routes.MapHttpRoute(
name: "ChildApi",
routeTemplate: "api/{parentController}/{parentId}/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
Мои родительские контроллеры являются очень стандартными и соответствуют указанному выше маршруту по умолчанию. Образец дочернего контроллера выглядит следующим образом:
public class CommentController : ApiController
{
// GET api/product/5/comment
public string Get(ParentController parentController, string parentId)
{
return "This is the comment controller with parent of "
+ parentId + ", which is a " + parentController.ToString();
}
// GET api/product/5/comment/122
public string Get(ParentController parentController, string parentId,
string id)
{
return "You are looking for comment " + id + " under parent "
+ parentId + ", which is a "
+ parentController.ToString();
}
}
public enum ParentController
{
Product
}
Некоторые недостатки моей реализации
- Как вы можете видеть, я использовал
enum
, поэтому мне все еще нужно управлять родительскими контроллерами в двух разных местах. Он мог бы так же легко быть строковым параметром, но я хотел предотвратить работу api/crazy-non-existent-parent/5/comment/122
.
- Вероятно, есть способ использовать отражение или что-то сделать это на лету, не управляя им отдельно, но это работает для меня пока.
- Он не поддерживает детей детей.
Вероятно, лучшее решение, которое еще более общее, но, как я уже сказал, это работает для меня.
Ответ 4
Опция, не использующая маршрутизацию по умолчанию mvc, - это поиск маршрутизации атрибутов - https://github.com/mccalltd/AttributeRouting. Хотя его большая работа, декорирование индивидуальных методов действий обеспечивает тонкость гибкости, когда вам нужно разрабатывать сложные маршруты. Вы также можете использовать его в сочетании со стандартной трассировкой MVC.