【问题标题】:How to handle hierarchical routes in ASP.NET Web API?如何处理 ASP.NET Web API 中的分层路由?
【发布时间】:2012-06-02 18:42:12
【问题描述】:

目前我有两个控制器

1 - 父控制器

2 - 子控制器

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

someurl\parentcontroller

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

someurl\parentcontroller\1\childcontroller

最后一个 url 应该返回特定父级的所有子级。

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

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

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

【问题讨论】:

标签: c#-4.0 asp.net-mvc-4 asp.net-web-api restful-url


【解决方案1】:

如下配置路由。 {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 }
  );

然后调用子 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";
        }
        .......
    }

【讨论】:

  • 不工作..你能详细说明在这种情况下子控制器的外观吗?我将如何获得父母 ID?
  • @HarisHasan,你看到上面的链接了吗?
  • @user960567 是的,我已经看到了。但是这个答案中的方法要简单得多。
【解决方案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】:

    我想以更通用的方式处理这个问题,而不是像 Abhijit Kadam 那样直接使用 controller = "Child" 连接 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 }
    );
    

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

    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 工作。
    • 可能有一种方法可以使用反射或其他方式即时执行此操作,而无需单独管理,但目前这对我有用。
    • 不支持孩子的孩子。

    可能有更好的解决方案,更通用,但就像我说的,这对我有用。

    【讨论】:

    • 另一个缺点:假设您有第二种类型的孩子(例如,这里的产品有很多 cmets,如果产品也有很多“国家”怎么办 - 您对“父母”的概括阻止了这种情况的发生)
    • 我不明白为什么会这样。这就是我回答的目的。事实上,我使用上述代码的实际实现有几种不同类型的孩子。只是有一个类似的课程,到处都用“国家”代替“评论”这个词。那么你的网址是 api/product/5/country/122... 是我误会你的话了吗?
    • 更难的问题是,如果同一个子类型可以有多个父级,你不能为每个关系使用不同的控制器,单个子级必须在内部分叉自己的逻辑来处理父级案例
    • 在我的生产代码中,我有两个子类型,每个子类型都可以嵌套在三种不同父类型中的任何一种下。控制器不太关心父级是什么,但在某些时候,是的,我必须在我的依赖关系深处的某个地方有一个switch。我不认为这是该解决方案在实际应用中的重大缺陷。您完全可以围绕IHttpControllerSelector 设计一个功能强大的解决方案,以更优雅地处理它,但这超出了我的回答范围。
    【解决方案4】:

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

    【讨论】:

      猜你喜欢
      • 2019-01-20
      • 2015-05-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多