Опубликован: 02.08.2013 | Доступ: свободный | Студентов: 464 / 16 | Длительность: 18:38:00
Специальности: Программист
Самостоятельная работа 8:

Работа webClient и HttpWebRequest

HttpWebRequest

Рассмотрим работу с HttpWebRequest на примере приложения, размещенного в библиотеке кода MSDN "Работа с сервисом прогнозирования погоды" ("Weathen Forecast Sample"). Загрузить пример можно здесь: http://code.msdn.microsoft.com/Weather-Forecast-Sample-586ef733.

В приложении (Рис. 29.2) используются две страницы, одна из них, MainPage.xaml, выводит список городов, при касании строки, соответствующей городу, осуществляется переход на страницу ForecastPage.xaml, на которой отображается подробный прогноз погоды для выбранного города. В приложении используется несколько вспомогательных классов.

Проект приложения, работающего с HttpWebRequest

увеличить изображение
Рис. 29.2. Проект приложения, работающего с HttpWebRequest

Нужно отметить, что целевая платформа для данного приложения – Windows Phone 7.1. С проектами таких приложений можно работать в Visual Studio 2012, в частности, если планируется развитие приложения, дополнение его функциональнми возможностями, характерными для платформы Windows Phone 8, можно повысить версию платформы, открыв, таким образом, доступ к новым возможностям. Для этого нужно открыть контекстное меню проекта, выбрать в нём команду Свойства и на странице Приложение окна свойств установить параметр Целевая версия ОС Windows Phone в значение Windows Phone OS 8.0. При этом (рис. 29.3) система предупредит о том, что операция это необратима, что предварительно необходимо создать резервную копию файлов проекта.

Запрос на обновление версии платформы приложения

увеличить изображение
Рис. 29.3. Запрос на обновление версии платформы приложения

Для обновления проекта достаточно нажать на кнопку Да в появившемся окне. В данном случае преобразование прошло нормально, приложение сохранило работоспособность. В ходе подобного преобразования следует учитывать то, что хотя большинство механизмов платформ совместимо, в реализации некоторых API имеются различия, которые могут помешать нормальной работе приложения без дополнительных усилий по приведению приложения в надлежащий вид.

В приложении, для отображения данных в интерфейсе, использованы привязки данных. В файле City.cs определена базовая структура данных для хранения сведений о городе, для которого можно вывести информацию о погоде, в файле Cities.cs формируется список городов для вывода на главную страницу. Вспомогательный класс ForecastPeriod.cs определяет структуру данных для хранения прогноза погоды за определенный период. Основной функционал приложения, который, кроме прочего, подразумевает использование HttpWebRequest и сопутствующих механизмов для получения данных из службы прогнозов погоды, реализован в файле Forecast.cs.

На странице MainPage выводится список городов, он выводится в списке, источник элементов которого устанавливается на объект типа Cities, объявленный в классе App. При прикосновении к элементу вызывается, с параметрами, соответствующими выбранному городу, страница ForecastPage.

В файле кода этой страницы определен объект типа Forecast, при переходе на страницу, в событии OnNavigatedTo, извлекаются параметры, переданные ей при переходе на неё с главной страницы, после чего создаётся новый объект типа Forecast и вызывается его метод GetForecast с указанием долготы и широты выбранного города. Этот объект устанавливается в качестве контекста данных страницы. Его поле ForecastList устанавливается в качестве источника данных для списка, содержащегося на странице и отображающего прогноз погоды.

