Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multi-Level Routing in ASP.NET web API without Areas

I'm trying to use the new ASP.NET Web API to do the following:

A GET to /api/business/{id} gets the business's directory information. A PUT to the same URL updates the information, etc. That part works fine. The problem I'm having comes when I want to add what would formerly have been an action, to view reviews of that business. Ideally I want to be reachable at /api/business/{id}/reviews, where a GET returns the reviews, a POST submits a new review, and so forth.

In a normal ASP.NET MVC application, I could define two action methods (Reviews and PostReview) then used attributes to change the action name and accepted HTTP method of the second function. I would expect there's some way to do this with classes in the new system, but I can't figure out what it is and I'm not seeing anything about the issue in the documentation.

Using areas does not work, as best I can tell: I need the /business/{id} URL to work and with areas that breaks.

like image 519
ehdv Avatar asked Dec 07 '22 15:12

ehdv


1 Answers

Web API does support routing by action, so you can do something like this:

routes.MapHttpRoute(
    name: "ActionApi",
    routeTemplate: "api/{controller}/{id}/{action}",
    defaults: new { action = "DirectoryInfo", id = RouteParameter.Optional }
);

Controller methods:

[HttpGet]
[ActionName("DirectoryInfo")]
public void GetDirectoryInfo(int id)

[HttpPut]
[ActionName("DirectoryInfo")]
public void PutDirectoryInfp(int id)

[HttpGet]
public void Review(int id)

[HttpPost]
[ActionName("Review")]
public void PostReview(int id)

Another option is to create two controllers, BusinessController and ReviewController, and create the following routes:

routes.MapHttpRoute(
    name: "BusinessRoute", 
    routeTemplate: "api/business/{id}", 
    defaults: new { controller = "Business", id = RouteParameter.Optional }
    );
routes.MapHttpRoute(
    name: "reviewsRoute", 
    routeTemplate: "api/contacts/{id}/reviews/", 
    defaults: new { controller = "Reviews", id = RouteParameter.Optional}
    );

and then use Web API-style implicit action names.

like image 97
Mike Wasson Avatar answered Jan 07 '23 16:01

Mike Wasson