Цель работы: освоить технологию работы с классами webClient и HttpWebRequest
Для работы с веб-сервисами из приложений для Windows Phone обычно используют классы System.Net.WebClient (http://msdn.microsoft.com/en-us/library/windowsphone/develop/system.net.webclient%28v=vs.105%29.aspx) и System.Net.HttpWebRequest (http://msdn.microsoft.com/en-us/library/windowsphone/develop/system.net.httpwebrequest%28v=vs.105%29.aspx). И тот и другой класс позволяют достигать схожих целей, однако, между ними есть некоторые отличия, которые и определяют выбор того или иного класса для использования в конкретном приложении.
Так, обычно WebClient применяют тогда, когда нужно получить какие-либо данные из Интернета, он обеспечивает простую и удобную работу с GET/POST запросами. То есть, если наша задача – это получение, например, RSS-ленты с сервиса, или отправка файла с использованием POST-запроса, возможностей WebClient для этого вполне хватит. Кроме того, его использование позволит упростить код. Его возможностей хватит и для выполнения многих других действий, но более сложные сценарии взаимодействия с веб-службами обычно реализуют с использованием HttpWebRequest. Этот класс, в частности, нужен там, где предполагается использование PUT/DELETE запросов, он предоставляет больший уровень контроля над параметрами запроса. Например, если речь идёт об отправке файла на веб-сервер, то обычно для этого нам понадобится HttpWebRequest. При работе над конкретным проектом стоит ознакомиться с наборами инструментов, доступных в пространстве имен System.Net (http://msdn.microsoft.com/en-us/library/windowsphone/develop/btdf6a7e%28v=vs.105%29.aspx).
Можно сказать, в итоге, что для выполнения простых задач использование WebClient позволяет упростить их решение, при прочих равных условиях HttpWebRequest потребует более сложных программных конструкций, больше настроек. А при выполнении задач более сложных, требующих более полного контроля над процессом взаимодействия с веб-службой, некоторая усложнённость использования HttpWebRequest вполне оправдана.
Рассмотрим работу с WebClient на примере приложения, размещенного в библиотеке кода MSDN "RSS-ридер в Windows Phone 8" ("RSS Reader in Windows Phone 8"). Загрузить пример можно по этой ссылке: http://code.msdn.microsoft.com/RSS-Reader-in-Windows-afa86457.
В структуре проекта (рис. 29.1.), присутствует файл RSSItem.css (Листинг 29.1), в котором определена структура для хранения данных о записи RSS-канала. Основная функциональность приложения реализована в файле кода к странице MainPage.xaml.
(рис 29.1) Приложение, демонстрирующее работу в WebClient
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace RSSReaderWindowsPhone
{
public class RSSItem
{
private string Description;
public string Description1
{
get { return Description; }
set { Description = value; }
}
private string Link;
public string Link1
{
get { return Link; }
set { Link = value; }
}
private string Title;
public string Title1
{
get { return Title; }
set { Title = value; }
}
}
}
Сама эта страница (Листинг 29.2) содержит элемент управления ListBox. Он, при работе приложения, представляет собой список полученных записей, который можно прокручивать. Заполнение элемента управления записями производится программным способом, при обработке данных, полученных с веб-службы, предоставляющей RSS-ленту. Приложение работает с RSS-летной в формате XML, ссылка на такую ленту присутствует в исходном варианте приложения.
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,131,12,0">
<ListBox Name="ListBoxRss" Margin="10,-157,10,10">
</ListBox>
</Grid>
В Листинге 29.3 приведен код файла MainPage.xaml, здесь опущены некоторые комментарии, некоторые комментарии переведены для лучшего понимания структуры проекта.
using Microsoft.Phone.Controls;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Xml.Linq;
namespace RSSReaderWindowsPhone
{
public partial class MainPage : PhoneApplicationPage
{
// Constructor
public MainPage()
{
InitializeComponent();
this.Loaded += new RoutedEventHandler(MainPage_Loaded);
}
private void MainPage_Loaded(object sender, RoutedEventArgs e)
{
// В этом обработчике события нам нужно создать webClient, который загрузит данные по заданной ссылке
WebClient wc = new WebClient();
wc.DownloadStringCompleted += new DownloadStringCompletedEventHandler(wc_DownloadStringCompleted);
// Ссылка на ленту
wc.DownloadStringAsync(new Uri("http://www.mosaiquefm.net/Syndicate/MosaNews.xml"));
}
private void wc_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
//В ходе этой простой проверки будет осуществлен возврат из обработчика если устройство не подключено к сети
if (e.Error != null)
return;
XElement xmlitems = XElement.Parse(e.Result);
// Создаем список элементов
List<XElement> elements = xmlitems.Descendants("item").ToList();
//Разместим полученную информацию в XAML-элементе управления ListBox
List<RSSItem> aux = new List<RSSItem>();
foreach (XElement rssItem in elements)
{
RSSItem rss = new RSSItem();
rss.Description1 = rssItem.Element("description").Value;
rss.Link1 = rssItem.Element("link").Value;
rss.Title1 = rssItem.Element("title").Value;
aux.Add(rss);
TextBlock tbTitle = new TextBlock();
tbTitle.Text = rss.Title1 + "\n";
ListBoxRss.Items.Add(tbTitle);
TextBlock tbDescription = new TextBlock();
tbDescription.Text = rss.Description1 + "\n";
ListBoxRss.Items.Add(tbDescription);
}
}
}
}
В конструкторе MainPage мы подписываемся на событие страницы Loaded, которое вызывается при добавлении её объекта в дерево объектов. В обработчике события MainPage_Loaded создаётся новый экземпляр объекта типа WebClient. После того, как этот объект создан, мы должны выполнить некоторые его настройки. В частности, задать обработчик события DownloadStringCompleted. Этот обработчик вызывается после завершения загрузки данных из Интернета. Подобные операции способны занимать достаточно много времени, что зависит от скорости сетевого соединения и объема данных, поэтому они выполняются асинхронно, когда они завершаются, вызывается соответствующий обработчик.
Операцию загрузки инициируем вызовом метода DownloadStringAsync с указанием URI ресурса, в данном случае это – адрес RSS-канала.
Загрузка занимает некоторое время, в это время в интерфейсе приложения ничего не выводится, когда же происходит вызов обработчика события завершения загрузки, wc_DownloadStringComplete, в этот обработчик передаётся аргумент e типа DownloadStringCompletedEventArgs, свойство которого Result, при удачном завершении операции, содержит данные, загруженные по заданному URI.
Данные приходят с веб-сервиса в виде текста в формате XML. Для того чтобы работать с подобными данными, нужно произвести их предварительную подготовку. Такая подготовка выполняется в два этапа. Сначала создаётся объект xmlitems типа XElement (System.Xml.Linq.XElement), в него, с помощью статического метода Parse класса XElement, загружаются XML-данные из строки, которая имеется в свойстве e.Result.
После этого осуществляется построение списка типа XElement на основе элемента xmlitems. Из XML-кода, содержащегося в элементе, выбираются элементы, имя которых соответствуют заданному. В данном случае это – item. Элементы попадают в список.
На следующем шаге создаётся список типа RSSItem – этот тип определен в рассматриваемом приложении, осуществляется заполнение списка, ListBoxRSS, который расположен на MainPage.xaml и применяется для вывода списка сообщений.
Подобная схема работы характерна для WebClient. Её основные составные части выглядят следующим образом:
Рассмотрим работу с HttpWebRequest на примере приложения, размещенного в библиотеке кода MSDN "Работа с сервисом прогнозирования погоды" ("Weathen Forecast Sample"). Загрузить пример можно здесь: http://code.msdn.microsoft.com/Weather-Forecast-Sample-586ef733.
В приложении (Рис. 29.2) используются две страницы, одна из них, MainPage.xaml, выводит список городов, при касании строки, соответствующей городу, осуществляется переход на страницу ForecastPage.xaml, на которой отображается подробный прогноз погоды для выбранного города. В приложении используется несколько вспомогательных классов.
(рис 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; }
}
Здесь сначала формируется строка запроса к веб-сервису, которая включает в себя адрес службы и параметры, передаваемые в запросе. Далее создаётся новый 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 выглядит следующим образом:
HttpWebRequest и WebClient – это мощные средства, которые позволяют организовать работу с различными веб-службами – от сравнительно простых запросов на получение каких-либо данных, до сложных операций, включающих в себя взаимодействие с API веб-сервисов. С WebClient проще работать при выполнении простых операций, HttpWebRequest предусматривает немного более сложную инфраструктуру вспомогательных элементов, но обладает большими возможностями. Помимо рассмотренных в данной лабораторной работе методов асинхронного выполнения задач Visual Studio 2012 поддерживает более удобные средства выполнения асинхронных вызовов, в дальнейшем мы вернемся к этой теме.
Если приложение, над которым вы работаете, подразумевает работу с каким-либо веб-сервисом, получение данных из Интернета, подумайте над тем, какие из рассмотренных механизмов вы сможете в них использовать. В частности, исходя из круга задач, которые ваше приложение будет решать с использованием интернет-сервисов аргументируйте использование в нём таких средств, как классы HttpWebRequest или WebClient, задача вызова веб-браузера из приложения, элемент управления, который позволяет встраивать веб-браузер в страницу приложения.
К данной лабораторной работе подготовлено видеоприложение.
Цель работы: освоить технологию работы с классами webClient и HttpWebRequest
Для работы с веб-сервисами из приложений для Windows Phone обычно используют классы System.Net.WebClient (http://msdn.microsoft.com/en-us/library/windowsphone/develop/system.net.webclient%28v=vs.105%29.aspx) и System.Net.HttpWebRequest (http://msdn.microsoft.com/en-us/library/windowsphone/develop/system.net.httpwebrequest%28v=vs.105%29.aspx). И тот и другой класс позволяют достигать схожих целей, однако, между ними есть некоторые отличия, которые и определяют выбор того или иного класса для использования в конкретном приложении.
Так, обычно WebClient применяют тогда, когда нужно получить какие-либо данные из Интернета, он обеспечивает простую и удобную работу с GET/POST запросами. То есть, если наша задача – это получение, например, RSS-ленты с сервиса, или отправка файла с использованием POST-запроса, возможностей WebClient для этого вполне хватит. Кроме того, его использование позволит упростить код. Его возможностей хватит и для выполнения многих других действий, но более сложные сценарии взаимодействия с веб-службами обычно реализуют с использованием HttpWebRequest. Этот класс, в частности, нужен там, где предполагается использование PUT/DELETE запросов, он предоставляет больший уровень контроля над параметрами запроса. Например, если речь идёт об отправке файла на веб-сервер, то обычно для этого нам понадобится HttpWebRequest. При работе над конкретным проектом стоит ознакомиться с наборами инструментов, доступных в пространстве имен System.Net (http://msdn.microsoft.com/en-us/library/windowsphone/develop/btdf6a7e%28v=vs.105%29.aspx).
Можно сказать, в итоге, что для выполнения простых задач использование WebClient позволяет упростить их решение, при прочих равных условиях HttpWebRequest потребует более сложных программных конструкций, больше настроек. А при выполнении задач более сложных, требующих более полного контроля над процессом взаимодействия с веб-службой, некоторая усложнённость использования HttpWebRequest вполне оправдана.
Рассмотрим работу с WebClient на примере приложения, размещенного в библиотеке кода MSDN "RSS-ридер в Windows Phone 8" ("RSS Reader in Windows Phone 8"). Загрузить пример можно по этой ссылке: http://code.msdn.microsoft.com/RSS-Reader-in-Windows-afa86457.
В структуре проекта (рис. 29.1.), присутствует файл RSSItem.css (Листинг 29.1), в котором определена структура для хранения данных о записи RSS-канала. Основная функциональность приложения реализована в файле кода к странице MainPage.xaml.
(рис 29.1) Приложение, демонстрирующее работу в WebClient
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace RSSReaderWindowsPhone
{
public class RSSItem
{
private string Description;
public string Description1
{
get { return Description; }
set { Description = value; }
}
private string Link;
public string Link1
{
get { return Link; }
set { Link = value; }
}
private string Title;
public string Title1
{
get { return Title; }
set { Title = value; }
}
}
}
Сама эта страница (Листинг 29.2) содержит элемент управления ListBox. Он, при работе приложения, представляет собой список полученных записей, который можно прокручивать. Заполнение элемента управления записями производится программным способом, при обработке данных, полученных с веб-службы, предоставляющей RSS-ленту. Приложение работает с RSS-летной в формате XML, ссылка на такую ленту присутствует в исходном варианте приложения.
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,131,12,0">
<ListBox Name="ListBoxRss" Margin="10,-157,10,10">
</ListBox>
</Grid>
В Листинге 29.3 приведен код файла MainPage.xaml, здесь опущены некоторые комментарии, некоторые комментарии переведены для лучшего понимания структуры проекта.
using Microsoft.Phone.Controls;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Xml.Linq;
namespace RSSReaderWindowsPhone
{
public partial class MainPage : PhoneApplicationPage
{
// Constructor
public MainPage()
{
InitializeComponent();
this.Loaded += new RoutedEventHandler(MainPage_Loaded);
}
private void MainPage_Loaded(object sender, RoutedEventArgs e)
{
// В этом обработчике события нам нужно создать webClient, который загрузит данные по заданной ссылке
WebClient wc = new WebClient();
wc.DownloadStringCompleted += new DownloadStringCompletedEventHandler(wc_DownloadStringCompleted);
// Ссылка на ленту
wc.DownloadStringAsync(new Uri("http://www.mosaiquefm.net/Syndicate/MosaNews.xml"));
}
private void wc_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
//В ходе этой простой проверки будет осуществлен возврат из обработчика если устройство не подключено к сети
if (e.Error != null)
return;
XElement xmlitems = XElement.Parse(e.Result);
// Создаем список элементов
List<XElement> elements = xmlitems.Descendants("item").ToList();
//Разместим полученную информацию в XAML-элементе управления ListBox
List<RSSItem> aux = new List<RSSItem>();
foreach (XElement rssItem in elements)
{
RSSItem rss = new RSSItem();
rss.Description1 = rssItem.Element("description").Value;
rss.Link1 = rssItem.Element("link").Value;
rss.Title1 = rssItem.Element("title").Value;
aux.Add(rss);
TextBlock tbTitle = new TextBlock();
tbTitle.Text = rss.Title1 + "\n";
ListBoxRss.Items.Add(tbTitle);
TextBlock tbDescription = new TextBlock();
tbDescription.Text = rss.Description1 + "\n";
ListBoxRss.Items.Add(tbDescription);
}
}
}
}
В конструкторе MainPage мы подписываемся на событие страницы Loaded, которое вызывается при добавлении её объекта в дерево объектов. В обработчике события MainPage_Loaded создаётся новый экземпляр объекта типа WebClient. После того, как этот объект создан, мы должны выполнить некоторые его настройки. В частности, задать обработчик события DownloadStringCompleted. Этот обработчик вызывается после завершения загрузки данных из Интернета. Подобные операции способны занимать достаточно много времени, что зависит от скорости сетевого соединения и объема данных, поэтому они выполняются асинхронно, когда они завершаются, вызывается соответствующий обработчик.
Операцию загрузки инициируем вызовом метода DownloadStringAsync с указанием URI ресурса, в данном случае это – адрес RSS-канала.
Загрузка занимает некоторое время, в это время в интерфейсе приложения ничего не выводится, когда же происходит вызов обработчика события завершения загрузки, wc_DownloadStringComplete, в этот обработчик передаётся аргумент e типа DownloadStringCompletedEventArgs, свойство которого Result, при удачном завершении операции, содержит данные, загруженные по заданному URI.
Данные приходят с веб-сервиса в виде текста в формате XML. Для того чтобы работать с подобными данными, нужно произвести их предварительную подготовку. Такая подготовка выполняется в два этапа. Сначала создаётся объект xmlitems типа XElement (System.Xml.Linq.XElement), в него, с помощью статического метода Parse класса XElement, загружаются XML-данные из строки, которая имеется в свойстве e.Result.
После этого осуществляется построение списка типа XElement на основе элемента xmlitems. Из XML-кода, содержащегося в элементе, выбираются элементы, имя которых соответствуют заданному. В данном случае это – item. Элементы попадают в список.
На следующем шаге создаётся список типа RSSItem – этот тип определен в рассматриваемом приложении, осуществляется заполнение списка, ListBoxRSS, который расположен на MainPage.xaml и применяется для вывода списка сообщений.
Подобная схема работы характерна для WebClient. Её основные составные части выглядят следующим образом:
Рассмотрим работу с HttpWebRequest на примере приложения, размещенного в библиотеке кода MSDN "Работа с сервисом прогнозирования погоды" ("Weathen Forecast Sample"). Загрузить пример можно здесь: http://code.msdn.microsoft.com/Weather-Forecast-Sample-586ef733.
В приложении (Рис. 29.2) используются две страницы, одна из них, MainPage.xaml, выводит список городов, при касании строки, соответствующей городу, осуществляется переход на страницу ForecastPage.xaml, на которой отображается подробный прогноз погоды для выбранного города. В приложении используется несколько вспомогательных классов.
(рис 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; }
}
Здесь сначала формируется строка запроса к веб-сервису, которая включает в себя адрес службы и параметры, передаваемые в запросе. Далее создаётся новый 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 выглядит следующим образом:
HttpWebRequest и WebClient – это мощные средства, которые позволяют организовать работу с различными веб-службами – от сравнительно простых запросов на получение каких-либо данных, до сложных операций, включающих в себя взаимодействие с API веб-сервисов. С WebClient проще работать при выполнении простых операций, HttpWebRequest предусматривает немного более сложную инфраструктуру вспомогательных элементов, но обладает большими возможностями. Помимо рассмотренных в данной лабораторной работе методов асинхронного выполнения задач Visual Studio 2012 поддерживает более удобные средства выполнения асинхронных вызовов, в дальнейшем мы вернемся к этой теме.
Если приложение, над которым вы работаете, подразумевает работу с каким-либо веб-сервисом, получение данных из Интернета, подумайте над тем, какие из рассмотренных механизмов вы сможете в них использовать. В частности, исходя из круга задач, которые ваше приложение будет решать с использованием интернет-сервисов аргументируйте использование в нём таких средств, как классы HttpWebRequest или WebClient, задача вызова веб-браузера из приложения, элемент управления, который позволяет встраивать веб-браузер в страницу приложения.
К данной лабораторной работе подготовлено видеоприложение.
Для получения официальных документов о завершении программы дополнительного профессионального образования (удостоверения о повышении квалификации, дипломов о профессиональной переподготовке и MBA) необходимо предоставить:
Внимание! Вы можете не заказывать доставку бумажной версии официального документы, а скачать его в электронном виде и распечатать самостоятельно. Информация о выданном документе в течение 1 месяца загружается в Федеральную информационную систему «Федеральный реестр сведений о документах об образовании и (или) о квалификации, документах об обучении» - ФИС ФРДО.
Доступ на новый сайт осуществляется с использованием адреса электронной почты, который был указан вами при регистрации на "старом". Мы постарались перенести все ваши данные с прежнего ресурса, однако не исключена вероятность потери части информации.
При возникновении проблемы со входом, воспользуйтесь функцией сброса пароля
Если вы обнаружите несоответствия, пожалуйста, сообщите нам.