I'm pretty sure you can use the routing engine to take care of this. The order of rules do matter and you have to put the more specific above the more generic ones. Remember you can also use constraints like regex to match parts of the URL now.
So you'd have a list of rules with URLs something like this (and hardcode Controller = "Flight" in the route defaults):
thx for your reply. But is there any attribute I can annotate my Methods with, to define a route for them? Or do I have to create a route within Global.asax? Of course, I could write such an attribute by my self, but if there's a standard-mechanism for doing
that, I would prefer it ...
We don't currently have an attribute based mechansim for adding routes. Using an attribute has some complexities since the route order is important.
We do however dispatch to overloaded actions based on the presence of route variables. For example you can have the following two actions on the same controller:
public class ContactsController
{
// GET contacts
public IEnumerable<Contact> Get() {...}
// GET contacts/1
public Contact Get(int id) {...}
}
Here you are basically modeling two resources (the collection and individual items) with one controller.
Daniel Roth
Senior Program Manager
ASP.NET
Marked as answer by manfred.steyer on Feb 17, 2012 05:57 PM
This is a little old, but you could convert the
MVC-based route attribute to work with Web API trivially. I think a route attribute is also available in MvcContrib, though again that would be MVC-specific.
I am migrating from WCF Web API to the new ASP.NET Web API, and I am having trouble with the routing when it comes to "nested" resources. Before I was using webGet and WebInvoke attributes.
I am trying to setup routing such that these are my paths are like this:
/api/contacts
/api/contacts/{id)
/api/contacts/{contactId}/addresses
/api/contacts/{contactId}/addresses/{id}
/api/contacts/{contactId}/phoneNumbers
/api/contacts/{contactId}/phoneNumbers/{id}
Basically I have a resource with one or more child resources. Can anyone provide an example of how to use MapHttpRoute to register routing for the example above? Do I need to have more than one ApiController in the case described?
Ok, I think I figured out the semi-generic approach to this problem. I was able to use GET, DELETE, etc. the trick was to not specify the action. I should have tried this approach sooner, I had wondered if I needed separate controllers, and it turns out
for what I wanted that was necessary.
Create an ApiController for the 'parent' resource, and allow the default route to handle it
Create an ApiController for each 'child' resource.
Map HTTP routes for each child resource like this:
routes.MapHttpRoute(
name: "MyChildResourceRoute",
routeTemplate: "api/contacts/{contactId}/adresses/{id}",
defaults: new { controller = "contactaddresses", id = RouteParameter.Optional }
);
In Beta, we don't support adding method level attribute for routing. The challenge here is how to merge and order those attributes with what user already specifies in the global.asax.cs. That said, we are definately thinking of improving the routing story
for the next release.
manfred.stey...
Member
35 Points
57 Posts
"sub-ressources"
Feb 17, 2012 04:31 PM|LINK
Hi,
what is the recommended way to implement "sub-ressources" like
flight/4711/tickets/T001 oder
flight/4711/tickets?name=max
Wishes
Manfred
SiggiGG
Member
265 Points
105 Posts
Re: "sub-ressources"
Feb 17, 2012 05:20 PM|LINK
I'm pretty sure you can use the routing engine to take care of this. The order of rules do matter and you have to put the more specific above the more generic ones. Remember you can also use constraints like regex to match parts of the URL now.
So you'd have a list of rules with URLs something like this (and hardcode Controller = "Flight" in the route defaults):
flight/{flightId}/tickets?name={nameFilter}
flight/{flightId}/tickets/{ticketId}
flight/{flightId}/tickets/
flight/{flightId}
You can probably merge lines 2 and 3 and mark the ticketId part as optional.
manfred.stey...
Member
35 Points
57 Posts
Re: "sub-ressources"
Feb 17, 2012 05:37 PM|LINK
Hi,
thx for your reply. But is there any attribute I can annotate my Methods with, to define a route for them? Or do I have to create a route within Global.asax? Of course, I could write such an attribute by my self, but if there's a standard-mechanism for doing that, I would prefer it ...
Wishes,
Manfred
danroth27
Member
174 Points
40 Posts
Microsoft
Re: "sub-ressources"
Feb 17, 2012 05:45 PM|LINK
We don't currently have an attribute based mechansim for adding routes. Using an attribute has some complexities since the route order is important.
We do however dispatch to overloaded actions based on the presence of route variables. For example you can have the following two actions on the same controller:
public class ContactsController { // GET contacts public IEnumerable<Contact> Get() {...} // GET contacts/1 public Contact Get(int id) {...} }Here you are basically modeling two resources (the collection and individual items) with one controller.
Senior Program Manager
ASP.NET
panesofglass
Member
730 Points
237 Posts
Re: "sub-ressources"
Feb 17, 2012 06:02 PM|LINK
This is a little old, but you could convert the MVC-based route attribute to work with Web API trivially. I think a route attribute is also available in MvcContrib, though again that would be MVC-specific.
Routing
Oppositional
Member
72 Points
19 Posts
Re: "sub-ressources"
Feb 22, 2012 10:50 PM|LINK
I am migrating from WCF Web API to the new ASP.NET Web API, and I am having trouble with the routing when it comes to "nested" resources. Before I was using webGet and WebInvoke attributes.
I am trying to setup routing such that these are my paths are like this:
Basically I have a resource with one or more child resources. Can anyone provide an example of how to use MapHttpRoute to register routing for the example above? Do I need to have more than one ApiController in the case described?
hilbertZg
Member
28 Points
14 Posts
Re: "sub-ressources"
Feb 22, 2012 11:01 PM|LINK
It is a bit tricky, but I guess you could use the default for the first and the second:
config.Routes.MapHttpRoute( "API Default", "api/{controller}/{id}", new { id = RouteParameter.Optional });And now... As I understand you could use:
config.Routes.MapHttpRoute( name: "ContactAddresses", routeTemplate: "api/contacts/{contactId}/addresses", defaults: new { controller = "contacts", action = "GetAddresses" }, constraints: new { contactId = @"\d+" } );And so on for each Action. I'd be interested in a better solution (I bet there is one) too, hope the MS team can help us.
:)
Oppositional
Member
72 Points
19 Posts
Re: "sub-ressources"
Feb 22, 2012 11:32 PM|LINK
Ok, I think I figured out the semi-generic approach to this problem. I was able to use GET, DELETE, etc. the trick was to not specify the action. I should have tried this approach sooner, I had wondered if I needed separate controllers, and it turns out for what I wanted that was necessary.
Hongmei Ge
Member
26 Points
8 Posts
Microsoft
Re: "sub-ressources"
Feb 23, 2012 12:36 AM|LINK
In Beta, we don't support adding method level attribute for routing. The challenge here is how to merge and order those attributes with what user already specifies in the global.asax.cs. That said, we are definately thinking of improving the routing story for the next release.
LittleClive
Member
91 Points
65 Posts
Re: "sub-ressources"
Mar 13, 2012 02:36 PM|LINK
I used the following approach to sub-resources (only supports one level of sub-resource):
routes.Add(
new Route("SubController", "api/{controller}/{id}/{subcontroller}/{subId}", new { subId = RouteParameter.Optional }));
Finally create a controller called:BooksAuthorsController to allow /api/books/1/authors