Post JSON HttpContent to ASP.NET Web API

Leigh picture Leigh · Jun 8, 2014 · Viewed 40k times · Source

I have an ASP.NET Web API hosted and can access http get requests just fine, I now need to pass a couple of parameters to a PostAsync request like so:

var param = Newtonsoft.Json.JsonConvert.SerializeObject(new { id=_id, code = _code });
HttpContent contentPost = new StringContent(param, Encoding.UTF8, "application/json");

var response = client.PostAsync(string.Format("api/inventory/getinventorybylocationidandcode"), contentPost).Result;

This call is returning a 404 Not Found result.

The server side API action looks like so:

[HttpPost]
public List<ItemInLocationModel> GetInventoryByLocationIDAndCode(int id, string code) {
...
}

And just to confirm my route on the Web API looks like this:

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

I assume I'm passing the JSON HttpContent across incorrectly, why would this be returning status 404?

Answer

Justin Helgerson picture Justin Helgerson · Jun 8, 2014

The reason you're receiving a 404 is because the framework didn't find a method to execute given your request. By default, Web API uses the following rules to bind parameters in methods:

  • If the parameter is a “simple” type, Web API tries to get the value from the URI. Simple types include the .NET primitive types (int, bool, double, and so forth), plus TimeSpan, DateTime, Guid, decimal, and string, plus any type with a type converter that can convert from a string. (More about type converters later.)
  • For complex types, Web API tries to read the value from the message body, using a media-type formatter.

Given those rules, if you want to bind the parameter from the POST body simply add a [FromBody] attribute in front of the type:

[HttpPost]
public List<ItemInLocationModel> GetInventoryByLocationIDAndCode([FromBody] int id, string code) {
...
}

For more information please see the documentation.