Portable HttpClient for .NET Framework and Windows Phone


Many of you told us you want HttpClient for Windows Phone. In this post, Alok Shriram, a Program Manager on the .NET Framework team, will talk about an important announcement of ours. –Immo

Today we are announcing our Beta release of the portable version of HttpClient, the modern networking API. The HttpClient library is a set of APIs for .NET which provide a flexible and extensible way to access all things exposed through HTTP.

This release of HttpClient adds support for the following platforms:

  • .NET framework 4.0
  • Windows Phone 7.5 and higher
  • Portable class libraries

What does HttpClient do?

HttpClient is a part of .NET Framework 4.5 and Windows Store apps that provides developers an extremely easy way to connect with services across the internet including REST-based services. In fact, the methods exposed by HttpClient are the same verbs the HTTP protocol uses to communicate like GET/PUT/POST/DELETE.

In order to get some content from a web server say www.contoso.com we can write the following simple lines of code

HttpClient httpClient = new HttpClient();
string responseBodyAsText = await httpClient.GetStringAsync(“www.contoso.com”);

…and get a response back from a web service. Obviously this is the simplest example, and the HttpClient library has many more feature and functions.

Why a portable HttpClient?

Before releasing this package, the HttpClient class was not available on all platforms. This complicated the experience for developers trying to share code across Microsoft platforms. For instance, a developer who wanted to target both the Windows Phone and Windows Store app platforms would need to write networking logic using the HttpWebRequest and HttpWebResponse classes for networking, since it was the networking abstraction available in portable. However HttpClient is a much simpler programming interface to code against, in addition to being very close to HTTP semantics, which makes it more intuitive. In addition HttpClient exposes the new Task based asynchronous methods, which makes writing responsive and performant UI applications across all platforms a lot simpler.

In order to bridge this gap we have created a portable class library for HttpClient that will allow developers to consume HttpClient on Windows Phone 7.5 and higher, Windows Store apps, and .NET Framework 4.0 and higher. In addition it also enables other portable library developers who require networking support to use HttpClient while targeting all or a subset of the supported platforms.

What do I need?

In order to use this release of HttpClient you need to ensure that you have two things.

  • Visual Studio 2010 (for .NET 4.0 Windows Phone 7.1) or Visual Studio 2012 (required for .NET 4.5, Windows Store and Windows Phone 8).
  • The NuGet package manager version 2.1 or higher.

To use the HttpClient package, right click on your solution, go to the Manage Nuget Packages dialog, search for Id Microsoft.Net.Http, and make sure “Include Prerelease” is turned on.

 

Accept the license terms and agreements and NuGet will install the right packages to your folder.

Writing a Cross platform App

The full surface area for HttpClient as shipped in .NET Framework 4.5 is documented here. This package includes support for that surface area, and introduces a few new methods that are not currently in the documentation above.These new APIs are used to help determine which networking capabilities are supported on the platform on which you’re running, since not all platforms support all capabilities. The new APIs added are:

public static bool SupportsPreAuthenticate(this HttpClientHandler handler);
public static bool SupportsProtocolVersion(this HttpClientHandler handler);
public static bool SupportsTransferEncodingChunked(this HttpClientHandler handler);

In order to write a portable piece of code which would work across all the supported platforms, code that would have previously been

HttpClientHandler 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);

Will now change to

HttpClientHandler 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);

Using HttpClient on .NET Framework 4.0 or Windows Phone 7.5

If you are writing a cross platform app targeting .Net 4.0 or the windows phone and write the code that you had written above you will get a compile error.

“Cannot await System.Threading.Task<HttpRequestMessage>”

This is because .Net 4.0 and Windows Phone 7.5 did not support the async/await keywords.In order to fix this add a reference to the Microsoft.Bcl.Async nuget package, which adds the support for Async and Await in down level platforms.To read more about this release go here.

 

This was one of the higher rated user voice requests, so thanks for taking the time to engage with us. Please note this package is marked as prerelease software – that is, there are some rough edges to be expected. We’ve published the known issues here. As usual, we’d like to know if you run into any issues when using it. Simply use the comment section under this blog post.

Happy “Get”ting!

