C# httpwebrequest пустые символы в responsestream

Я пытаюсь прочитать ответ от веб-сервера, используя httpwebrequests в C#. Я использую следующий код:

UriBuilder urib = new UriBuilder();
urib.Host = "wikipedia.com";

HttpWebRequest req = WebRequest.CreateHttp(urib.Uri);
req.KeepAlive = false;
req.Host = "wikipedia.com/";
req.Method = "GET";

HttpWebResponse response = (HttpWebResponse) req.GetResponse();
byte[] buffer = new byte[response.ContentLength];
System.IO.Stream stream = response.GetResponseStream();
stream.Read(buffer, 0, buffer.Length);

Console.WriteLine(System.Text.Encoding.ASCII.GetString(buffer, 0, buffer.Length));

Код действительно получает правильный объем данных (я сравнил длину содержимого, использованного для создания буфера, с длиной вывода на консоль, они одинаковые. Моя проблема в том, что последние 80% или около того ответа пустые chars. Они все 0x00. Я проверил это на нескольких страницах, включая wikipedia.com, и по какой-то причине он просто обрезает середину файла.

Я неправильно понял / неправильно использовал веб-запросы или кто-нибудь может обнаружить ошибку здесь?

2 ответа

Решение

Попробуйте использовать этот метод:

public static String GetResponseString(Uri url, CookieContainer cc)
{
    HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
    request.Method = WebRequestMethods.Http.Get;
    request.CookieContainer = cc;
    request.AutomaticDecompression = DecompressionMethods.GZip;

    HttpWebResponse response = (HttpWebResponse)request.GetResponse();

    StreamReader reader = new StreamReader(response.GetResponseStream());

    String responseString = reader.ReadToEnd();

    response.Close();

    return responseString;
}

Есть несколько проблем с вашим кодом:

  1. Вы пытаетесь прочитать весь ответ за один раз, используя Stream.Read - это не то, для чего он был разработан. Это следует использовать для более оптимального чтения, например, фрагментов по 4 КБ.

  2. Вы читаете ответ HTML как кодировку ASCII - вы уверены, что на странице нет символов Unicode? Я бы придерживался кодировки UTF-8, чтобы быть на безопасной стороне (или альтернативно прочитать Content-Type заголовок в ответе).

При чтении символов из потока байтов (что является вашим response по сути) рекомендуемый подход заключается в использовании StreamReader. Более конкретно, если вы хотите прочитать весь поток за один раз, используйте StreamReader.ReadToEnd.

Ваш код может быть сокращен до:

HttpWebRequest req = WebRequest.CreateHttp(new Uri("http://wikipedia.org"));
req.Method = WebRequestMethods.Http.Get;
using (var response = (HttpWebResponse)req.GetResponse())
using (var reader = new StreamReader(response.GetResponseStream()))
{
    Console.WriteLine(reader.ReadToEnd());
}
Другие вопросы по тегам