Menerima data JSON kembali dari permintaan HTTP


91

Saya memiliki permintaan web yang berfungsi dengan baik, tetapi hanya mengembalikan status OK, tetapi saya membutuhkan objek yang saya minta untuk dikembalikan. Saya tidak yakin bagaimana cara mendapatkan nilai json yang saya minta. Saya baru menggunakan objek HttpClient, apakah ada properti yang saya lewatkan? Saya sangat membutuhkan objek yang kembali. Terima kasih atas bantuannya

Melakukan panggilan - berjalan dengan baik mengembalikan status 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;

Metode api get

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

Apakah Anda bertanya bagaimana cara mendapatkan konten respons saat menggunakan kelas .NET 4.5 HttpClient?
Panagiotis Kanavos

Jawaban:


162

Jika Anda merujuk ke System.Net.HttpClient di .NET 4.5, Anda bisa mendapatkan konten yang dikembalikan oleh GetAsync menggunakan properti HttpResponseMessage.Content sebagai objek yang berasal dari HttpContent . Anda kemudian dapat membaca konten ke string menggunakan metode HttpContent.ReadAsStringAsync atau sebagai aliran menggunakan metode ReadAsStreamAsync .

The HttpClient dokumentasi kelas meliputi contoh ini:

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

3
Belum menguji ini, tetapi dokumentasi EnsureSuccessStatusCode mengatakan "Jika Konten tidak null, metode ini juga akan memanggil Buang ke sumber daya yang dikelola dan tidak dikelola secara gratis." jadi Anda mungkin ingin membaca isinya terlebih dahulu. msdn.microsoft.com/en-us/library/…
Ryan Williams

4
Tidak ada alasan untuk ini. Seperti yang dibuktikan oleh Reflector, EnsureSuccessStatusCode HANYA akan membuang jika kode status tidak berhasil, tepat sebelum mengeluarkan pengecualian. Namun kasus lain di mana teks dokumentasinya sedikit membingungkan.
Panagiotis Kanavos

1
Kenapa tidak client.GetStringAsync(...)? Bukankah itu sekitar tahun 2012. Mereka berdua akan melakukan pengecualian jika tanggapannya tidak 200tepat?
Simon_Weaver

1
@ Simon_Weaver karena bukan itu pertanyaannya - OP bertanya bagaimana cara membaca string dari respon. Ada yang perbedaan. Anda tidak dapat memeriksa respons GetStringAsyncyang artinya Anda tidak tahu apa pesan respons itu. Anda mungkin tidak ingin membuang jika respons 3xx dikembalikan. Anda mungkin ingin mencoba lagi tanpa melempar jika kesalahan pembatasan kembali.
Panagiotis Kanavos

1
@Simon_Weaver ada banyak cara untuk menelepon - mengapa tidak GetAsync<T>? Atau GetStreamAsync dan teruskan streaming ke Json.NET, menghindari string sementara? Sekali lagi, mungkin lebih baik untuk menggunakan GetAsyncterlebih dahulu kemudian mengakses objek konten
Panagiotis Kanavos

40

Berdasarkan jawaban @Panagiotis Kanavos , berikut adalah metode kerja sebagai contoh yang juga akan mengembalikan respons sebagai objek, bukan string:

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

Ingatlah bahwa ini hanya sebuah contoh dan Anda mungkin ingin menggunakannya HttpClientsebagai instance bersama daripada menggunakannya dalam klausa penggunaan.


Hati-hati httpclient tidak membuang seperti itu dengan menggunakan statment
rogue39nin

Sejak await segera kembali, apakah mungkin itu if (response != null)dijalankan sebelum panggilan pos selesai?
Nishant


7

Menurut saya cara terpendek adalah:

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

7
Hanya berpikir id menambahkan bahwa ReadAsAsync adalah metode ekstensi. Anda perlu menggunakan System.Net.Http.Formatting untuk .net 4+ dan Microsoft.AspNet.WebApi.Client untuk .net core. agar ini berfungsi.
lembut

0

Apa yang biasanya saya lakukan, mirip dengan yang menjawab:

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

Di mana 'model' adalah kelas model C # Anda.


0

Ini bekerja dengan baik untuk saya dengan cara berikut -

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;
    }
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.