Comments (40)

  1. Great news, thank you guys!

    Now the only missing features for me is support for PCLibs in Visual Studio Express editions – it really should be possible to develop PCL targeting Windows Phone + something in VS Express for WP.

    And Azure Mobiles Service SDK for Windows Phone 7.1.

    Otherwise good job, especially with Microsoft.Bcl.Async!

  2. Magnus Ohlsson says:

    Thanks, will try it out immediately!

  3. Oran says:

    Will this work on MonoTouch and Mono for Android?

  4. John O'Halloran says:

    What about Silverlight?

  5. James says:

    This is suppose to work for XNA games targeting WP7 mango (read: wp 7.1) right?

    Warning 11 The primary reference "System.Net.Http" could not be resolved because it has an indirect dependency on the framework assembly "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" which could not be resolved in the currently targeted framework. ".NETFramework,Version=v4.0,Profile=Client". To resolve this problem, either remove the reference "System.Net.Http" or retarget your application to a framework version which contains "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089". BattleCity (Phone Mango)

    As far as I know WP7 xna games must target the 'client' .net profile. So if these assemblies were build against non-client 4.0, they are not going to work… or am I missing something here?

  6. James, this worked for me.  I think you are using the release version of Microsoft.Net.Http (which only supports .Net 4).  Double check that you have selected "include prerelease" and the version you install is 2.1.3-beta.

  7. Viish says:

    It's great to have the same API for both platforms, but this release missed the support for the Http method PROPFIND…

  8. Ker says:

    Same question like Oran:

    Will this work on MonoTouch and Mono for Android?

    That would be great!

  9. Bra says:

    Thank you so much, guys! :)

  10. Found bug! It's not possible to install Microsoft.Net.Http in Visual Studio 2012 Express for Windows Phone into WP8 project, but it works for WP7.1 project!

    I guess this is related to the fact that Portable Class Libraries are not supported in this VS edition and for the WP8 project the PCL library is selected during the installation from NuGet, but for the WP7.1 project specific sl4-windowsphone71 lib is selected.

  11. @Martin Suchan: The express edition issue is a good one. I'll add it to the known issue list.

    @John O'Halloran: We didn't list Silverlight support because there are open issues that prevent it from being fully supported. However, technically there is nothing stopping you from using HttpClient from a Silverlight app. We'd be happy to hear about your experience using it.

  12. James says:

    Yep, not working for me. I manually added references to the dll's from the nuget packet located here:

    "packagesMicrosoft.Net.Http.2.1.3-betalibsl4-windowsphone71"

    Giving the error previously posted.

  13. @Immo Landwerth

    > We didn't list Silverlight support because there are open issues that prevent it from being fully supported.

    Can you elaborate on this, if you don't mind? Is it the current policy to not support Silverlight libraries? Microsoft has promised to support it for 10 years, so it is ironic that even the portable libraries are not supported for Silverlight…

  14. dsplaisted says:

    @Martin Suchan: Do you have NuGet 2.1 or higher installed?  Windows Phone 8 and Portable Class Library support were added to NuGet in that version.  You can't create Portable Class Libraries with VS Express, but you should be able to reference them (either directly or via NuGet).

    @James: Windows Phone XNA projects "pretend" to target .NET 4 Client Profile, and NuGet doesn't seem to be compensating for that correctly.  You can probably get it to work by referencing the DLLs manually, referencing Microsoft.Bcl.Build, and adding binding redirects to the project's app.config.

  15. @dsplaisted not sure, what's the NuGet version at the VS Express machine. Anyway I've also tested adding this library to "XNA Windows Phoone Game" project and it worked fine in VS 2012 Ultimate.

  16. Ian Lee says:

    This is a step in the right direction.  Thanks.  Now if you would just add GZip support to WP8 then I'd be able to get rid of most of my #if conditional compile blocks.

  17. Update, after updating the NuGet to latest version the installation of this package works in Visual Studio 2012 Express in WP8 project.

  18. @Ian: Decompression isn't directly supported by the phone networking stack but a couple other Nuget packages out there add support by registering a custom HttpWebRequest implementation with WebRequest.RegisterPrefix.  I had success using these with the portable HttpClient in a phone app.  See SharpGIS.GZipWebClient, Coding4Fun.Toolkit.Net.  Ymmv.

  19. @Andrew Skalkin: Portable Class Libraries (PCL) do support Silverlight as a target (requiring Silverlight 4 or higher) and you can run HttpClient on Silverlight. Please let us know if you run into any issues and we’ll do our best to address them.

  20. App is hanging whenever await or task.result is used with httpClient.GetStringAsync on UI thread for windows phone 8. but the same code works fine on windows 8. i think same httpwebrequest deadlock issue happening here. see http://goo.gl/9Itrx

    Code:

               var hc = new HttpClient();

               var task = hc.GetStringAsync(urlpath);

               var response = task.Result;

  21. tiwahu says:

    Fantastic.  The next version of "Live Music Access" on WP8 will love this!  Really could have used it last week, but may circle back and make the necessary changes.  Thanks!

  22. Any estimation, when the "Go live" license will be available? We're currently testing this library in pretty big WP8 project and it works just fine.

  23. Ricardo says:

    What's about System.Net.Http.Formatting?

  24. @Martin Suchan: We don't have a date yet.

    @Ricardo: We're in contact with the owners of System.Net.Http.Formatting but it's too soon share anything.

  25. htuomola says:

    Hi, I've noticed that the value of WWW-authenticate header is not correctly parsed in our case. We've got a custom authentication solution which includes several, whitespace & comma-separated strings (which is valid based on HTTP spec) and only the first one is populated to AuthenticationHeaderValue.Parameter property. I can provide you with more details if you like, feel free to contact me i.e. on twitter @htuomola.

  26. Hi,

    Thank you for this library.

    I have the same problem that @Anil Tallam have.

    Here is my code :

    HttpClient httpClient = new HttpClient();

    Task<HttpResponseMessage> result = httpClient.GetAsync(_urlAccessFormat + key);

    It works only once. Then, nothing.

    On windows 8, no problem …

    So I tried this one and noticed that the thread never return …

    using (HttpClient httpClient = new HttpClient())

    {

       Task<HttpResponseMessage> result = httpClient.GetAsync(_urlAccessFormat + key);

       result.Wait(); // NEVER RETURN

    }

    Can you please provide us a feedback ?

    Thank you.

  27. OK,

    It was what I was thinking : A caching problem.

    Here is two workarounds. None is nice but it works :

    stackoverflow.com/…/wp7-httpwebrequest-without-caching

    timdams.com/…/creating-a-wp-7-app-caching-urls

  28. Ash says:

    This is pure heaven.. hated the WebClient !

  29. Lori says:

    Hi, I am getting this message when i try to install it to a Portable Class Library.

    Could not install package 'Microsoft.Bcl 1.0.16-rc'. You are trying to install this package into a project that targets '.NETPortable,Version=v4.0,Profile=Profile154', but the package does not contain any assembly references that are compatible with that framework. For more information, contact the package author.

    Please help,

    Thanks.

  30. @Lori:

    That looks like you are using an outdated version of the NuGet client. You can check whether you have the latest version by going to Tools | Extensions and Updates. When the Extensions and Updates dialog opens, select Updates | Visual Studio Gallery and look for an entry titled NuGet Package Manager.

  31. Great thanks for developers, it's fantastic opportunity to develop cross-platform network libraries!

    Do you plan to implement HttpUtility class ?

  32. ils@neue.cc says:

    Current inner WebRequest's AllowReadStreamBuffering and AllowWriteStreamBuffering property are true.

    But it should be set to false?

    For example, Twitter's streaming api needs AllowReadStreamBuffering = false.

    Otherwise program freeze.

    In current HttpClient, cannot connect.

  33. Jernej says:

    It seems like cookies container does not work properly or I don't know how to use it.

    When I receive content, I should receive 3 cookies (1 with domain and 2 without domain) but I get just one. (with domain)

    When I sent a request with HttpClient.PostAsync, there are no clues that any cookies were sent even though HttpClientHandler does contains 1 cookie. Are there any tutorials on these topic or source code for HttpClient so I can check out where might be a problem?

    I'm trying to port a WP7 code from WebClient to Portable Class Library with HttpClient but I can't make this work.

  34. I'm so glad that you guys listened to the voice of the masses and got this done!  Hopefully you can point out what I'm doing wrong here.  I'm trying to use a CookieContainer with an HttpClientHandler in my HttpClient and I'm getting some build errors.  I tried this in a simple PCL targeting only .Net Framework 4.5 and Windows Phone 8.

    Here is the offending code:

    var cookieContainer = new CookieContainer();

    var clientHandler = new HttpClientHandler { CookieContainer = cookieContainer };

    var client = new HttpClient(clientHandler);

    Here are the errors:

    Error 1 The type 'System.Net.CookieContainer' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Net, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e, Retargetable=Yes'

    Error 2 Cannot implicitly convert type 'System.Net.CookieContainer [c:Program Files (x86)Reference AssembliesMicrosoftFramework.NETPortablev4.5ProfileProfile49System.Net.Primitives.dll]' to 'System.Net.CookieContainer'

  35. @Andy, I think you are hitting a bug caused by VS Update 2 when installed on top of the Phone tools.  Can you try running the following command to repair the portable library targetting pack: msiexec.exe /fomus {6A6F1B4D-1BCE-3703-93D8-4494FB7F1280}

  36. @neuecc You are correct.  To be consistent with the inbox version we should be setting this to false.  I'll get this fixed.  Thanks for the report.

  37. Bernhard Koenig says:

    Loving this library … only issues I have with it is missing compression Support and missing Support for PreAuthenticate … both things that I think are very important on mobile phones as they save bandwidth and half of the HTTP calls when using Basic authentication.

  38. I get the error below when trying to add the package via nuget to a PCL project.  Presumably it is the Silverlight support causing the problem.  However, in V2012, you can't remove Silverlight from the PCL targets because it re-adds it automatically saying it is covered by another target.  So it seems ruled out on a technicality I am not trying to use and can't disable.  Am I missing something?

    Attempting to resolve dependency 'Microsoft.Bcl (≥ 1.0.16-rc)'.

    Attempting to resolve dependency 'Microsoft.Bcl.Build (≥ 1.0.4)'.

    Successfully installed 'Microsoft.Bcl.Build 1.0.4'.

    Successfully installed 'Microsoft.Bcl 1.0.19'.

    'Microsoft.Net.Http 2.1.3-beta' already installed.

    Successfully uninstalled 'Microsoft.Bcl.Build 1.0.4'.

    Install failed. Rolling back…

    Could not install package 'Microsoft.Bcl.Build 1.0.4'. You are trying to install this package into a project that targets 'portable-win+net45+sl40+wp', but the package does not contain any assembly references or content files that are compatible with that framework. For more information, contact the package author.

     

    Edit by Immo Landwert [MSFT]: Are you running the latest version of NuGet? You can check whether you have the latest version by going to Tools | Extensions and Updates. When the Extensions and Updates dialog opens, select Updates | Visual Studio Gallery and look for an entry titled NuGet Package Manager.