Windows 8 / Windows Phone Code Sharing: HttpWebRequest GetResponseAsync
I’m working on building helpers for sharing code between Windows 8 (Windows Store) and Windows Phone. Keep an eye on my github for additional updates.
I love the new async-await model in .NET 4.5 (and also in .NET 4.0 if you’re interested). One of the most exciting uses of it (for me) is the ability to do HTTP calls and simply wait for the result. Instead of setting up event handlers and custom events I can write a service that works like
Tweet myTweet = await GetTweet(tweetID);
and just wait for the result to come back. If I’m writing a service call for a Windows Store app and I use HttpWebRequest to make my call, the writing this call is very simple
public async Task<string> GetMyData(string urlToCall) { HttpWebRequest request = (HttpWebRequest)WebRequest.Create(urlToCall); request.Method = HttpMethod.Get; HttpWebResponse response = (HttpWebResponse)await request.GetResponseAsync(); using (var sr = new StreamReader(response.GetResponseStream())) { return sr.ReadToEnd(); } }
and then I can run this as an await-able method.
But if we want to share code between my Windows 8/Windows Store app and my Windows Phone app, the problem comes where this await-able GetResponseAsync method isn’t available in Windows Phone. We’re stuck using the old event based model.
So I threw together these extensions for solving that problem. These are actually two problems here:
- There is no awaitable GetResponseAsync() in Windows Phone’s version of HttpWebRequest
- There is no HttpMethod enum in Windows Phone. We have to use a string instead.
So I wrote the following so we can write the same http service calls one time and share it across our Windows 8 and Windows Phone projects.
First, an extension for Windows Phone HttpWebResponse:
namespace WinPhoneExtensions { public static class HttpExtensions { public static Task<HttpWebResponse> GetResponseAsync(this HttpWebRequest request) { var taskComplete = new TaskCompletionSource<HttpWebResponse>(); request.BeginGetResponse(asyncResponse => { try { HttpWebRequest responseRequest = (HttpWebRequest)asyncResponse.AsyncState; HttpWebResponse someResponse = (HttpWebResponse)responseRequest.EndGetResponse(asyncResponse); TaskComplete.TrySetResult(someResponse); } catch (WebException webExc) { HttpWebResponse failedResponse = (HttpWebResponse)webExc.Response; taskComplete.TrySetResult(failedResponse); } }, request); return taskComplete.Task; } } }
This takes the event-based model that we use in Windows Phone and encapsulates it in a Task so we can use it in an await-async manner.
Second, I added this class to the same namespace to deliver an HttpMethod class that works with the same code that we would use in Windows 8.
public static class HttpMethod { public static string Head { get{return "HEAD";} } public static string Post { get{return "POST";} } public static string Put { get{return "PUT";} } public static string Get { get{return "GET";} } public static string Delete { get{return "DELETE";} } public static string Trace { get{return "TRACE";} } public static string Options { get{return "OPTIONS";} } public static string Connect { get{return "CONNECT";} } public static string Patch { get{return "PATCH";} } }
Now, to use this with our code above, we only need to add:
#if WINDOWS_PHONE using WinPhoneExtensions; #endif
to our class that makes the Http call and we’re good to go!
13 Responses to Windows 8 / Windows Phone Code Sharing: HttpWebRequest GetResponseAsync
Did anyone get it working for POST, PUT, DELETE etc?
Please share more information. Urgent!!!
You can open .NET 4.5 libraries using .NET Reflector, and you’ll see that GetResponseAsync is achieved much more simple than you suggest. I use this code that is actually just a copy-paste from disassembled .NET 4.5 assemblies:
public static Task GetResponseTaskAsync(this WebRequest webRequest)
{
Func<Task> function =
() => Task.Factory.FromAsync(
webRequest.BeginGetResponse, webRequest.EndGetResponse, null);
return Task.Run(function);
}
Pingback: Cant get Async (asynx await) download of JSON to work - Windows Phone 8 | BlogoSfera
I’m trying to get get a grasp on Windows 8 and Windows Phone 8 development. The most difficult aspect, so far, has been trying to figure out what is supported on each platform. Ideas like this are very helpful to bridge the gap and make simultaneous development more practical.
Thanks.
It isn’t work for me on Windows 8 because of response is null. 🙁
How would you change this to be able to send data with the post method?
Hey, were you able to use the above code for send POST data?
I’ll see if I can throw a sample together this week.
This works no problem in Windows Phone 8, but it can also work in Windows Phone 7.5 if you add the AsyncBridge reference or (for portable libraries) the Microsoft.Bcl.Async targeting pack.
Hi, Thank you for this tutorial.How to make this work for POST request?
Do have any demo with this? And this is only for WP8, right?
Pingback: Windows Store Developer Links – 2012-12-12 | Dan Rigby
Pingback: Windows 8 / Windows Phone Code Sharing: HttpWebRequest GetResponseAsync | Matthias Shapiro | Around computing
Pingback: Dew Drop – December 11, 2012 (#1,460) | Alvin Ashcraft's Morning Dew