Reputation: 433
I've created controller class that extends ApiController and includes following methods :
// GET api/Posts/5
[ResponseType(typeof(Post))]
public IHttpActionResult GetPost(int id)
{
...
}
// GET api/Posts/ByBoardID/2
[HttpGet]
[ActionName("ByBoardID")]
public IQueryable<Post> GetByBoardID(int boardID)
{
...
}
The idea is to match those method to a given routes (i.e 'api/Posts/ByBoardID/2' to a GetByBoardID(int boardID) method and 'api/Posts/2' to a GetPosts(int id) method).
Here's route config :
config.Routes.MapHttpRoute(
name: "ByParamApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional });
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional });
Second route ('api/Posts/ByBoardID/2') cannot be matched - No HTTP resource was found that matches the request URI
.
Whats the best practice to create such 'nested' routes inside controller? I will use many controllers with the same pattern (/{controller}/{id} and /{controller}/bySpecialParam/{id})
so I don't want to 'hardcode' such route that won't be reusable.
Upvotes: 1
Views: 1865
Reputation: 11
This worked:
1) Provide actionName for both the methods in the controller.
[ActionName("DefaultAction")]
[ActionName("ByBoardID")]
2) In the webapiconfig class, add the following routes
config.Routes.MapHttpRoute(
"defaultActionRoute",
"{controller}/{action}/{id}",
null,
new
{
action = "ByBoardId"
});
config.Routes.MapHttpRoute(
"defaultRoute",
"{controller}/{id}",
new
{
action = "DefaultAction"
});
Make sure you have the GlobalConfiguration.Configuration.EnsureInitialized();
at the end of Application_Start()
method.
Upvotes: 1
Reputation: 2213
Only way I ever got working such combination is by changing this
[ActionName("ByBoardID")]
to
[Route("api/Posts/ByBoardID/{boardID}")]
Never able to figure out how the ActionName attribute works so always preferred to go with Route attribute
Upvotes: 1