Reputation: 764
I've got some api controller with this action:
public class ProxyController : ApiController {
public async Task<HttpResponseMessage> PostActionAsync(string confirmKey)
{
return await Task<HttpResponseMessage>.Factory.StartNew( () =>
{
var result = GetSomeResult(confirmKey);
return Request.CreateResponse(HttpStatusCode.Created, result);
});
}
}
And here is my api routing confuguration:
routes.MapHttpRoute("DefaultApi", "api/{controller}/{action}/{id}", new { id = RouteParameter.Optional });
When I try to make any Post/Get Requests to this action, it's returns '404' error. How can I fix it? All other not-async actions in this controller works fine.
UPD. JS query:
$.ajax({
url: Url + '/api/Proxy/PostActionAsync',
type: 'POST',
data: { confirmKey: that.confirmKey },
dataType: 'json',
xhrFields: { withCredentials: true },
success: function (data) {
............
},
error: function (jqXHR, textStatus, errorThrown) {
............
}
});
UPD. Resolved by adding [FromBody]
to my parameters in action method just like in J. Steen's answer, now it's look's like
public class ProxyController : ApiController {
public async Task<HttpResponseMessage> PostActionAsync([FromBody]string confirmKey)
{
var someModel = new SomeResultModel(User.Identity.Name);
await Task.Factory.StartNew(() => someModel.PrepareModel(confirmKey));
return Request.CreateResponse(HttpStatusCode.OK, someModel);
}
}
And it works!
Upvotes: 2
Views: 4281
Reputation: 15578
The routing configuration for Web API works a little differently than MVC.
Try
routes.MapHttpRoute("DefaultApi", "api/{controller}/{id}", new { id = RouteParameter.Optional });
Note the missing {action}
as that is resolved by Web API at call-time, automagically, depending on the HTTP verb you use for your request.
Consider this article on Web API routing which lists (as an example):
HTTP Method URI Path Action Parameter
GET api/products GetAllProducts (none)
GET api/products/4 GetProductById 4
DELETE api/products/4 DeleteProduct 4
In your case, the async version of an action is also resolved automatically.
POST api/products PostActionAsync (Post data)
Since we now know the controller name, requests would be like:
GET api/proxy
GET api/proxy/4
POST api/proxy (with post data)
Edit:
After additional research (brief, I admit) I have found the issue.
You need to add [FromBody]
infront of your in-parameter.
public async Task<HttpResponseMessage> PostActionAsync([FromBody] string confirmKey)
This, combined with sending just the value (no wrapping json) works wonders. Set content type to "application/x-www-form-urlencoded" instead of json, and send your parameter as "=" + that.confirmKey
.
Alternative:
If you don't want to fiddle around with content-types and prefixing =-signs, just send it as part of the querystring. Forget the [FromBody]
and the rest. Call
/api/Proxy/PostActionAsync?confirmKey=' + that.confirmKey
Additional, exhaustive information in this blog.
Upvotes: 3
Reputation: 7475
Is that change possible?
public async Task<HttpResponseMessage> PostActionAsync()
{
var result = await GetSomeResult();
return Request.CreateResponse(HttpStatusCode.Created, result);
}
Upvotes: 1