如何使用的HttpClient从网络API调用PUT方法? [英] How to call PUT method from Web Api using HttpClient?

查看:466
本文介绍了如何使用的HttpClient从网络API调用PUT方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我要调用API函数(1)。从第二个API函数使用的的HttpClient 。但是,我总是得到的 404 错误。

第一个API函数端点:的http://本地主机:XXXXX / API /测试/)

 公开的Htt presponseMessage把(INT ID,INT帐户ID,字节[]的内容)
[...]

第2 API函数

 公开的Htt presponseMessage把(INT ID,INT援助的byte [] filecontent)
{
    WebRequestHandler处理程序=新WebRequestHandler()
    {
        AllowAutoRedirect =假,
        UseProxy = FALSE
    };    使用(HttpClient的客户端=新的HttpClient(处理))
    {
        client.BaseAddress =新的URI(HTTP://本地主机:XXXXX /);        //添加JSON格式的Accept头。
        client.DefaultRequestHeaders.Accept.Add(新MediaTypeWithQualityHeaderValue(应用/ JSON));        VAR参数=新对象[6];
        参数[0] = ID;
        参数[1] =/;
        参数[2] =援助=?;
        参数[3] =助剂;
        参数[4] =与&含量=;
        参数[5] = filecontent;        使用(HTT presponseMessage响应= client.PutAsJsonAsync(API /测试/,参数)。结果)
        {
            返回response.EnsureSuccessStatus code();
        }
    }
}

所以我的问题是。 我可以发表方法的参数从HttpClient的一个对象数组像我一样吗我不想为通模式作为方法的参数。

什么是错误的,我code?

无法得到任何回应,后变化code到

 返回client.PutAsJsonAsync(URI,filecontent)
           .ContinueWith< Htt的presponseMessage>
            (
               任务= GT; task.Result.EnsureSuccessStatus code()
            );

 返回client.PutAsJsonAsync(URI,filecontent)
           .ContinueWith
            (
               任务= GT; task.Result.EnsureSuccessStatus code()
            );


解决方案

正如你可能发现,没有你做不到。当你调用 PostAsJsonAsync 中,code将参数转换为JSON并在请求主体发送。您的参数是一个JSON阵列,这将类似于下面的数组:

  [1,/,援助?,345,&放大器; CONTENT =,aGVsbG8gd29ybGQ =]

这是不是第一个函数需要(至少这是我想象的,因为你还没有显示的路线信息)。有几个问题在这里:


  • 默认情况下,类型参数字节[] (引用类型)被传递在体内的请求,而不是在URI(除非你明确地标记与 [FromUri] 属性参数)。

  • 其他参数(同样,根据我对你的路线猜)必须是URI的一部分,而不是身体。

在code会是这个样子:

  VAR URI =API /测试/+身份证+?/援助=+援助;
使用(HTT presponseMessage响应= client.PutAsJsonAsync(URI,filecontent)。结果)
{
    返回response.EnsureSuccessStatus code();
}

现在,有与code以上的另一个潜在的问题。它等待的网络响应(也就是当您访问在任务&LT的。结果属性会发生什么; Htt的presponseMessage> PostAsJsonAsync 返回。根据环境的不同,可能发生更糟糕的是,它可能会死锁(在一个线程中的网络响应将抵达等待)。在最好的情况下,这个线程将被阻止网络电话,这也是不好的时间考虑使用异步模式(等待结果,返回任务< T> 在动作),而不是像在下面

的例子

 公共异步任务< Htt的presponseMessage>把(INT ID,INT援助的byte [] filecontent)
{
    // ...    VAR URI =API /测试/+身份证+?/援助=+援助;
    HTT presponseMessage响应=等待client.PutAsJsonAsync(URI,filecontent);
    返回response.EnsureSuccessStatus code();
}

或不异步/等待关键字:

 公共任务< Htt的presponseMessage>把(INT ID,INT援助的byte [] filecontent)
{
    // ...    VAR URI =API /测试/+身份证+?/援助=+援助;
    返回client.PutAsJsonAsync(URI,filecontent).ContinueWith< Htt的presponseMessage>(
        任务= GT; task.Result.EnsureSuccessStatus code());
}

I want to call Api function (1st) . from 2nd Api function using HttpClient. But I always get 404 Error.

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

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

2nd Api function

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

So My question is that. Can I post Method Parameter as an object array from HttpClient as I did ? I don't want to Pass model as method parameter.

What is the wrong in my code ?

Unable to get any response , after change code to

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

OR

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

解决方案

As you probably found out, no you can't. When you call PostAsJsonAsync, the code will convert the parameter to JSON and send it in the request body. Your parameter is a JSON array which will look something like the array below:

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

Which isn't what the first function is expecting (at least that's what I imagine, since you haven't showed the route info). There are a couple of problems here:

  • By default, parameters of type byte[] (reference types) are passed in the body of the request, not in the URI (unless you explicitly tag the parameter with the [FromUri] attribute).
  • The other parameters (again, based on my guess about your route) need to be part of the URI, not the body.

The code would look something like this:

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

Now, there's another potential issue with the code above. It's waiting on the network response (that's what happens when you access the .Result property in the Task<HttpResponseMessage> returned by PostAsJsonAsync. Depending on the environment, the worse that can happen is that it may deadlock (waiting on a thread in which the network response will arrive). In the best case this thread will be blocked for the duration of the network call, which is also bad. Consider using the asynchronous mode (awaiting the result, returning a Task<T> in your action) instead, like in the example below

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

Or without the async / await keywords:

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

这篇关于如何使用的HttpClient从网络API调用PUT方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