web-dev-qa-db-ja.com

HttpClientを使用してWebApiからPUTメソッドを呼び出す方法は?

Api関数(1st)を呼び出したい。 HttpClientを使用して2番目のApi関数から。しかし、私は常に404エラーを受け取ります。

1番目のApi関数EndPoint: http:// localhost:xxxxx/api/Test /)

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

2番目の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()
            );

OR

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

おそらくお気づきかもしれませんが、できません。 PostAsJsonAsyncを呼び出すと、コードはパラメーターをJSONに変換し、リクエスト本文で送信します。パラメータはJSON配列であり、次の配列のようになります。

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

これは最初の関数が期待していることではありません(少なくとも、ルート情報を表示していないので、私が想像していることです)。ここにはいくつかの問題があります。

  • デフォルトでは、タイプbyte[](参照タイプ)のパラメーターは、URIではなくリクエストのbodyで渡されます(パラメーターに[FromUri]属性を明示的にタグ付けしない限り)。
  • 他のパラメーター(これも、ルートに関する私の推測に基づく)は、本体ではなくURIの一部である必要があります。

コードは次のようになります。

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

さて、上記のコードには別の潜在的な問題があります。ネットワーク応答を待機しています(PostAsJsonAsyncによって返される.ResultTask<HttpResponseMessage>プロパティにアクセスすると発生します。環境によっては、デッドロックが発生する可能性があります(スレッドを待機している)ネットワーク応答が到着します)。最良の場合、このスレッドはネットワーク呼び出しの間ブロックされますが、これも悪いことです。代わりに、非同期モード(結果を待って、アクションでTask<T>を返す)を使用することを検討してください。以下の例

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