3

HttpClientを使用してWebAPIメソッドに対してPUTリクエストを実行しようとしています。ほぼ同じPOSTリクエストが期待どおりに機能しますが、PUTリクエストの結果は400(Bad Request)エラーになります。何が間違っているのかわかりません。

これが私のWebAPIコントローラーコードです。

public HttpResponseMessage Post(object val)
{
    Debug.WriteLine(val.ToString());
    return new HttpResponseMessage(HttpStatusCode.OK);
}

public HttpResponseMessage Put(int id, object val)
{
    Debug.WriteLine(id.ToString(), val.ToString());
    return new HttpResponseMessage(HttpStatusCode.OK);
}

そして、これらのメソッドを呼び出そうとするクライアント側のコードを次に示します。POSTリクエストは次のようになります。

var client = new HttpClient();
var content = log.ToJsonContent();
var address = new Uri(_webApiBaseAddress + "logs");

client.PostAsync(address, content).ContinueWith(requestTask =>
    {
        requestTask.Result.EnsureSuccessStatusCode();
    });

そして、機能しないPUTリクエストは次のようになります。

var client = new HttpClient();
var content = log.ToJsonContent();
var address = new Uri(_webApiBaseAddress + "logs/" + jobId);

client.PutAsync(address, content).ContinueWith(requestTask =>
    {
        requestTask.Result.EnsureSuccessStatusCode();
    });

ご覧のとおり、機能を可能な限り削除しましたが、毎回PUTリクエストでエラーが発生します。

ちなみに、RestSharpクライアントを使用してPUTリクエストを正常に行うことができます。このコードは、APIメソッドを正常に呼び出します。

var client = new RestClient(_webApiBaseAddress);
var request = new RestRequest("logs/{id}", Method.PUT);
request.AddUrlSegment("id", jobId.ToString());
request.AddObject(log);
client.Execute(request);

この方法で行うことの問題は、AddObjectを使用して渡したオブジェクトが、コントローラーメソッドに到達したときに文字列になってしまうことです。intを渡す場合、intを取得したいと思います。HttpClientはPOSTメソッドでこれを行うので、それを使用したかったのですが、PUTはエラーをスローします。そのため、残念ながら、完全なソリューションにはならない2つの半ば機能するソリューションで立ち往生しています。これを機能させるために、どちらのパターンについてもフィードバックをいただければ幸いです。

編集: それは以下に言及されたので、ここに私の.ToJsonContent()拡張メソッドがあります:

public static StringContent ToJsonContent(this object obj)
{
    var converter = new IsoDateTimeConverter();
    converter.DateTimeStyles = DateTimeStyles.AdjustToUniversal;
    var json = JsonConvert.SerializeObject(obj, converter);
    var content = new StringContent(json, Encoding.UTF8, "application/json");
    return content;
}
4

1 に答える 1

5

あなたが書いた機能ですかToJsonContent?もしそうなら、正しい Content-Type を提供し、適切な JSON 形式を生成していることを確認するために、それを見る価値があるかもしれません。問題である JSON を排除するには、次のようなテストを実行できます。

var client = new HttpClient();
var content = new StringContent(
    @"{""message"": ""this is a log message"" }",
    Encoding.UTF8,
    "application/json");

var address = new Uri(_webApiBaseAddress + "logs/" + jobId);

client.PutAsync(address, content).ContinueWith(task =>
{
    task.Result.EnsureSuccessStatusCode();
});

パラメータapplication/jsonとして指定します。リクエストのメディア タイプがわからない場合、Web API はおかしなことをすることはわかってます。

役立つかもしれない 2 番目の部分は、非同期呼び出しが実際に初期化されて送信される前に閉じる可能性があるコンソール アプリのようなものでこれをテストしている場合、応答が得られないことです。.Wait()の後に a を付けるだけでこれをテストできますContinueWithが、実際に 400 応答を受け取っている場合は、そうではないと思います。

于 2012-05-17T20:24:32.073 に答える