How to handle hierarchical routes in ASP.NET Web API?

后端 未结 4 1012
日久生厌
日久生厌 2020-12-07 14:06

Currently I have two controllers

1 - Parent Controller

2 - Child Controller

I access my Parent Controller like this

someurl\\parentc         


        
相关标签:
4条回答
  • 2020-12-07 14:18

    Configure the routes as below. The {param} is optional (use if you need):

    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 }
      );
    

    Then call the child APi as /api/Parent/1/child The parent can be called simple as /api/Parent/

    The child controller:

        public class ChildController : ApiController
        {     
            public string Get(int id)
            {
              //the id is id between parent/{id}/child  
              return "value";
            }
            .......
        }
    
    0 讨论(0)
  • 2020-12-07 14:18

    Since Web API 2 you can now use Route Attributes to define custom routing per Method,

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

    You also need to add following line to WebApiConfig.Register() initialization method,

      config.MapHttpAttributeRoutes();
    

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

    0 讨论(0)
  • 2020-12-07 14:19

    An option beyond using default mvc routing is to look at Attribute Routing - https://github.com/mccalltd/AttributeRouting. Although its more work, decorating individual action methods provides a ton of flexibility when you need to design complicated routes. You can also use it in conjunction with standard MVC routing.

    0 讨论(0)
  • 2020-12-07 14:25

    I wanted to handle this in a more general way, instead of wiring up a ChildController directly with controller = "Child", as Abhijit Kadam did. I have several child controllers and didn't want to have to map a specific route for each one, with controller = "ChildX" and controller = "ChildY" over and over.

    My WebApiConfig looks like this:

    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 }
    );
    

    My parent controllers are very standard, and match the default route above. A sample child controller looks like this:

    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
    }
    

    Some drawbacks of my implementation

    • As you can see, I used an enum, so I'm still having to manage parent controllers in two separate places. It could have just as easily been a string parameter, but I wanted to prevent api/crazy-non-existent-parent/5/comment/122 from working.
    • There's probably a way to use reflection or something to do this on the fly without managing it separetly, but this works for me for now.
    • It doesn't support children of children.

    There's probably a better solution that's even more general, but like I said, this works for me.

    0 讨论(0)
提交回复
热议问题