Archive for July, 2011

This post is a continuation of the first part (here) on Updating the underlying data behind an OData service.

So, we continue from where we left off. We have a SQL Azure table called “Team” which has its data exposed as an OData service. This can obviously be read easily by various clients; but what about updates? In the last post, we talked about how we can host a WCF Service in Azure that allows us CRUD operations on the underlying SQL Azure data. This does work; but what if you did not want to add a Service Reference to your project? Isn’t the promise of OData to be able to make plain HTTP requests to perform CRUD on data?

Yes, you are right. In this post, we see how to insert records into the SQL Azure DB table through OData by simply doing native HTTP Posts at the correct URL. Now, I will do this from a Windows Phone app, that is, Silverlight. This brings in the asynchronous factor since we cannot lock up the UI thread. Essentially, we need to open a Request channel at the right URL, write some byte content into the request stream & then expect a response back. In Silverlight, this means jumping through two different threads before coming back to the main UI thread. Check out this wonderful post on why we need to do this (here).

Now, in addition to the thread-hopping, our HTTP Post request needs to be formatted correctly in header & content for the OData endpoint to honor it. Here’s some code using the native “HttpWebRequest” from a Windows Phone app. Essentially, I am making an HTTP Post request against my SQL Azure OData service to insert a new Team member to our DB table:


       private void SubmitPost()
        {
            HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(new Uri("YourODataEndpoint"));
            myRequest.Method = "POST";
            myRequest.Accept = "application/atom+xml";
            myRequest.ContentType = "application/atom+xml;type=entry";
            myRequest.BeginGetRequestStream(new AsyncCallback(GetRequestStreamCallback), myRequest);
        }

        private void GetRequestStreamCallback(IAsyncResult asynchronousResult)
        {
            HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;
            System.IO.Stream postStream = request.EndGetRequestStream(asynchronousResult);

            XNamespace ds = "http://schemas.microsoft.com/ado/2007/08/dataservices";
            XNamespace dsmd = "http://schemas.microsoft.com/ado/2007/08/dataservices/metadata";
            var content =
              new XElement(dsmd + "properties",
                new XElement(ds + "Name", "Test"),
                new XElement(ds + "TwitterHandle", "@Test")
              );

            XNamespace atom = "http://www.w3.org/2005/Atom";
            var entry =
              new XElement(atom + "entry",
                new XElement(atom + "title", "A new team member"),
                new XElement(atom + "id", string.Format("urn:uuid:{0}", Guid.NewGuid())),
                new XElement(atom + "updated", DateTime.Now),
                new XElement(atom + "author",
                new XElement(atom + "name", "Sam")),
                new XElement(atom + "content",
                  new XAttribute("type", "application/xml"),
                  content)
              );

            byte[] postContentBytes = Encoding.UTF8.GetBytes(entry.ToString());
            postStream.Write(postContentBytes, 0, postContentBytes.Length);
            postStream.Close();
            request.BeginGetResponse(new AsyncCallback(GetResponseCallback), request);
        }

        private void GetResponseCallback(IAsyncResult asynchronousResult)
        {
            HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;
            HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asynchronousResult);
            Stream streamResponse = response.GetResponseStream();
            StreamReader streamRead = new StreamReader(streamResponse);
            string responseString = streamRead.ReadToEnd();   
            // Update some UI if needed.         
            streamResponse.Close();
            streamRead.Close();           
            response.Close();
        }

In addition to the native “HttpWebRequest”, the “WebClient” class also seems to get the job done; but you need to set the “WebClient.Headers” property correctly to make the right HTTP request. Check out this post (here) on details about HTTP communication from the Silverlight world. Anyway, here’s the corresponding code using WebClient class:


       private void PostUsingWebClient()
        {
            WebClient client = new WebClient();
            client.UploadStringCompleted += new UploadStringCompletedEventHandler(client_UploadStringCompleted);

            XNamespace ds = "http://schemas.microsoft.com/ado/2007/08/dataservices";
            XNamespace dsmd = "http://schemas.microsoft.com/ado/2007/08/dataservices/metadata";
            var content =
              new XElement(dsmd + "properties",
                new XElement(ds + "Name", "Test"),
                new XElement(ds + "TwitterHandle", "@Test")
              );

            XNamespace atom = "http://www.w3.org/2005/Atom";
            var entry =
              new XElement(atom + "entry",
                new XElement(atom + "title", "A new team member"),
                new XElement(atom + "id", string.Format("urn:uuid:{0}", Guid.NewGuid())),
                new XElement(atom + "updated", DateTime.Now),
                new XElement(atom + "author",
                new XElement(atom + "name", "Sam")),
                new XElement(atom + "content",
                  new XAttribute("type", "application/xml"),
                  content)
              );

            client.UploadStringAsync(new Uri("YourODataEndpoint", UriKind.Absolute), entry.ToString());
        }
        
        void client_UploadStringCompleted(object sender, UploadStringCompletedEventArgs e)
        {
            if (e.Error != null)
            {
                // Oops
            }
            else
            {
                // Success
            }
        }

