Currently I have two controllers
1 - Parent Controller
2 - Child Controller
I access my Parent Controller like this
someurl\parentcontroller
Now I want to access my children controller like this
someurl\parentcontroller\1\childcontroller
This last url should return all the children of a particular parent.
I have this route currently in my global.asax file
routes.MapHttpRoute ("Route1", "{controller}/{id}", new { id = RouteParameter.Optional });
I am not sure how can I achieve my parent\id\child
hierarchy.. How should I configure my routes to achieve this? Ideas?
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";
}
.......
}
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
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 preventapi/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.
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.
来源:https://stackoverflow.com/questions/10783946/how-to-handle-hierarchical-routes-in-asp-net-web-api