HTTPリクエストからJSONデータを受信する


97

正常に機能しているWebリクエストがありますが、ステータスOKを返しているだけですが、返すように要求しているオブジェクトが必要です。要求しているjson値を取得する方法がわかりません。オブジェクトHttpClientを使用するのは初めてですが、見逃しているプロパティはありますか?私は本当に戻りオブジェクトが必要です。助けてくれてありがとう

電話をかける-正常に実行すると、ステータスOKが返されます。

HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Accept
  .Add(new MediaTypeWithQualityHeaderValue("application/json"));
var responseMsg = client.GetAsync(string.Format("http://localhost:5057/api/Photo")).Result;

APIgetメソッド

//Cut out alot of code but you get the idea
public string Get()
{
    return JsonConvert.SerializeObject(returnedPhoto);
}

.NET 4.5 HttpClientクラスを使用するときに応答コンテンツを取得する方法を尋ねていますか?
Panagiotis Kanavos 2012年

回答:


168

あなたは.NET 4.5でSystem.Net.HttpClientを参照している場合は、使用してGetAsyncによって返されたコンテンツを取得することができますHttpResponseMessage.Contentとしての特性をHttpContent由来オブジェクト。次に、HttpContent.ReadAsStringAsyncメソッドを使用してコンテンツを文字列に読み取るか、ReadAsStreamAsyncメソッドを使用してストリームとして読み取ることができます。

HttpClientをクラスのドキュメントは、この例が含まれています。

  HttpClient client = new HttpClient();
  HttpResponseMessage response = await client.GetAsync("http://www.contoso.com/");
  response.EnsureSuccessStatusCode();
  string responseBody = await response.Content.ReadAsStringAsync();

3
これはテストされていませんが、EnsureSuccessStatusCodeのドキュメントには、「コンテンツがnullでない場合、このメソッドはDisposeを呼び出して、管理対象リソースと管理対象外リソースを解放します」と記載されています。そのため、最初にコンテンツを読むことをお勧めします。 msdn.microsoft.com/en-us/library/…–
Ryan Williams

4
これには理由がありません。Reflectorで証明されているように、EnsureSuccessStatusCodeは、例外をスローする直前に、ステータスコードが失敗した場合にのみ破棄します。ドキュメントのテキストが少し混乱しているさらに別のケース。
Panagiotis Kanavos 2013年

1
なぜだけではないのclient.GetStringAsync(...)ですか?それは2012年頃ではありませんでした。応答が200正しくなかった場合、両方とも例外をスローしますか?
Simon_Weaver

1
@Simon_Weaverはそれが問題ではなかったので、OPは応答から文字列を読み取る方法を尋ねました。違いがあります。応答を検査することはできませんGetStringAsync。つまり、応答メッセージが何であったかがわかりません。3xx応答が返された場合は、おそらくスローしたくないでしょう。スロットルエラーが返された場合は、スローせずに再試行することをお勧めします。
PanagiotisKanavos18年1

1
@Simon_Weaverその呼び出しを行う方法はたくさんあります-なぜGetAsync<T>ですか?または、GetStreamAsyncを使用して、一時的な文字列を避けてストリームをJson.NETに渡しますか?繰り返しになりGetAsyncますが、最初に使用してからコンテンツオブジェクトにアクセスする方が望ましい場合があります
PanagiotisKanavos18年1

43

@Panagiotis Kanavosの回答に基づいて、文字列ではなくオブジェクトとして応答を返す例としての作業メソッドを次に示します。

using System.Text;
using System.Net.Http;
using System.Threading.Tasks;
using Newtonsoft.Json; // Nuget Package

public static async Task<object> PostCallAPI(string url, object jsonObject)
{
    try
    {
        using (HttpClient client = new HttpClient())
        {
            var content = new StringContent(jsonObject.ToString(), Encoding.UTF8, "application/json");
            var response = await client.PostAsync(url, content);
            if (response != null)
            {
                var jsonString = await response.Content.ReadAsStringAsync();
                return JsonConvert.DeserializeObject<object>(jsonString);
            }
        }
    }
    catch (Exception ex)
    {
        myCustomLogger.LogException(ex);
    }
    return null;
}

これは単なる例でありHttpClient、using句で使用するのではなく、共有インスタンスとして使用することをお勧めします。


して気をつけHTTPClientの使用なステートメントでそのように処分していません
rogue39nin

awaitはすぐに戻るのでif (response != null)、ポストコールが完了する前に実行される可能性はありますか?
ニシャント

10

このnugetパッケージをMicrosoftからインストールしますSystem.Net.Http.Json。拡張メソッドが含まれています。

それから加えて using System.Net.Http.Json

これで、次のメソッドを確認できるようになります。

ここに画像の説明を入力してください

だからあなたは今これを行うことができます:

await httpClient.GetFromJsonAsync<IList<WeatherForecast>>("weatherforecast");

ソース:https//www.stevejgordon.co.uk/sending-and-receiveing-json-using-httpclient-with-system-net-http-json


8

最短の方法は次のとおりです。

var client = new HttpClient();
string reqUrl = $"http://myhost.mydomain.com/api/products/{ProdId}";
var prodResp = await client.GetAsync(reqUrl);
if (!prodResp.IsSuccessStatusCode){
    FailRequirement();
}
var prods = await prodResp.Content.ReadAsAsync<Products>();

8
idは、ReadAsAsyncが拡張メソッドであることを追加すると考えました。.net 4+にはSystem.Net.Http.Formattingを使用し、.netCoreにはMicrosoft.AspNet.WebApi.Clientを使用する必要があります。これを機能させるために。
おそらく

0

答え1と同様に、私が通常行うこと:

var response = await httpClient.GetAsync(completeURL); // http://192.168.0.1:915/api/Controller/Object

if (response.IsSuccessStatusCode == true)
    {
        string res = await response.Content.ReadAsStringAsync();
        var content = Json.Deserialize<Model>(res);

// do whatever you need with the JSON which is in 'content'
// ex: int id = content.Id;

        Navigate();
        return true;
    }
    else
    {
        await JSRuntime.Current.InvokeAsync<string>("alert", "Warning, the credentials you have entered are incorrect.");
        return false;
    }

ここで、「model」はC#モデルクラスです。


0

それは私にとって次のようにうまく機能しています-

public async Task<object> TestMethod(TestModel model)
    {
        try
        {
            var apicallObject = new
            {
                Id= model.Id,
                name= model.Name
            };

            if (apicallObject != null)
            {
                var bodyContent = JsonConvert.SerializeObject(apicallObject);
                using (HttpClient client = new HttpClient())
                {
                    var content = new StringContent(bodyContent.ToString(), Encoding.UTF8, "application/json");
                    content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
                    client.DefaultRequestHeaders.Add("access-token", _token); // _token = access token
                    var response = await client.PostAsync(_url, content); // _url =api endpoint url
                    if (response != null)
                    {
                        var jsonString = await response.Content.ReadAsStringAsync();

                        try
                        {
                            var result = JsonConvert.DeserializeObject<TestModel2>(jsonString); // TestModel2 = deserialize object
                        }
                        catch (Exception e){
                            //msg
                            throw e;
                        }
                    }
                }
            }
        }
        catch (Exception ex)
        {
            throw ex;
        }
        return null;
    }
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.