Отримання даних JSON назад із запиту HTTP


91

У мене є веб-запит, який працює належним чином, але він просто повертає статус ОК, але мені потрібен об’єкт, про який я прошу, щоб він повернувся. Я не впевнений, як отримати запитуване значення json. Я новачок у використанні об'єкта HttpClient, чи є властивість, яку я втрачаю? Мені дуже потрібен предмет, що повертається. Дякую за будь-яку допомогу

Здійснення дзвінка - нормальний запуск повертає стан ОК.

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

Відповіді:


162

Якщо ви маєте на увазі 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
Не тестував цього, але в документації EnsureSuccessStatusCode сказано: "Якщо Вміст не є нульовим, цей метод також викликає Dispose для звільнення керованих та некерованих ресурсів." тож ви можете спочатку прочитати вміст. msdn.microsoft.com/en-us/library/…
Райан Вільямс,

4
Причин для цього немає. Як засвідчує Reflector, EnsureSuccessStatusCode розпоряджається ТІЛЬКИ, якщо код стану невдалий, безпосередньо перед створенням винятку. Ще один випадок, коли текст документації трохи заплутаний.
Панайотис Канавос,

1
Чому не просто client.GetStringAsync(...)? Хіба цього не було в 2012 році. Вони обидва мали б зробити виняток, якщо відповідь була 200неправильною?
Simon_Weaver

1
@Simon_Weaver, бо не в цьому було питання - ОП запитало, як прочитати рядок із відповіді. Там є відмінність. Ви не можете перевірити відповідь, GetStringAsyncщо означає, що ви не знаєте, яким було відповідь. Ви, мабуть , не хочете кидати, якщо повертається відповідь 3xx. Можливо, ви захочете повторити спробу, не кидаючи, якщо буде повернуто помилку дроселювання.
Панайотис Канавос,

1
@Simon_Weaver існує безліч способів здійснити цей дзвінок - чому б і ні GetAsync<T>? Або GetStreamAsync і передати потік на Json.NET, уникаючи тимчасового рядка? Знову ж таки, може бути кращим використовувати GetAsyncспочатку, а потім отримати доступ до об’єкта вмісту
Panagiotis Kanavos

40

Спираючись на відповідь @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 не розпоряджається так із використанням
статуту

Оскільки await повертається негайно, можливо, це if (response != null)буде виконано до завершення поштового дзвінка?
Nishant

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-receiving-json-using-httpclient-with-system-net-http-json


7

Я думаю, що найкоротший шлях:

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
Просто подумав, що додаю, що ReadAsAsync - це метод розширення. вам потрібно буде використовувати System.Net.Http.Formatting для .net 4+ та Microsoft.AspNet.WebApi.Client для .net core. щоб це працювало.
Squibly

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

Де 'модель' - це ваш клас моделі 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;
    }
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.