Reputation: 1579
I am attempting to write an API. The signatures look like this:
public class CardsController : ApiController
{
[HttpGet]
public ClientData NewGame(){...}
[HttpGet]
public ClientData Deal(int sessionId){...}
[HttpGet]
public ClientData Stand(int sessionId){...}
}
With everything else at default I was getting an error saying my class couldn't differentiate between Deal and Stand. After a bit of research I found it was a routing issue. So I decided to update my routing.
My global.asax.cs now looks like this:
public class MvcApplication : HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
WebApiConfig.Register(GlobalConfiguration.Configuration);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
AuthConfig.RegisterAuth();
RegisterRoutes(RouteTable.Routes);
}
public static void RegisterRoutes(RouteCollection routes)
{
routes.MapHttpRoute("api", "api/{controller}/{action}/{value}", new { value = RouteParameter.Optional});
}
}
Going to http://localhost:54924/api/Cards/Stand/19
gives an error that says no HttpResource was found, and going to http://localhost:54924/api/Cards/Stand
triggers the NewGame()
action. How can I get Stand and Deal to work on the same controller?
Upvotes: 1
Views: 199
Reputation: 9441
Add the routes:
routes.MapHttpRoute("DealApi",
"api/{controller}/deal/{sessionId}",
new { action="Deal", sessionId = RouteParameter.Optional });
routes.MapHttpRoute("StandApi",
"api/{controller}/stand/{sessionId}",
new { action="Stand", sessionId = RouteParameter.Optional });
Now, in your Controller class:
[HttpGet]
[ActionName("Deal")]
public ClientData Deal(int sessionId){...}
[HttpGet]
[ActionName("Stand")]
public ClientData Stand(int sessionId){...}
Now, whenever you pull up the url http://www.yourhost.com/api/deal/12345, the Deal function will be called. Same thing with Stand.
Keep in mind that whatever you set in your routes tables are only for recognizing whether a url is valid. By having the action specified in the third parameter, you're telling Web Api to find a function whose ActionName attribute is set to what you specify.
Another thing - put those two routes BEFORE any of your default api routes.
Upvotes: 1
Reputation: 1038720
Web API works with RESTful routes. In REST you have resources and standard actions with them: GET, POST, PUT, PATCH and DELETE. That's how your actions should be named. Deal
and Stand
means absolutely noting in RESTful
routing. When you are designing an API you should be thinking in terms of resources and the standard HTTP verbs that you could do with those resources. In a RESTful API the controller represents your resource and the HTTP verbs are the actions that you want to perform with this resource.
If you want to violate the default RESTful conventions that are built into the Web Api routing you will have to modify your route setup and include the {action}
name in it. Then you will be able to name your actions however you want. Just bare in mind that if you are designing an API there are standards that consumers adhere to. If you want to be reinventing wheels make sure you have really good documentation of your API.
Upvotes: 3