So, that’s it. Performing CRUD operations against an OData service isn’t all that bad, is it?

Hope this was of some interest. Please drop comments.

Adios!

This will be a longish post .. you have been warned :)

I think OData is rather cool .. head over (here) to learn more, if you haven’t already. There is nothing proprietary  about it; just culmination of existing technologies of HTTP, AtomPub and Json to provide a platform independent way of sharing information. As I heard someone say “..think of it as RSS for real updateable data..” and in this new age of www as a collection of connected web services rather than collection of web pages, I think OData can play an important role. Why the restrictions against opening up our data to interoperability if we can put adequate security on it?

Now, I wanted to talk about OData from a Windows Phone standpoint (specially WP7.5 or Mango); but also something that applies equally & is just as easily doable on other mobile OS platforms. Most well-designed mobile solutions these days also have a web interface that allows for easier data entry than on a phone form factor; yet data has to stay in sync whenever the user switches between platforms. A centralized data repository with OData feeds seems perfect for a case like this .. so, that’s what we shall talk about in this post.

After looking around a little bit on OData & WP7, I found a lot of examples on how to set up an OData source & consume the feeds from a Windows Phone app. This is obviously the first step & rather important as we shall see; but I also wanted to see if I could set up CRUD operations from WP7 back to the OData source. In the meantime, check out these few posts on how to consume OData in the first place:

  • Surely, one of the best ways to play with OData in real world is the Netflix catalog. Netflix worked with MSFT to expose their entire data set through an OData service (here) and now it becomes easy for various applications to consume the vast information in their catalog. This series of posts (here) covers how to build a Windows Phone client to browse through the Netflix catalog.
  • Michael Crump did this brilliant series on how to set up an OData source & consume it in Silverlight/Windows Phone. You may find it (here).
  • Post (here) from your’s truly on how to consume OData feeds from SQL Azure in a Windows Phone app.

Now all this is cool; but what if you wanted to update the OData source from your Windows Phone app? Isn’t that the promise of OData? Sure, we can do CRUD in Windows Phone 7.0; it just gets much easier in Mango. And the beauty of it is that it can be done completely without adding a service reference (proxy) to the OData service; simply HTTP Post with the correct request at the right URL. And this works the same way in iOS, Android or any darn platform .. that is where lies the nicety of OData.

For our data repository, lemme again chose SQL Azure, which gives us a nice way to expose our data globally through a simple OData feed. Please see my previous post (here) on how to set up a simple web application to reach out to create/manipulate data in SQL Azure & have it consumed in a Windows Phone app. Now, we really want the Windows Phone version to be able to update data records back in Azure & have it picked up seamlessly in the web application or any other consumer .. wouldn’t that be nice!

So, we start with a simple table called “Team” which is hosted in SQL Azure & has the data schema as below:

SQL Azure Team Table

The data in the table is then exposed out as an OData service with these steps:
  • Heading over to https://www.sqlazurelabs.com/ and logging in to the OData service with admin credentials.
  • Then, we select the DB & Table and check the OData checkbox.
  • For authentication, we select Anonymous Access so that anybody may access the data without security sign-ons. In real world, this is obviously not good practice. In essence however, Anonymous Access really uses the “dbo” or your admin credentials for SQL Azure operations. So, it should not be too difficult to create users for SQL Azure access & giving them appropriate access rights. This way, the OData service will require submission of security tokens (through ACS or some other federated authentication source) for data access/updates. This post (here) describes the intricacies of the Azure OData service wonderfully. Make sure you copy the OData URL as exposed by your SQL Azure instance.

