web-dev-qa-db-ja.com

HttpClient.PostAsyncにオブジェクトを渡してJSONボディとしてシリアル化する方法を教えてください。

私はSystem.Net.Httpを使用しています、私はウェブ上でいくつかの例を見つけました。私はPOSTリクエストを作るためにこのコードを作成することに成功しました:

public static string POST(string resource, string token)
{
    using (var client = new HttpClient())
    {
        client.BaseAddress = new Uri(baseUri);
        client.DefaultRequestHeaders.Add("token", token);

        var content = new FormUrlEncodedContent(new[]
        {
             new KeyValuePair<string, string>("", "")
        });

        var result = client.PostAsync("", content).Result;
        string resultContent = result.Content.ReadAsStringAsync().Result;
        return resultContent;
    }
 }

すべてうまくいきました。しかし、POSTメソッドに3番目のパラメーター、dataというパラメーターを渡したいとします。データパラメータは次のようなオブジェクトです。

object data = new
{
    name = "Foo",
    category = "article"
};

どのように私はKeyValuePairを作成せずにそれを行うことができますか?私のphp RestAPIはjson入力を待つので、FormUrlEncodedContentraw jsonを正しく送信するはずです。しかし、どうすればこれをMicrosoft.Net.Httpで行うことができますか?ありがとう。

59
IlDrugo

あなたの質問に対する直接的な答えは次のとおりです。いいえ。 PostAsync メソッドのシグネチャは次のとおりです。

公開タスクPostAsync(Uri requestUri、HttpContentコンテンツ)

そのため、objectPostAsyncに渡すことはできますが、HttpContent型である必要があり、匿名型はその基準を満たしていません。

ただし、達成したいことを達成する方法はあります。まず、あなたの匿名型をJSONにシリアライズする必要があります。このための最も一般的なツールは Json.NET です。そしてこれのためのコードはかなり簡単です:

var myContent = JsonConvert.SerializeObject(data);

次に、このデータを送信するためのコンテンツオブジェクトを作成する必要があります。ByteArrayContentオブジェクトを使用しますが、必要に応じて別の種類を使用または作成することもできます。

var buffer = System.Text.Encoding.UTF8.GetBytes(myContent);
var byteContent = new ByteArrayContent(buffer);

次に、これがJSONであることをAPIに知らせるようにコンテンツタイプを設定します。

byteContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");

その後、フォームの内容を使用して、前の例と非常によく似た要求を送信できます。

var result = client.PostAsync("", byteContent).Result

ちなみに、ここで行っているように.Resultプロパティを呼び出すと、デッドロックなどの 悪い副作用 が発生する可能性があるので、これには注意してください。

103
CodingGorilla

FormUrlEncodedContentではなく生の文字列としてデータをリクエストボディに渡す必要があります。そのための1つの方法は、それをJSON文字列にシリアル化することです。

var json = JsonConvert.SerializeObject(data);

あとはpostメソッドに文字列を渡すだけです。

var stringContent = new StringContent(json, UnicodeEncoding.UTF8, "application/json");

var client = new HttpClient();
var response = await client.PostAsync(uri, stringContent);
35
elolos

簡単な解決策は NuGetMicrosoft ASP.NET Web API 2.2 Clientを使うことです。

その後、これを実行するだけで、オブジェクトをJSONにシリアル化し、Content-Typeヘッダーをapplication/json; charset=utf-8に設定します。

var data = new
{
    name = "Foo",
    category = "article"
};

var client = new HttpClient();
client.BaseAddress = new Uri(baseUri);
client.DefaultRequestHeaders.Add("token", token);
var response = await client.PostAsJsonAsync("", data);
24
trydis

.NET Standardまたは.NET Coreを使ったもっと簡単な方法があります。

var client = new HttpClient();
var response = await client.PostAsync(uri, myRequestObject, new JsonMediaTypeFormatter());

注:JsonMediaTypeFormatterクラスを使用するには、Microsoft.AspNet.WebApi.Client NuGetパッケージをインストールする必要があります。これは直接インストールすることも、Microsoft.AspNetCore.Appなどの別の方法でインストールすることもできます。

このHttpClient.PostAsyncのシグネチャを使用して、任意のオブジェクトを渡すことができ、JsonMediaTypeFormatterは自動的にシリアル化などの処理を行います。

レスポンスでは、HttpContent.ReadAsAsync<T>を使用してレスポンスの内容を期待している型にデシリアライズできます。

var responseObject = await response.Content.ReadAsAsync<MyResponseType>();
10
Ken Lyon