Классы HttpWebRequest и HttpWebResponse
147C# и .NET --- Сетевое программирование --- Классы HttpWebRequest и HttpWebResponse
Среда .NET Framework предоставляет два основных класса, облегчающих доступ к HTTP: HttpWebRequest и HttpWebResponse. В этих классах в простой форме реализована значительная часть функциональных возможностей, предоставляемых протоколом HTTP. Они порождены от абстрактных классов WebRequest и WebResponse.
Чтобы познакомиться с работой этих классов, давайте рассмотрим пример, как их можно использовать для получения страницы из Интернета:
string site = "http://www.professorweb.ru";
HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(site);
HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
using (StreamReader stream = new StreamReader(
resp.GetResponseStream(), Encoding.UTF8))
{
txb_text.Text = stream.ReadToEnd();
}
Для создания объекта HttpWebRequest нужно вызвать статический метод Create() класса WebRequest (также наследуемый классом HttpWebRequest). Этот метод исследует формат переданного ему URI и по обстановке возвращает объект WebRequest, представляющий HTTP-запрос или запрос к файловой системе. Поскольку один и тот же метод используется для создания как HTTP-запроса, так и запроса к файловой системе, возвращаемый объект имеет тип WebRequest и его нужно привести к типу HttpWebRequest или FileWebRequest. Метод Create() выполняет разбор URL и передает его в объект запроса. Затем блок запроса строит исходящий HTTP-запрос и также формирует конфигурацию HTTP-заголовков.
Получив объект запроса, можно вызвать для него метод GetResponse(). Этот метод отправляет запрос серверу и возвращает объект WebResponse (надо снова привести его к типу HttpWebResponse). Этот объект представляет сообщение HTTP-ответа и содержит информацию HTTP-заголовков, в том числе ContentType, ContentLength, StatusCode и Cookies, и первую часть данных, которые помещаются во внутренний буфер и должны быть считаны из потока. Вместе с данными устанавливаются свойства объекта HttpWebResponse.
Далее с помощью метода GetResponseStream() получаем поток. Он указывает на текущий ответ от Web-cepвepa (тело сути ответного сообщения) в двоичном виде. Поток предоставляет значительную гибкость в реализации способов получения данных от Web-cepвepa. Чтобы извлечь текущие данные и получить с Web-cepвepa оставшуюся часть результирующего документа, нужно считать этот поток. В данном примере используем объект StreamReader, возвращающий строку с данными. Для кодировки установлен тип UTF8. Кодировка — это важный момент, поскольку передача данных потоком байтов без перекодирования приведет к неверным преобразованиям всех расширенных символов.
В приведенном примере используется метод ReadToEnd() объекта StreamReader, считывающий в строку все данные с Web-cepвepa. Однако данные можно также считывать по частям, если применить метод Read() того же объекта.
Установка и считывание HTTP-заголовков
В обоих классах, HttpWebRequest и HttpWebResponse, есть свойство Headers, возвращающее объект WebHeaderCollection, содержащий информацию о заголовках HTTP-сообщения. Вызывая метод Add() или метод Set() этого объекта, можно добавлять заголовки в HTTP-запрос:
HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(site);
req.Headers.Add("Accept-Language: ru-ru");
Как показывает приведенный пример, метод Add() принимает один строковый параметр, представляющий все поле заголовка, тогда как метод Set() принимает два строковых значения: имя заголовка и значение, которое хотим в нем установить. Оба метода можно равным образом использовать для стандартных и специализированных HTTP-заголовков. Однако в классе HttpWebRequest также есть несколько открытых свойств, позволяющих установить заголовок запроса без обращения к свойству Headers:
Свойство | Тип данных | HTTP-заголовок |
---|---|---|
Accept | string | Accept |
Connection | string | Connection |
ContentLength | long | Content-Length |
ContentType | string | Content-Type |
Expect | string | Expect |
IfModifiedSince | DateTime | If-Modified-Since |
Referer | string | Referer |
TransferEncoding | string | Transfer-Encoding |
UserAgent | string | User-Agent |
Например, чтобы сформировать заголовок User-Agent в виде "User-Agent: SimpleHttpClient", можно написать:
req.UserAgent = "SimpleHostClient";
Обратите внимание, что при наличии свойства установки заголовка следует обращаться именно к нему. Например, если попытаться установить заголовок User-Agent следующим образом:
req.Headers.Add("User-Agent: SimpleHostClient");
то при выполнении будет порождено исключение.
Объект HttpWebResponse также содержит несколько открытых свойств (все они доступны только на чтение), позволяющие обращаться к значениям выбранных HTTP-заголовков (ContentEncoding, ContentLength, ContentType, LastModified и Server).
К каждому отдельному полю заголовка также можно обратиться как к паре имя-значение в коллекции WebHeaderCollection. Имена заголовков являются ключами в коллекции, а значения заголовков — соответствующими значениями. Следовательно, можно обратиться к значению заголовка, используя в индексаторе коллекции имя заголовка. В следующем коде все заголовки ответа выводятся в текстовый элемент управления WPF:
foreach (string header in resp.Headers)
txb_text.Text += String.Format("{0}: {1}\n", header, resp.Headers[header]);
