Отримання вмісту / повідомлення від HttpResponseMessage


175

Я намагаюся отримати вміст HttpResponseMessage. Має бути так: {"message":"Action '' does not exist!","success":false}але я не знаю, як вийти з програми HttpResponseMessage.

HttpClient httpClient = new HttpClient();
HttpResponseMessage response = await httpClient.GetAsync("http://****?action=");
txtBlock.Text = Convert.ToString(response); //wrong!

У цьому випадку txtBlock матиме значення:

StatusCode: 200, ReasonPhrase: 'OK', Version: 1.1, Content: System.Net.Http.StreamContent, Headers:
{
  Vary: Accept-Encoding
  Keep-Alive: timeout=15, max=100
  Connection: Keep-Alive
  Date: Wed, 10 Apr 2013 20:46:37 GMT
  Server: Apache/2.2.16
  Server: (Debian)
  X-Powered-By: PHP/5.3.3-7+squeeze14
  Content-Length: 55
  Content-Type: text/html
}

Відповіді:


66

Вам потрібно зателефонувати GetResponse () .

Stream receiveStream = response.GetResponseStream ();
StreamReader readStream = new StreamReader (receiveStream, Encoding.UTF8);
txtBlock.Text = readStream.ReadToEnd();

33
Дякую, але чому я отримую цю помилку тут: "System.Net.Http.HttpResponseMessage" не містить визначення для "GetResponseStream" і немає методу розширення "GetResponseStream", який приймає перший аргумент типу "System.Net.Http.HttpResponseMessage" можна було знайти »
Клем

13
@Klemzy - Тому що ви називаєте це Асинхронічно. Спробуйте скористатися Contentвласністю. Подивіться приклад тут . Прокрутіть вниз до другого кроку.
Icemanind

2
@Klemzy - Подивіться приклад тут . Прокрутіть вниз до другого кроку. Якщо ви не можете цього зрозуміти, я відредагую свою відповідь і наведу приклад для вас
Icemanind

17
Ця відповідь є абсолютно поза темою, ОП використовує HttpClient, не HttpWebRequest/ HttpWebResponse.
Максим Россіні

1
Питання стосується HttpCient, ваша відповідь ґрунтується на застарілому та застарілому HttpWebRequest.
Пайям

370

Я думаю, що найпростіший підхід - це просто змінити останній рядок на

txtBlock.Text = await response.Content.ReadAsStringAsync(); //right!

Таким чином, вам не потрібно вводити жодних зчитувачів потоків, і вам не потрібні методи розширення.


5
Не впевнений, чому це не прийнята відповідь, тим більше, що це дає можливість легко серіалізувати вміст у ваші об’єкти.
Джейсон МакКіндлі

3
ReadAsStringAsync не справляється з помилками IMHO.
stannius

16
Ви також можете використовувати Response.Content.ReadAsStringAsync (). Результат замість того, щоб використовувати wait
Джастін

8
Але будьте обережні: ReadAsStringAsync () може кинути, якщо у відповіді є смайлики чи інші символи Unicode. Мені довелося використовувати Потоки (як у прийнятій відповіді), щоб подолати це.
Гінкго

41

Спробуйте це, ви можете створити такий спосіб розширення:

    public static string ContentToString(this HttpContent httpContent)
    {
        var readAsStringAsync = httpContent.ReadAsStringAsync();
        return readAsStringAsync.Result;
    }

а потім простий метод розширення виклику:

txtBlock.Text = response.Content.ContentToString();

Я сподіваюся, що це допоможе тобі ;-)


До сих пір легше отримати і працює
Оге

Будь ласка, використовуйте awaitзамість .Result... або використовуйте синхронний клієнт HTTP замість цього, якщо ваш код не може обробляти програму асинхронізації. Але будь-який сучасний код повинен, інакше це може бути ознакою того, що ваша програма робить щось не так.
Максим Россіні

9

Якщо ви хочете призначити його певному типу (наприклад, у тестах), ви можете використовувати метод розширення ReadAsAsync :

object yourTypeInstance = await response.Content.ReadAsAsync(typeof(YourType));

або наступне для синхронного коду:

object yourTypeInstance = response.Content.ReadAsAsync(typeof(YourType)).Result;

Оновлення: існує також загальна опція ReadAsAsync <>, яка повертає екземпляр конкретного типу замість оголошеного об'єктом:

YourType yourTypeInstance = await response.Content.ReadAsAsync<YourType>();

2
об'єкт yourTypeInstance = очікувати відповідь.Content.ReadAsAsync (typeof (YourType)); повинен бути var yourTypeInstance = очікувати відповіді.Content.ReadAsAsync <YourType> ();
Thomas.Benz

Я використав Request.Content.ReadAsAsync для розбору Json і отримав жахливу продуктивність.
W.Leto

4

За відповіді rudivonstaden

`txtBlock.Text = await response.Content.ReadAsStringAsync();`

але якщо ви не хочете робити метод асинхронізації, який ви можете використовувати

`txtBlock.Text = response.Content.ReadAsStringAsync();
 txtBlock.Text.Wait();`

Зачекайте () це важливо, оскільки ми робимо операції з асинхронізацією, і нам потрібно дочекатися виконання завдання, перш ніж йти вперед.


3
використовуючи .Resultбудь-які різні ?,httpContent.ReadAsStringAsync().Result
mkb

.Resultзаблокує виконання потоку в цьому рядку ... де як txtBlock.Text.Wait()блоки при виклику wait () ... тож ви правильні, що в основному різниці немає. Але я підозрюю, що txtBlock.Text.Wait()буде брати необов’язковий цілий параметр, щоб GUI не завис, якщо попередній ReadAsStringAsync()виклик ніколи не повернеться. Наприклад, наступне блокує не більше 1 секундиtxtBlock.Text.Wait(1000)
benhorgen

3

Я пропоную швидку відповідь:

response.Result.Content.ReadAsStringAsync().Result


НЕ закликайте Resultдо виконання завдань. Ви ризикуєте заблокувати заявку. Замість цього використовуйте async / wait.
eltiare

Я б не сказав ніколи ... інколи швидко і брудно це робиться. Але я погоджуюся, що ви ризикуєте ReadAsStringAsync()не повернутися, тому переконайтеся, що не викликати його у вашому графічному інтерфейсі чи основному потоці програми.
benhorgen

1

Я думаю, що наступне зображення допомагає тим, кому потрібно Tповернутися як тип повернення.

введіть тут опис зображення


0

Можна скористатися GetStringAsyncметодом:

var uri = new Uri("http://yoururlhere");
var response = await client.GetStringAsync(uri);
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.