Next, we talk about 3 ways in performing updates to the underlying SQL Azure database through the OData service. First, through our own hosted service in Azure. Here are the steps:
  1. Make sure you have the Azure VS SDK (get is from here). This ensures that we can create projects with the Azure wrapper so that our service may be hosted easily in Azure.
  2. File — New Project — Cloud — Windows Azure Project. This creates the Azure wrapper project. Let’s add an ASP.NET Web Application project to be hosted as Web Role.
  3. In the ASP.NET project, Add a new item of type ADO.NET Data Entity. This is essentially the ORM mapper that reflects on DB schema and gives us .NET object to play with. In the setup wizard, we make it use an Existing DB & point to the OData Service URL as exposed by our SQL Azure table. You will be required to enter your SQL Azure Admin DB credentials or some other user access details. This should build the proxies out of the OData metadata, and thus expose the service offerings to our project. For our “Team” table in SQL Azure exposed through OData, the data model looks like this:
  4. ADO.NET Data Entity

     

     

     

     

     

     

     

     

     

     

     

  5. Next, we add a WCF Data Service to the project which should expose out the data provided by the ADO.NET data service. The configuration of the SVC.cs file should look something like this:
  6. 
    using System;
    using System.Collections.Generic;
    using System.Data.Services;
    using System.Data.Services.Common;
    using System.Linq;
    using System.ServiceModel.Web;
    using System.Web;
    
    namespace WebRole1
    {
        public class DemoService : DataService
        {
            // This method is called only once to initialize service-wide policies.
            public static void InitializeService(DataServiceConfiguration config)
            {
                config.SetEntitySetAccessRule("Teams", EntitySetRights.All);            
                config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
            }
        }
    }
    
    

  7. Notice how we ask for building a collection of data objects of the same entity type as exposed by our ADO.NET data model. Also, we allow this service to have access rights of “All ” so that we may perform CRUD against the SQL Azure table at will.
  8. If everything goes well, we should be able to right-click on the .SVC file & do a “View in Browser“. This should get us to the same OData view as in Azure; you should be able to drill in & see all your data through OData filtering on browser URL.
  9. Local WCF Service exposing OData


     

  10. So, by now we have our own service ready & pointed to the SQL Azure OData service with user credentials configured as needed. Now, this service is ready for primetime hosting in Azure.
  11. We right click on the solution & choose “Publish” and create the packages locally in our bin directory. This makes two files — a .cspkg application wrapper & a .cscfg configuration file.
  12. We simply create a new Hosted Service in Azure and push out these files & swap their IP to be Production. The end state looks something like this:

WCF Service in Azure

That’s it! We now have our own configured WCF Service hosted in Azure. We can try hitting the Production SVC URL to make sure we have access to the same OData stream.

Now, let’s switch focus to our Windows Phone app. We can obviously read data out of the Azure OData feed pretty easily, as evident (here). What we want to be trying to do is to add records into the SQL Azure table from the Windows Phone app. Accordingly, we add a little UI for allowing data entry; end goal is something like this:

Team in WP7

Added Team Member through WP7

The way we go about doing this is by adding a Reference to our own WCF Service hosted in Azure, as below. Please note, that this will work only in Windows Phone 7.1 Mango tooling:

Add WCF Service Ref.

With the service reference under our belt, we now have a direct context of the OData service in Azure. Accordingly, we can have access to “Team ” collection objects in code & be able to manipulate them at will. In our case, we already have Sam & Jeff in the SQL Azure table; we want the phone app to add a new member Mike. Here’s some code:


using Demo;
using System.Data.Services.Client;

namespace SQLAzureOData_Demo
{
    using DemoService;

    public partial class MainPage : PhoneApplicationPage
    {
       private static DemoEntities wcfContext = null;

       private void InsertDataThruService()
        {
            wcfContext = new DemoEntities(new Uri("http://YourAzureServiceNDS.cloudapp.net/DemoService.svc/"));

            var TeamMember = Team.CreateTeam(3);
            TeamMember.Name = "Mike";
            TeamMember.TwitterHandle = "@michaelcollier";

            var collection = new DataServiceCollection(wcfContext);
            collection.Add(TeamMember);
            wcfContext.BeginSaveChanges(new AsyncCallback(SaveChangesCB), null);
        }

        private void SaveChangesCB(IAsyncResult asynchronousResult)
        {
            // Warning: You are on a different thread!
            // Success or Error Handling.
            Dispatcher.BeginInvoke(() =>
                {
                    MessageBox.Show("All done!");
                    LoadTeam();
                });
        }
     }
}

