2013-04-29 24 views
2

我有这个动作有些API控制器:的Asp网页API异步行动 - 404错误

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); 
       }); 
    } 
} 

这里是我的API路由confuguration:

routes.MapHttpRoute("DefaultApi", "api/{controller}/{action}/{id}", new { id = RouteParameter.Optional }); 

当我尝试做任何发布/获取请求到这个动作,它返回'404'错误。我该如何解决它?此控制器中的所有其他非异步操作都可以正常工作。

UPD。 JS查询:

$.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。加入[FromBody]到我的行动方法的参数就像在J.斯蒂恩的回答解决了,现在它看起来的一样

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); 
     } 
    } 

和它的作品!

+0

发布你的'ActionResult'方法和控制器名称。如果可能的话,你的异步调用Jquery太:) – RajeshKdev 2013-04-29 15:14:25

+0

添加所有需要的 – 2013-04-30 07:23:47

+0

@IgorKonopko:尝试用'[HttpPost]'标记动作' – Catalin 2013-04-30 07:27:22

回答

3

的Web API的路由配置的作用有点不同于MVC。

尝试

routes.MapHttpRoute("DefaultApi", "api/{controller}/{id}", new { id = RouteParameter.Optional }); 

注意失踪{action}作为通过网络API在呼叫时间分辨,自动的,这取决于您使用您请求的HTTP动词。

考虑this article on Web API routing列出(作为一个例子):

HTTP Method URI Path   Action   Parameter 
GET   api/products  GetAllProducts (none) 
GET   api/products/4  GetProductById 4 
DELETE  api/products/4  DeleteProduct 4 

在你的情况下,动作的异步版本也自动解决。

POST   api/products  PostActionAsync (Post data) 

因为我们现在知道控制器名称,会请求像:

GET api/proxy 
GET api/proxy/4 
POST api/proxy (with post data) 

编辑

经过进一步的研究(简单地说,我承认),我已经找到问题。

您需要在参数的前面添加[FromBody]

public async Task<HttpResponseMessage> PostActionAsync([FromBody] string confirmKey) 

这与发送只是值(无包装JSON)可以创造奇迹组合。将内容类型设置为“application/x-www-form-urlencoded”而不是json,并将您的参数发送为"=" + that.confirmKey

替代

如果你不想摆弄内容类型和前缀= -signs,只是把它作为查询字符串的一部分。忘记[FromBody]和其他。致电

/api/Proxy/PostActionAsync?confirmKey=' + that.confirmKey 

Additional, exhaustive information in this blog

+0

我已更改路由,例如您的示例,也是我的客户端ajax url更改为ServerUrl +'/ api/Proxy?action = PostActionAsync',现在它返回500(内部服务器错误)。是不是应该在一个api控制器中只使用一个get/post/put动作? – 2013-04-30 08:33:25

+0

约定是每个控制器只使用一个POST。另外,?action = PostActionAsync可能也不太好,我很抱歉地说。 =/ – 2013-04-30 08:34:26

+0

我非常困惑。如果你想要基于动作的路由,我的答案是错误的。你的路由配置需要像你最初说明的那样。 – 2013-04-30 08:35:27

1

这种变化可能吗?

public async Task<HttpResponseMessage> PostActionAsync() 
{ 
    var result = await GetSomeResult(); 
    return Request.CreateResponse(HttpStatusCode.Created, result); 
} 
+0

'CreateResponse()'返回' HttpResponseMessage”,它不能转换到 '任务' – 2013-04-30 07:16:32

+0

'异步任务 WaitAsynchronouslyAsync(){等待Task.Delay(10000);返回“完成”; }'这是[MSDN]的示例(http://msdn.microsoft.com/zh-cn/library/vstudio/hh156528.aspx)。 – Vladimir 2013-04-30 07:33:35

+0

这是当前的代码http://pastebin.com/9pda4BPb,它仍然会返回“404” – 2013-04-30 07:55:29