如何在ASP.NET Web API中处理分层路由?

Har*_*san 36 restful-url c#-4.0 asp.net-mvc-4 asp.net-web-api

目前我有两个控制器

1 - 家长控制器

2 - 儿童控制器

我像这样访问我的父控制器

someurl\parentcontroller
Run Code Online (Sandbox Code Playgroud)

现在我想像这样访问我的孩子控制器

someurl\parentcontroller\1\childcontroller
Run Code Online (Sandbox Code Playgroud)

最后一个网址应该返回特定父级的所有子级.

我目前在global.asax文件中有这条路线

routes.MapHttpRoute ("Route1", "{controller}/{id}", new { id = RouteParameter.Optional });

我不确定如何实现我的parent\id\child层次结构..我应该如何配置我的路由来实现这一目标?想法?

Abh*_*t_K 31

配置路由如下.{param}是可选的(如果需要,可以使用):

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 }
  );
Run Code Online (Sandbox Code Playgroud)

然后将子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";
        }
        .......
    }
Run Code Online (Sandbox Code Playgroud)


小智 18

从Web API 2开始,您现在可以使用Route Attributes为每个Method定义自定义路由,

[Route("api/customers/{id:guid}/orders")]
public IEnumerable<Order> GetCustomerOrders(Guid id) {
   return new Order[0];
}
Run Code Online (Sandbox Code Playgroud)

您还需要在WebApiConfig.Register()初始化方法中添加以下行,

  config.MapHttpAttributeRoutes();
Run Code Online (Sandbox Code Playgroud)

全文, http://www.asp.net/web-api/overview/web-api-routing-and-actions/attribute-routing-in-web-api-2


mo.*_*mo. 10

我希望以更一般的方式处理这个问题,而不是controller = "Child"像Abhijit Kadam那样直接连接ChildController .我有几个子控制器,并且不希望必须为每个控制器映射一个特定的路由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 }
);
Run Code Online (Sandbox Code Playgroud)

我的父控制器非常标准,并且与上面的默认路由匹配.示例子控制器如下所示:

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
}
Run Code Online (Sandbox Code Playgroud)

我实现的一些缺点

  • 如你所见,我使用了一个enum,所以我仍然需要在两个不同的地方管理父控制器.它可以很容易地成为一个字符串参数,但我想阻止api/crazy-non-existent-parent/5/comment/122工作.
  • 可能有一种方法可以使用反射或其他东西来实现这一点,而无需进行单独管理,但这对我来说现在很有用.
  • 它不支持儿童的孩子.

可能有更好的解决方案甚至更普遍,但就像我说的,这对我有用.


Ale*_*Gad 5

除了使用默认mvc路由之外的一个选项是查看属性路由 - https://github.com/mccalltd/AttributeRouting.虽然它的工作量很大,但是当您需要设计复杂的路线时,装饰个人行动方法可以提供很大的灵活性.您还可以将它与标准MVC路由结合使用.