Just a few points to mention. On hitting the “+” App icon, I have a little UI pop-up that accepts the new Team members Name & TwitterHandle. The code sample above hard-codes the user; but you get the point that the UI needs to fire the “InsertDataThruService” method. Once we have the “WCFContext”, you can see how easy it gets to manipulate the data through any CRUD operations. Another important point to keep in mind is that the “BeginSaveChanges” call is asynchronous, this being Silverlight. So, the “SaveChangesCB” callback delegate does not fire on the same UI thread. This is important to keep in mind if you start wondering why the message pop-up or the refresh of the Team member list in our case, does not fire.

That’s it, few steps; but now we have a fully functional data repository that exposes OData feeds and can be read/updated from multiple platforms. This Service Reference way is just one way to do CRUD on an OData service though. In the next post, we talk about how to do this natively.

Hope this was helpful.

Adios!

Recently I had to work on a cross-platform mobile app, meant for internal use in our company. The iOS & Android versions were ready to ship; Windows Phone 7 just could not lag behind. It was mostly static content (lots of it) to display and centralization of data was important for content updates. Even before the Windows Phone app was started, much of the content was centralized for mobile device consumption and the format was HTML. Since it was mostly textual data with bulleted sections, I guess it was decided to marry pure data with some display pieces.

So, now the challenge was to design a Windows Phone 7 app that had rich metro UI; but mostly rendered HTML! The control of choice to display all this data was the WebBrowser control, which takes remote or local HTML and renders content using the IE shell in a Windows Phone. Thankfully, the content only had HTML snippets of data and not a full HTML DOM that the WebBrowser renders; so there was an opportunity to style some of the content to match the theme of the Windows Phone app. So, essentially, right before we hand-off the local HTML to our WebBrowser control, we got to give it some header/metedata or styling information.

I cannot post screenshots of the WP7 app for confidentiality; but here’s some code in use:


    private void webBrowserControl_Loaded(object sender, RoutedEventArgs e)
    {
       webBrowserControl.NavigateToString(FormatHTML("Local_HTML_Filepath"));
    }

    private string FormatHTML(string filePath)
    {
       string result = string.Empty;
       var ResourceStream = Application.GetResourceStream(new Uri(filePath, UriKind.Relative));

       if (ResourceStream != null)
       {
          Stream myFileStream = ResourceStream.Stream;

          if (myFileStream.CanRead)
          {
              using (StreamReader myStreamReader = new StreamReader(myFileStream))
              {
                  StringBuilder htmlText = new StringBuilder();
                  htmlText.Append("<html><meta name='viewport' content='width=400,user-scalable=no'/>");
                  htmlText.Append("<body bgcolor='ThemeColor'>");
                  htmlText.Append("<font color='SomeFontColor' size='SomeSize'>");
                  htmlText.Append("<link rel='stylesheet' type='text/css' href='someURI'>");
                  htmlText.Append(myStreamReader.ReadToEnd());
                  htmlText.Append("</font>");
                  htmlText.Append("</body>");
                  htmlText.Append("</html>");
                  result = htmlText.ToString();
               }
          }
       }

       return result;
     }

Now, before you start thinking this is all too basic, there are couple of very important caveats. First, the HTML rendered by the webbrowser control cannot have a transparent background ; so your hopes of preserving the theme of the underlying XAML page are futile. Also, any URI references that you make towards styling the content cannot come from local application package !! For example, if you have an image that you package as a resource/content in your Windows Phone project, it cannot be used as a background image for your HTML content. Needless to say, I find this restrictive and had to fight my way around this. If someone knows a way to use local resources for styling, please please drop me a comment.

So, essentially we have two options for referencing media or CSS for styling our HTML for the WebBrowser to render. One — make the resource available on the internet; that is, through an unique absolute HTTP URL. Or Two — store the resource as a file in Isolated Storage on the phone and then use the relative filepath from isolated storage in your CSS. These are the only two ways I know how to reference an external resource while styling HTML. Like I said, I would love to hear how other’s are doing this or any other ideas.

Adios!

This post is a continuation of Part 1 (here) & Part 2 (here) of the series on setting up a cloud-enabled Weather app for Windows Phone.

By now, we have a fully working Windows Phone app which allows the user to pull up weather forecasts for any city of their choice. We also Push Enabled the app so that any number of cities can be pinned to the start screen using the Mango secondary Live Tiles. Now, the only thing left to do is to have some sort of a service running in the cloud or some server that is able to keep track of all these cities the user has chosen to pin &  for the service to be able to push out live weather feeds at pre-defined/customized intervals. Now, for hosting such a service, I chose to utilize a free subscription I had in Azure; this could just as well be done on any machine running IIS with open ports.

