user610217
user610217

Reputation:

Works for GET, not for POST (404 error)

I have a WebApi controller ServicesApiController in my MVC4 project with a signature like so:

[Authorize(Roles = "sysadmin,Secretary")]
[AcceptVerbs("GET", "POST")]
public IEnumerable<Stock> TopRankedStocks(int maxRecords)
{
    // do stuff
    return result;
}

My routing for my api controllers looks like this:

config.Routes.MapHttpRoute(
    name: "ServicesApi",
    routeTemplate: "api/{controller}/{action}",
    defaults: new { controller = "ServicesApi", action="Index" }
    );

Using IIS Express, if I navigate to http://localhost:62281/api/ServicesApi/TopRankedStocks?maxRecords=20 in my browser, I get a nice xml list of my data objects.

However, if I call it like so:

myHttpClient.BaseAddress = "http://localhost:62281/";
var arguments = new List<KeyValuePair<string, string>>(new[] { KeyValuePair<string, string>("maxRecords", "10") });
var content = new FormUrlEncodedContent(arguments);
var result = myHttpClient.PostAsJsonAsync("/api/ServicesApi/TopRankedStocks", content).Result;

...I get a 404 (Not Found) error.

POST operations work in other places in my code. My config files for the application and IIS Express all allow all verbs. I have no idea why this is not working. Can someone clue me in?

I don't know if any of this is relevant information, but I'll post it in case there's some value here:

Upvotes: 1

Views: 2581

Answers (1)

Joanna Derks
Joanna Derks

Reputation: 4063

I can see a potential issue with this controller method:

The problem is that your argument is of type int (primitive type) - as long as you don't mark it as [FromBody] the WebApi parameter binding engine will assume that it comes from the url. That explains why GET works; I'm not sure how POST is considered when you don't supply the value in the url.

Still, if you marked maxRecords as FromBody and tried using it with a GET method it would stop working most probably. Also, note that in case you wanted to use form-urlencoded string for the post body with just one key-value-pair then to make it work you'd need to post it as "=10" and not "maxRecords=10".

To check if this is the issue that's causing the method to fail, I'd temporarily remove GET support leaving it with just POST, and mark the param as FromBody.

Upvotes: 2

Related Questions