如何使用 HttpClient 从 Web Api 调用 PUT 方法?

Posted

技术标签:

【中文标题】如何使用 HttpClient 从 Web Api 调用 PUT 方法?【英文标题】:How to call PUT method from Web Api using HttpClient? 【发布时间】:2013-04-09 19:19:29 【问题描述】:

我想调用 Api 函数 (1st) 。从使用 HttpClient 的第二个 Api 函数开始。但我总是得到 404 错误。

1st Api Function (EndPoint : http : // localhost : xxxxx /api/Test/)

public HttpResponseMessage Put(int id, int accountId, byte[] content)
[...]

第二个 API 函数

public HttpResponseMessage Put(int id, int aid, byte[] filecontent)

    WebRequestHandler handler = new WebRequestHandler()
    
        AllowAutoRedirect = false,
        UseProxy = false
    ;

    using (HttpClient client = new HttpClient(handler))
    
        client.BaseAddress = new Uri("http://localhost:xxxxx/");

        // Add an Accept header for JSON format.
        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

        var param = new object[6];
        param[0] = id;
        param[1] = "/";
        param[2] = "?aid="; 
        param[3] = aid;                           
        param[4] = "&content=";
        param[5] = filecontent;

        using (HttpResponseMessage response = client.PutAsJsonAsync("api/Test/", param).Result)
        
            return response.EnsureSuccessStatusCode();
        
    

所以我的问题是。 我可以像以前那样将方法参数作为对象数组从 HttpClient 发布吗?我不想传递模型作为方法参数。

我的代码有什么问题?

无法得到任何响应,代码更改为

return client.PutAsJsonAsync(uri, filecontent)
           .ContinueWith<HttpResponseMessage>
            (
               task => task.Result.EnsureSuccessStatusCode()
            );

return client.PutAsJsonAsync(uri, filecontent)
           .ContinueWith
            (
               task => task.Result.EnsureSuccessStatusCode()
            );

【问题讨论】:

【参考方案1】:

您可能已经发现,不,您不能。当您调用PostAsJsonAsync 时,代码会将参数转换为 JSON 并在请求正文中发送。您的参数是一个 JSON 数组,类似于下面的数组:

[1,"/","?aid",345,"&content=","aGVsbG8gd29ybGQ="]

这不是第一个函数所期望的(至少我是这样想的,因为您没有显示路线信息)。这里有几个问题:

默认情况下,byte[](引用类型)类型的参数在请求的 body 中传递,而不是在 URI 中(除非您使用 [FromUri] 属性显式标记参数) . 其他参数(同样,基于我对您的路由的猜测)需要是 URI 的一部分,而不是正文。

代码如下所示:

var uri = "api/Test/" + id + "/?aid=" + aid;
using (HttpResponseMessage response = client.PutAsJsonAsync(uri, filecontent).Result)

    return response.EnsureSuccessStatusCode();

现在,上面的代码还有另一个潜在问题。它正在等待网络响应(当您访问由PostAsJsonAsync 返回的Task&lt;HttpResponseMessage&gt; 中的.Result 属性时会发生这种情况。根据环境,可能发生的更糟糕的情况是它可能会死锁(在线程中等待网络响应将到达)。在最好的情况下,该线程将在网络调用期间被阻塞,这也很糟糕。考虑使用异步模式(等待结果,在您的操作中返回Task&lt;T&gt;) ,如下例所示

public async Task<HttpResponseMessage> Put(int id, int aid, byte[] filecontent)

    // ...

    var uri = "api/Test/" + id + "/?aid=" + aid;
    HttpResponseMessage response = await client.PutAsJsonAsync(uri, filecontent);
    return response.EnsureSuccessStatusCode();

或者没有 async / await 关键字:

public Task<HttpResponseMessage> Put(int id, int aid, byte[] filecontent)

    // ...

    var uri = "api/Test/" + id + "/?aid=" + aid;
    return client.PutAsJsonAsync(uri, filecontent).ContinueWith<HttpResponseMessage>(
        task => task.Result.EnsureSuccessStatusCode());

【讨论】:

请您描述一下您的awaiting the result, returning a Task&lt;T&gt; in your action 概念。 用一个例子编辑了答案。 async not available with .Net Framework 4 (VS 2010) 是他们的其他方法吗? 这是一个不同的问题,请提出一个新问题。 [***.com/questions/15933350/…我做到了

以上是关于如何使用 HttpClient 从 Web Api 调用 PUT 方法?的主要内容,如果未能解决你的问题,请参考以下文章

HttpClient 不报告从 Web API 返回的异常

如何使用 HttpClient 在 Web api 中传递标头值

如何使用 HttpClient 将 JSON 数据发布到 Web API

如何在 C# 中使用 HttpClient 读取 Web api 响应

如何使用存储在会话存储中的访问令牌使用 HttpClient 进行 Web api 调用?

从 ASP.net 4 Web API 2 项目通过 HttpClient 调用 REST 服务导致异常