Let’s add my thoughts here on the utilization of Azure cloud infrastructure for supplementing a mobile solution. As Windows Phone & other mobile platforms have shown us, smartphones do a lot with their small batteries & any work we can offload from it’s small processing power, helps in increasing battery life & hence user experience. As such, most connected Mobile solutions could compromise of a client running on the phone & some cloud support which does the repetitive heavy-lifting for the phone, sparing it from polling. Now, Windows Azure with its vast infrastructure for scalability could provide the perfect hosting solution for cloud service support; but there are some considerations. If you have MSDN subscription, you get some Azure processing & storage time free. After some benefit upgrades earlier this year, this Azure subscription can come in very handy, as you could really keep a couple of services with storage & decent bandwidth requirements running free 24/7 all month long. However, if your MSDN is paid for by your employer, and you are using it to host a cloud service that will empower your mobile app through which you make money, you are in shady territory :) So, my advice would be to check subscription & legal details to make sure you are safe. Another option is to flat-out pay for Azure services if you know your mobile app is that good & you will need the cloud support. My experience says that you need to be able to justify a $30 cost per month to be able to break even on Azure costs; be it through a paid app or advertisements. The $30 number though could fluctuate a lot based on what the needs are for your service hosting; it is simply based on my experience on running a simple service in Azure on 2 small instances & using some table storage.

So, with my babbling out of the way, here is the Azure hosted cloud service that acts as the backend for our Weather app, as it appears in the Azure portal. Now, this is set up to feed the Windows Phone Live Tiles; however, please take note that it can easily be set up to support iOS & Android Push Notifications. The Azure Toolkit for WP7 (here) already support iOS notifications, with Android support coming soon.

Azure WeatherLite Backend Service

The highlighted URL is where we get to hit up Azure to access the hosted service. This is what we had used to add a service reference for building proxies in our Windows Phone solution. With the metadata exposed, the phone app could call into any methods supported by the service. So, let’s see how we set up the cloud service. Here’s the project setup for the backend VS Solution:

WeatherBackend Project

WeatherBackend Project

 

 

 

 

 

 

 

 

 

 

 

 

So, our cloud backend solution is created using the Azure cloud solution template in VS & is made of 3 projects:

  • WeatherBackendCloud:
    This is the Azure wrapper project that includes the deliverables from the other two projects & provides for deployment settings for our service in the cloud.
  • WeatherBackendCloudSite:
    This is sort-off the web front-end of our service; essentially the WCF service is hosted inside of IIS as a web application. This project provides the “svc” WCF endpoint for our service and a 404 for everything else. Check out this wonderful video tutorial by Aaron Skonnard on how to set up your WCF service to run in IIS (here).
  • WeatherLiteBackend:
    This is our core WCF service that exposes the methods that our Windows Phone app calls into. This project includes the core processing of fetching Weather from Yahoo, packaging it up in a Push Notification payload & sending it out in an HTTP Post to the phone’s unique Channel URI in MPNS.

Now, about some implementation. The interface in our WCF project defines a standard for some methods exposed to consuming applications. The “Register” call that our phone app makes to let the cloud service know about Channel URI, city of choice & Secondary Live Tile ID has been defined as such:


    [ServiceContract]
    public interface IRegistrationService
    {        
        [OperationContract, WebGet]        
        void Register(string channelURI, int WOEID, string liveTileURI);
    }

