Uri Maimon - Nominal
Uri Maimon - Nominal

Reputation: 546

ASP.MVC web api routing issues

I'm trying to use Web API and Web application side by side and having some issues with the web API routing.

These are the route configurations:

routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );

// Map this rule first
        config.Routes.MapHttpRoute(
            name: "WithActionApi",
             routeTemplate: "api/{controller}/{action}/"
         );

        //sets up the API route
        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/"
            //,defaults: new { id = RouteParameter.Optional }
        );

It works fine for the web app and works fine for the web api that includes only the /api/controller but does not work fine if I call the /api/controll/action

I'm using:

[HttpPost]
    [ActionName("ConfirmRequest")]
    public HttpResponseMessage ConfirmRequest(string guid, string type, PartiStatus status = PartiStatus.Yes)

To specify the action verb and name. I tried the route debugger (which doesn't work in web api) and another one which does (and crashes) and was not able to get the POST action to work.

I ended up changing this actions to GET and it works fine, I guess the GET params help the framework figure it out.

I am still not sure how to make it work properly. (without individuality mapping to actions)

Upvotes: 1

Views: 444

Answers (2)

Kunal
Kunal

Reputation: 46

From my experience with Web API and routing, it's best to put your default action at the bottom. I also remove the "catch all" and have a default per controller for the basic verbs GET/PUT/POST/DELETE.

Try something like this

    config.Routes.MapHttpRoute(
        name: "WithActionApi",
        routeTemplate: "api/Target/ConfirmRequest/{id}",
        defaults: new { id = RouteParameter.Optional }
     );

    config.Routes.MapHttpRoute(
        name: "Default",
        routeTemplate: "api/{controller}/{action}/{id}",
        defaults: new { id = RouteParameter.Optional }
     );

Your sample call would look something like this

POST api/Target/ConfirmRequest?guid={guid}&type={type}&status{status}

There's a handy little Chrome add-in I use in conjunction with Fiddler when quickly testing REST API calls, Postman. It lets you save URLs and multiple environments for quick debugging.

Upvotes: 1

Ant P
Ant P

Reputation: 25221

Ensure that you are actually issuing a POST request to the URL in question. It appears as though your routing is correct and, while you have mentioned that it works if you change your [HttpPost] attribute to [HttpGet], you have made no mention of changing your request accordingly.

If you are issuing a GET request to the URL for the ConfirmRequest action and its only overload is decorated with the [HttpPost] attribute, the request will not be mapped to this action.

Most browsers have a profiler that will allow you to examine your HTTP request in detail (such as Chrome's Network Panel). If the request isn't coming from a browser, you might try a standalone profiler like Fiddler.

Upvotes: 0

Related Questions