รับข้อมูล JSON กลับจากคำขอ HTTP


97

ฉันมีคำขอทางเว็บที่ทำงานได้อย่างถูกต้อง แต่มันเพิ่งคืนสถานะตกลง แต่ฉันต้องการวัตถุที่ฉันขอให้ส่งคืน ฉันไม่แน่ใจว่าจะรับค่า 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;

เมธอด api get

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

คุณกำลังถามว่าจะรับเนื้อหาตอบกลับเมื่อใช้คลาส. NET 4.5 HttpClient ได้อย่างไร?
Panagiotis Kanavos

คำตอบ:


168

หากคุณอ้างถึง System.Net.HttpClient ใน. NET 4.5 คุณสามารถรับเนื้อหาที่ส่งคืนโดย GetAsync โดยใช้คุณสมบัติHttpResponseMessage.Contentเป็นวัตถุHttpContent -derived จากนั้นคุณสามารถอ่านเนื้อหาเป็นสตริงโดยใช้เมธอด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
ยังไม่ได้ทดสอบ แต่เอกสารของ SureSuccessStatusCode ระบุว่า "หากเนื้อหาไม่เป็นโมฆะเมธอดนี้จะเรียก Dispose เพื่อปลดปล่อยทรัพยากรที่มีการจัดการและไม่มีการจัดการ" ดังนั้นคุณอาจต้องการอ่านเนื้อหาก่อน msdn.microsoft.com/en-us/library/…
Ryan Williams

4
ไม่มีเหตุผลสำหรับเรื่องนี้ ตามหลักฐานจาก Reflector, SureSuccessStatusCode จะกำจัดเฉพาะในกรณีที่รหัสสถานะไม่สำเร็จก่อนที่จะโยนข้อยกเว้น อีกกรณีหนึ่งที่ข้อความในเอกสารมีความสับสนเล็กน้อย
Panagiotis Kanavos

1
ทำไมไม่เพียงclient.GetStringAsync(...)? นั่นไม่ได้เกิดขึ้นในปี 2012 ทั้งคู่จะมีข้อยกเว้นหากการตอบสนองไม่200ถูกต้อง?
Simon_Weaver

1
@Simon_Weaver เพราะนั่นไม่ใช่คำถาม - OP ถามวิธีอ่านสตริงจากคำตอบ มีมีความแตกต่าง คุณไม่สามารถตรวจสอบการตอบสนองGetStringAsyncซึ่งหมายความว่าคุณไม่รู้ว่าข้อความตอบกลับคืออะไร คุณคงไม่อยากโยนถ้าตอบกลับ 3xx คุณอาจต้องการลองอีกครั้งโดยไม่ขว้างหากมีการส่งคืนข้อผิดพลาดในการควบคุมปริมาณ
Panagiotis Kanavos

1
@Simon_Weaver มีหลายวิธีในการโทร - ทำไมไม่GetAsync<T>? หรือ GetStreamAsync และส่งกระแสข้อมูลไปยัง Json.NET หลีกเลี่ยงสตริงชั่วคราว? อีกครั้งอาจดีกว่าที่จะใช้GetAsyncก่อนแล้วจึงเข้าถึงวัตถุเนื้อหา
Panagiotis Kanavos

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เป็นอินสแตนซ์ที่ใช้ร่วมกันแทนที่จะใช้ในคำสั่งuse -clause


ระวัง httpclient ไม่ทิ้งแบบนั้นด้วยการใช้
สถิติ

เนื่องจากรอการส่งคืนทันทีเป็นไปได้ไหมที่if (response != null)จะดำเนินการก่อนที่การโพสต์จะเสร็จสิ้น
Nishant

11

ติดตั้งแพคเกจ nuget นี้จาก System.Net.Http.JsonMicrosoft มันมีวิธีการขยาย

จากนั้นเพิ่ม using System.Net.Http.Json

ตอนนี้คุณจะสามารถเห็นวิธีการเหล่านี้:

ป้อนคำอธิบายภาพที่นี่

ตอนนี้คุณสามารถทำได้:

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

ที่มา: https://www.stevejgordon.co.uk/sending-and-receiving-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 เป็นวิธีการขยาย คุณจะต้องใช้ System.Net.Http.Formatting สำหรับ. net 4+ และ Microsoft.AspNet.WebApi.Client สำหรับ. net core เพื่อให้ได้ผล
63

0

ปกติฉันทำอะไรคล้ายกับตอบข้อหนึ่ง:

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.