The actual implementation of our Registration service simply hangs on to the request parameters from the phone, performs core processing to fetch weather & builds a payload for submitting to MPNS. Since this is just for demo purposes, I am storing the subscriber’s Channel URIs in session memory, since the Registration service has been defined as a “Singleton” class. For any cloud services headed for Production, you would have to consider storing the URI & other needed subscriber details in Azure table storage or SQL Azure. Here’s what I am doing:


    [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
    public class RegistrationService : IRegistrationService
    {
        public void Register(string channelURI, int woeid, string liveTileURI)
        {
           // Add subscriber details to some list.

           WeatherLiteBackendCore coreEngine = new WeatherLiteBackendCore();
           coreEngine.PerformCoreProcessing();
        }
    }

    public class WeatherLiteBackendCore
    {
        public void PerformCoreProcessing()
        {
            // Fetch current list of Subscribers.
            SubscriberList = RegistrationService.GetSubscribers();

            if (SubscriberList == null || SubscriberList.Count == 0)
                return;

            foreach (Subscriber WP7Client in SubscriberList)
            {
                // Pick up the URIs.
                subscriberChannelUri = new Uri(WP7Client.ChannelUri);
                subscriberLiveTileUri = new Uri(WP7Client.LiveTileUri);

                // Fetch weather for registered location.
                // Send out Tile update payload to MPNS.                
            }
        }
    }

Our “WeatherBackendCloudSite” simply sets up the service endpoint to use the “RegistrationService”; here’s the config in “Registration.svc”:


     <%@ ServiceHost Language="C#" Debug="true" Service="WeatherLiteBackend.RegistrationService" %>

Now, the “PerformCoreProcessing()” method is also invoked once every hour (set at application level) to get a list of all WP7 subscribers & send out appropriate live weather feeds to all. Also, the “WeatherLiteTileNotificationSender” helper class builds the requisite payloads required to send out the Live Tile updates. Please see my earlier post (here) on exactly what the payloads need to look like for the Windows Phone OS to process the incoming data bits as Live Tiles or Toast notifications. Here’s the old-school way of building a secondary Live Tile payload & submitting to MPNS for delivery to subscribing phones:


        private static byte[] PrepareTilePayload()
        {
            MemoryStream stream = new MemoryStream();
            XmlWriterSettings settings = new XmlWriterSettings() { Indent = true, Encoding = Encoding.UTF8 };
            XmlWriter writer = XmlTextWriter.Create(stream, settings);
            writer.WriteStartDocument();
            writer.WriteStartElement("wp", "Notification", "WPNotification");
            writer.WriteStartElement("wp", "Tile", "WPNotification");            
            writer.WriteStartAttribute("ID");
            writer.WriteValue(appropriateLiveTileURI);
            writer.WriteEndAttribute();
            writer.WriteStartElement("wp", "BackgroundImage", "WPNotification");
            writer.WriteValue(appropriatebackgroundImageUri);
            writer.WriteEndElement();
            writer.WriteStartElement("wp", "Count", "WPNotification");
            writer.WriteValue(appropriateTemp.ToString());
            writer.WriteEndElement();
            writer.WriteStartElement("wp", "BackTitle", "WPNotification");
            writer.WriteValue(appropriateCity);
            writer.WriteEndElement();
            writer.WriteStartElement("wp", "BackContent", "WPNotification");
            writer.WriteValue(appropriateWeatherCondition);
            writer.WriteEndElement();
            writer.WriteEndDocument();
            writer.Close();

            byte[] payload = stream.ToArray();
            return payload;
        }

        private void SendMessage(Uri channelUri, byte[] payload, NotificationType notificationType, SendNotificationToMPNSCompleted callback)
        {  
            try
            {
                // Create and initialize the request object.
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(channelUri);
                request.Method = WebRequestMethods.Http.Post;
                request.ContentType = "text/xml; charset=utf-8";
                request.ContentLength = payload.Length;
                request.Headers[MESSAGE_ID_HEADER] = Guid.NewGuid().ToString();
                request.Headers[NOTIFICATION_CLASS_HEADER] = ((int)notificationType).ToString();

                if (notificationType == NotificationType.Toast)
                    request.Headers[WINDOWSPHONE_TARGET_HEADER] = "toast";
                else if (notificationType == NotificationType.Token)
                    request.Headers[WINDOWSPHONE_TARGET_HEADER] = "token";

                request.BeginGetRequestStream((ar) =>
                {                   
                    Stream requestStream = request.EndGetRequestStream(ar);
                   
                    requestStream.BeginWrite(payload, 0, payload.Length, (iar) =>
                    {                      
                        requestStream.EndWrite(iar);
                        requestStream.Close();
                        
                        request.BeginGetResponse((iarr) =>
                        {
                            using (WebResponse response = request.EndGetResponse(iarr))
                            {                               
                                // Give back response to callback method, if any.
                            }
                        },
                        null);
                    },
                    null);
                },
                null);
            }
            catch (WebException ex)
            {
                // Do something.
            }
        }

That’s about it with the code. Once everything compiles & works with locally hosted service, we simply right-click on the cloud wrapper project & allow it to create Azure packages locally. This generates two files in the Bin/Publish directory of the Azure solution — one .cscfg file containing configuration & one .cspkg package container containing the deployable deliverables of the project. Now, we simply create a new hosted solution in Azure & upload these two files into a Production environment to expose the cloud service endpoint for our Windows Phone application. We then have a service running in Azure that the phone application can reach out to if the user chooses to pin a city’s weather to start screen & one that pushes out live weather feeds to the secondary Live Tiles. Voila!

Hope this series was helpful. Please drop comments if you see something that could be done better or have any other thoughts.

Adios!