В конструкторе класса Forecast инициализируется его поле ForecastList. Далее, если следовать ходу исполнения приложения, вызывается метод GetForecast объекта Forecast. В Листинге 15.4 приведен фрагмент кода файла Forecast.cs, который иллюстрирует работу с HttpWebRequest от момента создания URI до получения XML-данных, которые подвергаются затем разбору. Здесь же находится объявление класса ForecastUpdateState, расположенное в том же файле

        public void GetForecast(string latitude, string longitude)
        {
            // Формирование URI
            UriBuilder fullUri = new UriBuilder("http://forecast.weather.gov/MapClick.php");
            fullUri.Query = "lat=" + latitude + "&lon=" + longitude + "&FcstType=dwml";

            // Инициализация нового объекта WebRequest
            HttpWebRequest forecastRequest = (HttpWebRequest)WebRequest.Create(fullUri.Uri);

            // объект с информацией о состоянии для асинхронного запроса
            ForecastUpdateState forecastState = new ForecastUpdateState();
            forecastState.AsyncRequest = forecastRequest;

            // Запуск асинхронного запроса
            forecastRequest.BeginGetResponse(new AsyncCallback(HandleForecastResponse),
                forecastState);
        }

        /// <summary>
        /// Обработка информации, полученной от асинхронного запроса
        /// </summary>
        /// <param name="asyncResult"></param>
        private void HandleForecastResponse(IAsyncResult asyncResult)
        {
            // информация о состоянии
            ForecastUpdateState forecastState = (ForecastUpdateState)asyncResult.AsyncState;
            HttpWebRequest forecastRequest = (HttpWebRequest)forecastState.AsyncRequest;

            // end the async request
            forecastState.AsyncResponse = (HttpWebResponse)forecastRequest.EndGetResponse(asyncResult);

            Stream streamResult;

            string newCredit = "";
            string newCityName = "";
            int newHeight = 0;

            // create a temp collection for the new forecast information for each 
            // time period
            ObservableCollection<ForecastPeriod> newForecastList =
                new ObservableCollection<ForecastPeriod>();

            try
            {
                // get the stream containing the response from the async call
                streamResult = forecastState.AsyncResponse.GetResponseStream();

                // load the XML
                XElement xmlWeather = XElement.Load(streamResult);
…
      /// <summary>
    /// Информация о состоянии для асинхронного вызова BeginGetResponse 
    /// </summary>
    public class ForecastUpdateState
    {
        public HttpWebRequest AsyncRequest { get; set; }
        public HttpWebResponse AsyncResponse { get; set; }
    }
Листинг 29.4. Фрагмент кода файла Forecast.cs

Здесь сначала формируется строка запроса к веб-сервису, которая включает в себя адрес службы и параметры, передаваемые в запросе. Далее создаётся новый HttpWebRequest forecastRequest, который создается на основе объекта WebRequest. На данном этапе, кроме того, можно настроить дополнительные параметры запроса, например – HTTP-заголовки. Далее, выполняется сохранение сформированного HttpRequest в объекте типа forecastState. Определение этого типа можно найти в нижней части кода, здесь объявлено два открытых поля, они используются для хранения объекта запроса (HttpWebRequest) и ответа (HttpWebResponse). На данном этапе его поле AsyncResponse не хранит никакого значения, оно используется при разборе ответа сервера.

Затем выполняется асинхронный вызов BeginGetResponse. В вызов передаётся делегат AsyncCallback, который ссылается на метод, который должен быть вызван при завершении асинхронной операции. Второй параметр вызова – это объект forecastState, который на данный момент хранит ссылку на объект запроса в поле AsyncRequest.

Когда асинхронная операция запроса данных с веб-сервиса завершается, вызывается метод HandleForecastResponse. Этот метод имеет аргумент asyncResult, свойство которого AsyncState позволяет получить доступ ко второму параметру (forecastState), который был передан при вызове асинхронной операции запроса веб-ресурса.

В методе HandleForecastResponse создаётся новый объект forecastState, в который записывается ссылка на объект, хранящийся в asyncResult, создаётся объект forecastRequest, с использованием соответствующего поля forecastState, после чего запрос завершается вызовом EndGetResponce для forecastRequest, при этом ответ сервера записывается в поле AsyncResponse объекта forecastState. Фактически, на данном этапе работа с сетевыми функциями завершается. Всё, что осталось для получения данных, с которыми можно работать дальше – это прочесть в поток streamResult данные из AsyncResponse. Служба, на основе которой построено приложение, возвращает данные в формате XML. Далее выполняется разбор этих данных.

Общая схема работы с HttpWebRequest выглядит следующим образом:

  1. Формирование запроса
  2. Создание объекта HttpWebRequest, при необходимости – настройка параметров.
  3. Создание метода, который будет вызван при завершении асинхронной операции, при этом в данном методе завершается запрос, выполняется получение результатов запроса, пригодных для последующего разбора.
  4. Выполнение асинхронного обращения к веб-службе.

Выводы

HttpWebRequest и WebClient – это мощные средства, которые позволяют организовать работу с различными веб-службами – от сравнительно простых запросов на получение каких-либо данных, до сложных операций, включающих в себя взаимодействие с API веб-сервисов. С WebClient проще работать при выполнении простых операций, HttpWebRequest предусматривает немного более сложную инфраструктуру вспомогательных элементов, но обладает большими возможностями. Помимо рассмотренных в данной лабораторной работе методов асинхронного выполнения задач Visual Studio 2012 поддерживает более удобные средства выполнения асинхронных вызовов, в дальнейшем мы вернемся к этой теме.

Задание

Если приложение, над которым вы работаете, подразумевает работу с каким-либо веб-сервисом, получение данных из Интернета, подумайте над тем, какие из рассмотренных механизмов вы сможете в них использовать. В частности, исходя из круга задач, которые ваше приложение будет решать с использованием интернет-сервисов аргументируйте использование в нём таких средств, как классы HttpWebRequest или WebClient, задача вызова веб-браузера из приложения, элемент управления, который позволяет встраивать веб-браузер в страницу приложения.

Дополнительные материалы

К данной лабораторной работе подготовлено видеоприложение.