2

我有一些具有此操作的 api 控制器:

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 路由配置:

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. Steen 的回答中一样,现在看起来像

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

它有效!

4

2 回答 2

3

Web API 的路由配置与 MVC 的工作方式略有不同。

尝试

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

请注意缺少{action}的内容,因为 Web API 在调用时会自动解决此问题,具体取决于您用于请求的 HTTP 动词。

考虑这篇关于 Web API 路由的文章,其中列出了(作为示例):

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.

替代方案

如果您不想摆弄内容类型和前缀 =-符号,只需将其作为查询字符串的一部分发送即可。忘记[FromBody]其他的。称呼

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

此博客中的其他详尽信息

于 2013-04-29T15:28:43.860 回答
1

这种改变可能吗?

public async Task<HttpResponseMessage> PostActionAsync()
{
    var result = await GetSomeResult();
    return Request.CreateResponse(HttpStatusCode.Created, result);
}
于 2013-04-29T15:15:00.153 回答