I have temporaly solved the issue using Magical Web Api Selector (http://www.strathweb.com/2013/01/magical-web-api-action-selector-http-verb-and-action-name-dispatching-in-a-single-controller/). But I hope there ir a easier way to do it.
ASP.NET Web API has two ways built-in for picking which action to call based on a request: by HTTP verb and by action name. By default we use the HTTP verb, which encourages a resource centric way of setting up your controllers. If an action variable is
present in the route data then we select the action by name, which is a more RPC-like model. The two modes of action selection don't mix very well at the moment so we in general recommend against mixing routes that have action variables with routes that don't.
Hierarchical routing structures like this one become easier with our new ASP.NET Web API OData support. You can simply model your data and we will build up the URI space for you following the OData conventions. If you are interested you can read more about it
on Alex James' blog:
http://blogs.msdn.com/b/alexj/archive/2012/12/07/odata-in-webapi-rc-release.aspx
hilbertZg
Member
28 Points
14 Posts
Routing issue
Jan 18, 2013 08:27 AM|LINK
Hi guys,
I am updating my old web-api code (based on Web-API beta release) and I am not able to make the routing work. What I need:
GET /admissions (get all admissions)
GET /admissions/id (get admission info)
GET /admissions/id/profile (get admission profile)
GET /admissions/id/invoice (get admission invoice)
In addition, I have other routes as:
GET /products
GET /register
And so on.
I have tried with this routes:
config.Routes.MapHttpRoute( name: "AdmissionsApi", routeTemplate: "api/{controller}/{id}/{action}", defaults: new { controller = "Admissions", id = RouteParameter.Optional } ); config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } ); }But when I try GET /admissions/3 the api gives me an error saying there are several actions that meets the request. This is the controller:
public class AdmissionsController : ApiController { [HttpGet] public HttpResponseMessage Get() { return null; } public HttpResponseMessage Post() { return null; } [HttpGet] public HttpResponseMessage GetById(int id) { return null; } public HttpResponseMessage Delete(int id) { return null; } [HttpGet] [ActionName("profile")] public HttpResponseMessage GetProfile(int id) { return null; } }Any ideas? Thank you in advanced.
DarrellNorto...
All-Star
86773 Points
9643 Posts
Moderator
MVP
Re: Routing issue
Jan 18, 2013 10:37 AM|LINK
First, the default Api routes start with "api/", so all of your /admissions will need api/ in front of them, like this: GET /api/admissions
Second, you need to change the first MapHttpRoute to have {action} then {id} for your ApiController to work, like this:
config.Routes.MapHttpRoute( name: "AdmissionsApi", routeTemplate: "api/{controller}/{action}/{id}", defaults: new { controller = "Admissions", id = RouteParameter.Optional } );Darrell Norton's Blog
Please click "Mark as Answer" if this helped you.
hilbertZg
Member
28 Points
14 Posts
Re: Routing issue
Jan 18, 2013 11:01 AM|LINK
Thank you Darrell.
The route change you propose does not work.
GET /api/admissions -> WORK
GET /api/admissions/4 -> does not exists
I have temporaly solved the issue using Magical Web Api Selector (http://www.strathweb.com/2013/01/magical-web-api-action-selector-http-verb-and-action-name-dispatching-in-a-single-controller/). But I hope there ir a easier way to do it.
Regards
danroth27
Member
174 Points
40 Posts
Microsoft
Re: Routing issue
Jan 18, 2013 04:41 PM|LINK
ASP.NET Web API has two ways built-in for picking which action to call based on a request: by HTTP verb and by action name. By default we use the HTTP verb, which encourages a resource centric way of setting up your controllers. If an action variable is present in the route data then we select the action by name, which is a more RPC-like model. The two modes of action selection don't mix very well at the moment so we in general recommend against mixing routes that have action variables with routes that don't.
For your scenario I would do something like this:
// Handles: // api/admissions/1/profile -> ProfileController // api/admissions/1/invoice -> InvoiceController config.Routes.MapHttpRoute( name: "AdmissionsApi", routeTemplate: "api/admissions/{id}/{controller}" ); // Handles everything else config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } );Hierarchical routing structures like this one become easier with our new ASP.NET Web API OData support. You can simply model your data and we will build up the URI space for you following the OData conventions. If you are interested you can read more about it on Alex James' blog: http://blogs.msdn.com/b/alexj/archive/2012/12/07/odata-in-webapi-rc-release.aspx
Hope this helps!
Senior Program Manager
ASP.NET