Получение контента / сообщения от 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();
Icemanind
источник
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.
Payam
371

Я думаю, что самый простой подход - это просто изменить последнюю строку на

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

Таким образом, вам не нужно вводить потоковые ридеры и вам не нужны никакие методы расширения.

rudivonstaden
источник
5
Не уверен, почему это не принятый ответ, тем более что это дает вам возможность легко сериализовать содержимое в ваши объекты.
Джейсон Маккиндли
3
ReadAsStringAsync не обрабатывает ошибки хорошо IMHO.
Станниус
16
Вы также можете использовать Response.Content.ReadAsStringAsync (). Результат вместо использования await
Джастин
8
Однако будьте осторожны: ReadAsStringAsync () может выдавать, если в ответе есть смайлики или другие символы Юникода. Мне пришлось использовать потоки (как в принятом ответе), чтобы преодолеть это.
Гинкго
41

Попробуйте это, вы можете создать метод расширения следующим образом:

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

а затем просто вызовите метод расширения:

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

Я надеюсь, что это поможет вам ;-)

MCurbelo
источник
До сих пор легче получить и работает
Оге
Пожалуйста, используйте 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>();
тарас-mytofir
источник
2
object yourTypeInstance = await response.Content.ReadAsAsync (typeof (YourType)); должно быть var yourTypeInstance = await response.Content.ReadAsAsync <YourType> ();
Thomas.Benz
Я использовал Request.Content.ReadAsAsync для анализа Json и получил ужасную производительность.
W.Leto
4

К ответу из Рудивонстадена

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

но если вы не хотите делать метод асинхронным, вы можете использовать

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

Wait () это важно, потому что мы выполняем асинхронные операции, и мы должны дождаться завершения задачи, прежде чем идти дальше.

stanimirsp
источник
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

benhorgen
источник
НЕ вызывайте Resultна задачи. Вы рискуете заблокировать свое приложение. Вместо этого используйте async / await.
Эльтиаре
Я бы не сказал никогда ... иногда быстро и грязно это делается. Но я согласен, что вы рискуете ReadAsStringAsync()не вернуться, поэтому не вызывайте его в своем графическом интерфейсе или в главном потоке приложений.
Бенхорген
1

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

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

ОСШ
источник
0

Вы можете использовать GetStringAsyncметод:

var uri = new Uri("http://yoururlhere");
var response = await client.GetStringAsync(uri);
Hinrich
источник