Portable class libraries and fetching JSON
        Posted  
        
            by Jeff
        on ASP.net Weblogs
        
        See other posts from ASP.net Weblogs
        
            or by Jeff
        
        
        
        Published on Wed, 31 Oct 2012 21:41:00 GMT
        Indexed on 
            2012/10/31
            23:01 UTC
        
        
        Read the original article
        Hit count: 320
        
Windows RT
|surface
|.NET
|General Software Developm
|Visual Studio
|Windows Phone
After much delay, we finally have the Windows Phone 8 SDK to go along with the Windows 8 Store SDK, or whatever ridiculous name they’re giving it these days. (Seriously… that no one could come up with a suitable replacement for “metro” is disappointing in an otherwise exciting set of product launches.) One of the neat-o things is the potential for code reuse, particularly across Windows 8 and Windows Phone 8 apps.
This is accomplished in part with portable class libraries, which allow you to share code between different types of projects. With some other techniques and quasi-hacks, you can share some amount of code, and I saw it mentioned in one of the Build videos that they’re seeing as much as 70% code reuse. Not bad.
However, I’ve already hit a super annoying snag. It appears that the HttpClient class, with its idiot-proof async goodness, is not included in the Windows Phone 8 class libraries. Shock, gasp, horror, disappointment, etc. The delay in releasing it already caused dismay among developers, and I’m sure this won’t help.
So I started refactoring some code I already had for a Windows 8 Store app (ugh) to accommodate the use of HttpWebRequest instead. I haven’t tried it in a Windows Phone 8 project beyond compiling, but it appears to work.
I used this StackOverflow answer as a starting point since it’s been a long time since I used HttpWebRequest, and keep in mind that it has no exception handling. It needs refinement. The goal here is to new up the client, and call a method that returns some deserialized JSON objects from the Intertubes. Adding facilities for headers or cookies is probably a good next step. You need to use NuGet for a Json.NET reference. So here’s the start:
   using System.Net;      
using System.Threading.Tasks;       
using Newtonsoft.Json;       
using System.IO;
    namespace MahProject      
{       
    public class ServiceClient<T> where T : class       
    {       
        public ServiceClient(string url)       
        {       
            _url = url;       
        }
            private readonly string _url;
            public async Task<T> GetResult()      
        {       
            var response = await MakeAsyncRequest(_url);       
            var result = JsonConvert.DeserializeObject<T>(response);       
            return result;       
        }
            public static Task<string> MakeAsyncRequest(string url)      
        {       
            var request = (HttpWebRequest)WebRequest.Create(url);       
            request.ContentType = "application/json";       
            Task<WebResponse> task = Task.Factory.FromAsync(       
                request.BeginGetResponse,       
                asyncResult => request.EndGetResponse(asyncResult),       
                null);       
            return task.ContinueWith(t => ReadStreamFromResponse(t.Result));       
        }
            private static string ReadStreamFromResponse(WebResponse response)      
        {       
            using (var responseStream = response.GetResponseStream())       
                using (var reader = new StreamReader(responseStream))       
                {       
                    var content = reader.ReadToEnd();       
                    return content;       
                }       
        }       
    }       
}
   Calling it in some kind of repository class may look like this, if you wanted to return an array of Park objects (Park model class omitted because it doesn’t matter):
   public class ParkRepo      
{       
    public async Task<Park[]> GetAllParks()       
    {       
        var client = new ServiceClient<Park[]>(http://superfoo/endpoint);       
        return await client.GetResult();       
    }       
}
   And then from inside your WP8 or W8S app (see what I did there?), when you load state or do some kind of UI event handler (making sure the method uses the async keyword):
   var parkRepo = new ParkRepo();      
var results = await parkRepo.GetAllParks();       
// bind results to some UI or observable collection or something
   Hopefully this saves you a little time.
© ASP.net Weblogs or respective owner