Ioannis Panagopoulos blog

Tutorials on HTML5, Javascript, WinRT and .NET

Push Notifications in Windows 8 with ASP.NET MVC

by Ioannis Panagopoulos

In the previous post we have seen how we create scheduled and periodic tile notifications with Javascript for metro applications.

In this post we will cover push notifications. Push notifications do not require from your app to tell the OS that it has to query a service at specific time intervals as periodic notifications do. They rely on the fact that an external service can actually change the tile when it sees fit (hence the “push” name).

Such notifications cover scenarios like having an application that monitors stock prices and the user specifying that he wants to be informed when the price of a stock falls under a specific value. The push notification will change the tile’s appearance when the premise is fulfilled. Note that a periodic notification would not suit in this case unless the user could accept a possible maximum half hour delay of the delivery of the notification.

Push notifications work as follows:

 

  1. Your metro app requests from the device a specific URI which uniquely defines the combination app/device.
  2. Your metro app then transmits this URI to the server application you have implemented (in our case you will see that this is a ASP.NET MVC project). Your metro app can also transmit any other information specific to the logic of the notification required from the user.
  3. Your server application receives and saves the URI and it also receives and saves the logic for the push notification (when and under what circumstances the metro app desires to be notified).
  4. In order for your server application to send the push notification to that URI, it has to tell the Windows Push Notification Service (WNS-simply a server application offered for free from Microsoft) and this service will contact the actual device based on the supplied URI with the desired notification. So prior to doing so, your server application needs to authenticate itself with that service.

 

Before doing anything else you need to register your app. Full instructions can be found here and differentiate on whether you are a registered developer for the store or you just want to play around to see how things work. We will choose the second approach and therefore the short version of the registration instructions (in the document of the link above this is located in the Remarks section). So proceed as follows::

 

  1. Navigate to this link.
  2. Follow the instructions by supplying the application’s name and the publisher as required and click next.
  3. You will get a bunch of items that you will need to put in your application’s manifest file. This has connected the WNS with your application so they both know that each other exists via the keys. This has also given you all the appropriate stuff for your server application to use in order to communicate with the app on a user’s device (in a sense the URI will supply the exact machine/app and the security keys you obtained are an extra safety).

 

You can now start developing your server application. Create a new ASP.NET MVC project, create a ServicesController and provide a Register action as follows:

   1: public JsonResult Register(string uri)
   2: {
   3:     string[] parms = HttpContext.Request.RawUrl.Split(new string[] { "uri=" }, 
                                                    StringSplitOptions.RemoveEmptyEntries);
   4:     Subscribers.Uris.Add(parms[1]);
   5:     return Json(new { Success = true, Uri = uri }, JsonRequestBehavior.AllowGet);
   6: }

Note here that although we receive as a parameter the uri of the subscriber we prefer it to get it from the query string of the raw URL. This is because ASP.NET MVC decodes the encoded URL. The problem is that the uri you receive is partially encoded (the link is not encoded while the parameters are) and therefore it is not possible to get it in its decoded version adn  encode it again. Take good care of that cause otherwise you will be getting a 404 not found error when you try to send the notification and you will not be able to know the source of the error.

The Subscribers list is the one that will hold the URIs to be notified (metro apps). For our demo the class resides in the Models folder and is as follows:

   1: public static class Subscribers
   2: {
   3:     public static List<string> Uris = new List<string>();
   4: }

Of course in reality you would persist this information along with the notification predicates in a DB or file storage since the static list can be wiped out at any time! For our demo though we are just fine with this.

Having done that, if we deploy this simple ASP.NET MVC project and we provide in the metro app the following lines of code:

   1: Windows.Networking.PushNotifications.PushNotificationChannelManager
   2:     WinJS.xhr({ url: "http://server.application.address/Register?uri=" + channel.uri })
   3:         if (xhr.status < 200 || xhr.status >= 300) {
   4:             var dialog = new Windows.UI.Popups
   5:             dialog.showAsync();
   6:         }
   7:     });
   8: });
   9:  

We basically create a URI and then pass it to the server application (we can encrypt it for security but in this demo for simplicity we leave it as is).

So, we have managed to notify our server application that the metro app exists, with the URI it got from the Windows 8 device and is ready to receive Push Notifications. Of course, we have not supplied any predicates on when we require to receive such notifications (the logic and encoding of the way this will be communicated to the server app is up to the developer but will probably reside in some encoded string in a query string parameter (ie parameters) specified after the uri parameter: http://addres?uri=…&parameters=… This will be decoded by the server app along with the URI. In our case we will be generating the notification whenever we want from the server application.

Now all we have to do is write the code that will send the tile notification. This code can reside in any kind of application (windows service, WPF app) but in our case we will just provide an action in the ServicesController that exposes a view with an input box and a button. When the user clicks on the button, the text of the input box is sent as a tile notification to all subscriber URIs. The action in high level is as follows:

   1: WNSAuthorizer.OAuthToken Token = WNSAuthorizer.GetOAuthToken(<clientsecret>,<packageSID>);
   2: foreach (var uri in Subscribers.Uris)
   3: {
   4:     PushNotifier Notifier = new PushNotifier(uri, Token.AccessToken);
   5:     Notifier.SendNotification(PushNotifier.PushType.Tile, msg, "");
   6: }

Where in <clientsecret> and <packageSID> you provide the credentials you got from registering the application for push notifications. The code above uses a helper class to get authorization with the WNS (WNSAuthorizer) and then uses a helper class (PushNotifier) to send the push notification to all recipients. The correct format of the tile notification can be seen if you download the code for the helper classes at the end of this post. Note that this code is based on the code given in the article. Basically the notification for the tile has identical xml payload with the one presented in the previous post for periodic and scheduled notifications. Also the code allows you to send different kinds of push notifications tile and badge.

 

And this is it! You have managed to build an ASP.NET MVC application that will be able to send push notifications to windows 8 metro style apps. The ASP.NET MVC project can be downloaded

(for obvious reasons the credentials have been removed from the project and therefore you need to supply the ones that apply to your app. The project is in VS2012 but you can open the files in VS2010 and see the logic).
blog comments powered by Disqus
hire me