NuGet Package of the Week #13 - Portable HttpClient makes portable libraries more useful
When you've got an idea for an app, it's likely that you've got the idea for that app in more than one place. By this I mean, you'll start with a phone app, then make a desktop app, then a web app. Or you'll make a game on one platform and then want it to work anywhere. In fact, with the rise of Xamarin, C# lets you put an app in every AppStore in the world with one language.
You likely already knew that you can target different versions of the .NET framework. You likely also know that there are small .NET Frameworks like Silverlight and the tiny .NET Micro Framework.
You can also target XBox and Windows Phone, OR better yet, target a profile called Portable Libraries that I've briefly mentioned before. Portable Libraries are a great idea that have some issues when you try to really use them. There's actually a great (if a little older) video with the inventors over at Channel 9. Note that Portable Libraries ship with Visual Studio 2012 and are a supported thing.
The idea is that you write a library that contains as much shared functionality as possible and then every application uses your now "portable" library. However, the subset of classes that are available are a subset. That means you can only use things that are available in the intersection of the targets you choose. Check this dialog:
And check out the Supported Features table at this MSDN article on Portable Libraries to find out what you can use where. Here's a graphical table I stole from Daniel.
However, most folks that use Portable Libraries have ended up using them mostly for ViewModels - just simple classes without any real functionality. Almost as if we had a DLL full of structs. There are some great posts on how to make Portable Class Libraries work for you using architectural techniques like indirection and appropriate interfaces.
The number one complaint around code resuse and the number one voted item over at the Visual Studio UserVoice was "Add HttpClient support in Portable Class Libraries (including Windows Phone 8)." Why? Because the GETting of a remote resource via HTTP is such a fundamental thing that it'd be awesome to be able to bake that data access into a portable library and use it everywhere.
Now there is a Portable Http Client and you can get it via NuGet!
Here's an example of what the code looks like for a GET. Note that I'm using async and await also.
public static async Task<HttpResponseMessage> GetTheGoodStuff()
{
var httpClient = new HttpClient();
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, "http://hanselman.com/blog/");
var response = await httpClient.SendAsync(request);
return response;
}
If you were going to make a Twitter client (lame example, but bear with me) you could now put the JSON HTTP data access code in one library and share it across Windows Phone, Windows Store, WinForms, Console, whatever.
I'm hoping that the folks at MS and the folks at Mono will continue to work to make Portable Libraries a good option for Mono as well. I've been advocating (and pushing) to make something happen as well, as have the Portable Libraries folks. You'll find lots of working in the space around the web, so fear not, code reuse, either through Portable Libraries or via linked code files at compilation time is deeply possible. The game "Draw A Stickman Epic" achieved 95% code reuse by writing the game in C# with MonoGame!
.NET 4 or Windows Phone 7.5
If you want to use this HttpClient on .NET 4 or Windows Phone 7.5, note you might get a compile error if you use async and await.
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 .NET 4 and WP7.5. Here's a post with more details on how this backport works.
Related Links
- Great webservices example - Earthquake data with Portable Class Libraries (PCLs)
- Need GZip and Deflate for all platforms as well? Check out the HttpClient.Compression library
- Video: .NET 4.5: David Kean and Mircea Trofin - Portable Libraries
- Portable HttpClient for .NET Framework and Windows Phone
- Cross-Platform Development with the .NET Framework
- DrawAStickman on iOS, Windows Store, and Android!
About Scott
Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.
About Newsletter
So we have multiple projects to maintain, but we take a different approach to doing it from what seems to be the common way. As far as I can tell, other places tend to use file linking, so when you add a file in your master project you have to manually add a link to it in all the others.
We don't do that. We take advantage of MSBuild being the underlying language of project files, and structure our project so that shared code is all under one root folder, while any partial classes that may be needed to extend support to a particular environment will be in a different folder tree. When we add a file to the shared folder tree in the master project in the normal way, it's picked up by the other projects because we include those files using wildcards:
There are a couple of minor drawbacks:
<Compile Include="Source\**\*.cs">
<SubType>Code</SubType>
</Compile>
Maybe the Project Linker closes the gap on ease of use when working with linked files. We haven't done a serious evaluation of it.
Why does the Supported Features table show the dynamic keyword as not being supporting in .NET 4.0?
How is the "Add HttpClient support" item "the number one voted item over at the Visual Studio UserVoice"? It has 1887 votes; I posted a suggestion which got 3317 votes. Last time I checked, 3317 is higher than 1887.
Also, "MonoGame" is fantastic. :)
Assume for a second we'd give you support for #if -- would this change the picture?
@Richard: Regarding dynamic -- good question, I'll double check.
You're correct, your item was definitely was more popular. But at some point the item was declined which removes it from the list. When we released HttpClient, it was the highest voted ACTIVE user voice item. Sorry about that.
To be honest some of it is just that our portable projects pre-date the Portable Class Libraries and serious exploration of PCL as an alternative hasn't been a high enough priority. However, something I'd anticipate immediate difficulty with is that we're targetting Mono and iOS (MonoTouch, we haven't moved to Xamarin yet) as well as targets that you do support directly.
We try to avoid #if whenever possible, but I've just checked our main portable library and there are four usages, three of which are to do with portability, so I expect #if could be helpful.
i opened new project ASP.NET MVC 4 on two VS2012 and press CTRL+F5 for take preview.
i create different user & password in each WebApp preview.
i login to first webApp, then to second webApp.
i see first webApp logout automatically!!!
i see all session is together.
Is problem in Web Matrix?!
WebMatrix.WebData.WebSecurity
Pretty keen to see more of these awesome projects coming out from Microsoft focusing on cross platform development.
Have you seen this? I'm trying to use a CookieContainer in my HttpClient and I'm getting the following error:
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 Assemblies\Microsoft\Framework\.NETPortable\v4.5\Profile\Profile49\System.Net.Primitives.dll]' to 'System.Net.CookieContainer'
according to this Link "http://connect.microsoft.com/VisualStudio/feedback/details/781331/vs-2012-update-2-ctp-4-doesnt-work-with-portable-httpclient" this seems to be a bug in the updated 2 of VS2012 and can be solved by using the repair button in the Installer.
Had the same problem and got it solved by reparing the update.
As I understand it, Xbox 360 is essentially compact framework and it is supported. Compact framework may be old, but it is still in wide use. The company I work for still uses it for some handheld scanner devices which means that the poor souls who work on that project are stuck in Visual Studio 2008 with old-fashioned C# syntax while the rest of us are in VS 2012 with lovely C# 5.
Comments are closed.
Ouch! I certainly wouldn't call ViewModels classes without any functionality, although I suppose some people might prefer to make their ViewModels very thin and push most code down into the models. But the models can also be portable, so either way you can share most of your code using Portable Class Libraries!
In any case, I agree that HttpClient does make it much easier to put more code in PCLs. Previously, if you wanted to put your code in a Portable Class Library, you'd have to use HttpWebRequest, which isn't as nice of an API and doesn't support async code quite as well. Or you could have written platform-specific code for your networking and hooked it up to your PCL via the abstraction pattern, but since HttpClient wasn't available on Windows Phone, .NET 4, or Silverlight, you would probably have had to implement it using HttpWebRequest in any case.
Anyway, thanks for the post. :-)