От переводчика:
Этот пост включает перевод не только оригинальной записи из блога команды разработчиков BCL, но также и страницы со списком известных проблем текущей бета-версии для полноты картины. Ссылки на источники можно найти в конце поста.
Сегодня (18 февраля 2013 г. — прим. переводчика) мы анонсируем бета-версию переносимой версии HttpClient, современного API для работы с сетью. Библиотека HttpClient является набором API для .NET, предоставляющих гибкий и расширяемый способ доступа к возможностям HTTP.
Этот выпуск добавляет поддержку HttpClient для следующих платформ:
- .NET Framework 4.0
- Windows Phone 7.5 и выше
- Переносимые библиотеки классов
Что делает HttpClient?
HttpClient входит в состав .NET Framework 4.5 и приложений Windows Store и даёт разработчикам возможность очень легко подключаться к интернет-сервисам, включая REST-сервисы. По сути, методы HttpClient являются обёртками для методов, используемых HTTP-протоколом, таких как GET/PUT/POST/DELETE.
Чтобы получить какой-то контент с веб-сервера, например, www.contoso.com, мы можем написать такие простые строки кода:
HttpClient httpClient = new HttpClient();
string responseBodyAsText = await httpClient.GetStringAsync(“www.contoso.com”);
… и получить ответ от веб-сервиса. Понятно, что это самый простой пример, и библиотека HttpClient обладает гораздо большим количеством возможностей и функций.
Зачем нужен переносимый HttpClient?
До выпуска этого пакета, класс HttpClient не был доступен на всех платформах. Это усложняло задачу разработчикам, пытавшимся переносить код между платформами Microsoft. Например, разработчик, который хотел писать и для Windows Phone, и для Windows Store, должен был описывать логику работы с сетью при помощи классов HttpWebRequest и HttpWebResponse, поскольку они были доступны в переносимых библиотеках. Однако HttpClient является гораздо более простым программным интерфейсом, и к тому же он ближе к семантике HTTP, из-за чего более интуитивен. Вдобавок HttpClient предоставляет новые асинхронные методы, основанные на Task'ах, что позволяет намного легче создавать отзывчивый и производительный UI на всех платформах.
Чтобы закрыть этот пробел, мы создали переносимую библиотеку классов для HttpClient, которая позволит разработчикам использовать HttpClient на Windows Phone 7.5 и выше, в приложениях Windows Store, а также в .NET Framework 4.0 и выше. В дополнение, это также даст возможность разработчикам других переносимых библиотек, создаваемых для всех или некоторых поддерживаемых платформ, использовать HttpClient для работы с сетью.
Что мне потребуется?
Для того, чтобы воспользоваться этим выпуском HttpClient, вам потребуются следующие две вещи:
- Visual Studio 2010 (для .NET 4.0 и Windows Phone 7.1) или Visual Studio 2012 (необходима для .NET 4.5, Windows Store и Windows Phone 8).
- Менеджер пакетов NuGet версии 2.1 или выше.
Чтобы использовать пакет HttpClient, щёлкните правой кнопкой мыши на решении, выберите пункт «Управление пакетами Nuget» (Manage Nuget Packages), выполните поиск по идентификатору «Microsoft.Net.Http» и убедитесь, что выбран вариант «Включать предварительные версии» (Include Prerelease).
Примите лицензионное соглашение, и NuGet установит нужные пакеты в папку.
Написание кроссплатформенного приложения
Полная документация для HttpClient, поставляемого вместе с .NET Framework 4.5, доступна здесь. Этот пакет включает поддержку документированных функций и предоставляет несколько новых методов, пока не включённых в указанную документацию. Эти новые API используются для определения поддерживаемых текущей платформой возможностей работы с сетью, поскольку они доступны не на всех платформах. Новыми API являются:
public static bool SupportsPreAuthenticate(this HttpClientHandler handler);
public static bool SupportsProtocolVersion(this HttpClientHandler handler);
public static bool SupportsTransferEncodingChunked(this HttpClientHandler handler);
Чтобы написать переносимый код, который будет работать на всех поддерживаемых платформах, код, который раньше выглядел так:
HttpMessageHandler handler = new HttpClientHandler();
httpClient = new HttpClient(handler);
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, resourceAddress);
request.Content = streamContent;
request.Headers.TransferEncodingChunked = true;
HttpResponseMessage response = await httpClient.SendAsync(request);
должен будет обрести следующий вид:
HttpMessageHandler handler = new HttpClientHandler();
httpClient = new HttpClient(handler);
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, resourceAddress);
request.Content = streamContent;
if (handler.SupportsTransferEncodingChunked())
{
request.Headers.TransferEncodingChunked = true;
}
HttpResponseMessage response = await httpClient.SendAsync(request);
Использование HttpClient в .NET Framework 4.0 или Windows Phone 7.5
Если вы пишете кроссплатформенное приложение для .NET 4.0 или Windows Phone и напишете код, приведённый выше, вы получите ошибку компиляции: “Cannot await System.Threading.Task”.
Это происходит потому, что .NET 4.0 и Windows Phone 7.5 не поддерживают ключевые слова async/await. Чтобы это исправить, добавьте ссылку на NuGet-пакет Microsoft.Bcl.Async, который добавляет поддержку Async и Await для более ранних платформ. Узнать больше об этом пакете Вы можете здесь.
Это было одно из самых популярных предложений на UserVoice, поэтому спасибо за то, что уделили этому время. Пожалуйста, обратите внимание на то, что этот пакет помечен как предрелизный, так что можно ожидать в нём некоторых «шероховатостей». Мы опубликовали список известных проблем (дальше по тексту — прим. переводчика). И как обычно, нам бы хотелось узнать, с какими проблемами вы столкнулись при использовании этого пакета.
Известные проблемы
Проблема 1
Симптом
При установке HttpClient в проект, содержащий app.config или web.config с назначениями привязок, config-файл может быть неправильно изменён. Например:
<dependentAssembly bcl:name="System.Net.Http">
<assemblyIdentity name="ExistingAssembly" publicKeyToken="abcdef012345678" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
<assemblyIdentity name="System.Net.Http" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.0.43.0" newVersion="2.0.43.0" />
</dependentAssembly>
Решение
Чтобы исправить это, вы может обновить config-файл следующим образом:
<dependentAssembly>
<assemblyIdentity name="ExistingAssembly" publicKeyToken="abcdef012345678" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
</dependentAssembly>
<dependentAssembly bcl:name="System.Net.Http">
<assemblyIdentity name="System.Net.Http" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.0.43.0" newVersion="2.0.43.0" />
</dependentAssembly>
Проблема 2
Симптом
При использовании HttpClient в Silverlight-приложении классы FormUrlEncodedContent и MultipartContent неправильно кодируют контент, используя UTF8 вместо ISO-8859-1.
Решение
На данный момент мы рекомендуем воздержаться от использования этих классов в Silverlight-приложениях, пока эта ошибка не будет исправлена.
Проблема 3
Симптом
При использовании HttpClient в Silverlight-приложении многие HTTP-заголовки не поддерживаются, и если их указать и вызвать метод HttpClient, посылающий запрос, возникнут исключения ArgumentException или NotImplementedException.
Решение
См. список поддерживаемых в Silverlight заголовков:
http://msdn.microsoft.com/en-us/library/system.net.webheadercollection(v=vs.95).aspx
http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.headers(v=vs.95).aspx
Проблема 4
Симптом
Когда HttpClientHandler.SupportsProtocolVersion() равно false, свойство Version возвращаемого после запроса HttpResponseMessage будет иметь значение null.
Решение
Убедитесь, что каждый раз при использовании свойства Version из HttpResponseMessage вы делаете его проверку на null, если SupportsProtocolVersion() равно false.
Проблема 5
Симптом
При использовании данного HttpClient в приложениях .NET 4.0, 4.5 или Windows Store путём добавления ссылки на проект переносимой библиотеки, выбирается неправильная версия HttpClient для платформы.
Решение
Чтобы избежать этого, всегда устанавливайте NuGet-пакет HttpClient в каждый проект, использующий библиотеку (даже косвенно).
Проблема 6
Симптом
При использовании HttpClient в Silverlight или на телефоне принимайте во внимание, что сетевой стек может кэшировать ответы на запросы.
Решение
Чтобы избежать несоответствий при создании переносимой библиотеки классов, работающей на обеих платформах, убедитесь, что ваш сервер задаёт заголовок Cache-Control в ответе, соответствующий ожидаемому поведению кэширования на телефоне. Если вы не контролируете сервер, рассмотрите возможность добавления уникальной части запроса, если не хотите получить кэшированный результат.
Проблема 7
Симптом
При использовании переносимой библиотеки классов, в свою очередь использующей HttpClient, в приложении .NET 4.5, Windows Store или Windows Phone 8, приложение аварийно завершает работу с исключением, похожим на следующее:
Метод не найден: 'Void System.Net.Http.HttpClientHandler.set_AutomaticDecompression(System.Net.DecompressionMethods)'.
Решение
В проект приложения требуется также добавить ссылку на Nuget-пакет HttpClient.
Источники
- Portable HttpClient for .NET Framework and Windows Phone
- Известные проблемы — http://blogs.msdn.com/b/bclteam/p/httpclient.aspx
Автор: SgtRiggs91