Using the MVC-Mini-Profiler with Entity Framework
[![Notice how the success sign points at the title?](/wp-content/uploads...
Finally we arrive at the thrilling conclusion to my push notifications miniseries. This time we will actually push a notification to a device we have previously recorded.
When we left off, we had created a WP7 App Project and a WCF Rest Service Project. Now we need to create a Windows Service or Console Application to run on the server, pushing notifications when it is necessary. So that we can see the results of our pushing easily, I’ve opted to create a Console Application.
If you take a quick look at this code, you’ll see that we are simply sending some XML to a URI given to us by Microsoft. We picked up the URI in my last post, so read back if you haven’t got one yet. Regardless, here’s the code:
public class PushNotifications
{
public string SendToast(string uri, string text1, string text2)
{
string template =
“<?xml version=’1.0’ encoding=’utf-8’?>” +
“
string toastXML = string.Format(template, text1, text2);
HttpWebRequest sendNotificationRequest = (HttpWebRequest)WebRequest.Create(uri);
sendNotificationRequest.Method = "POST";
sendNotificationRequest.Headers = new WebHeaderCollection();
sendNotificationRequest.ContentType = "text/xml";
sendNotificationRequest.Headers.Add("X-WindowsPhone-Target", "toast");
sendNotificationRequest.Headers.Add("X-NotificationClass", "2");
byte[] notificationMessage = new UTF8Encoding().GetBytes(toastXML);
sendNotificationRequest.ContentLength = notificationMessage.Length;
using (Stream requestStream = sendNotificationRequest.GetRequestStream())
{
requestStream.Write(notificationMessage, 0, notificationMessage.Length);
}
// Sends the notification and gets the response.
HttpWebResponse response = (HttpWebResponse)sendNotificationRequest.GetResponse();
string notificationStatus = response.Headers["X-NotificationStatus"];
string notificationChannelStatus = response.Headers["X-SubscriptionStatus"];
string deviceConnectionStatus = response.Headers["X-DeviceConnectionStatus"];
return notificationStatus;
}
public string SendLiveTile(string uri, string backgroundImageUrl, string title, int count)
{
string template =
"<?xml version='1.0' encoding='utf-8'?>" +
"<wp:notification xmlns:wp='WPNotification'>" +
"<wp:tile>" +
"<wp:backgroundimage>{0}</wp:backgroundimage>" +
"<wp:count>{1}</wp:count>" +
"<wp:title>{2}</wp:title>" +
"</wp:tile>" +
"</wp:notification>";
string tileXML = string.Format(template, backgroundImageUrl, count.ToString(), title);
HttpWebRequest sendNotificationRequest = (HttpWebRequest)WebRequest.Create(uri);
sendNotificationRequest.Method = "POST";
sendNotificationRequest.Headers = new WebHeaderCollection();
sendNotificationRequest.ContentType = "text/xml";
sendNotificationRequest.Headers.Add("X-WindowsPhone-Target", "token");
sendNotificationRequest.Headers.Add("X-NotificationClass", "1");
byte[] notificationMessage = new UTF8Encoding().GetBytes(tileXML);
sendNotificationRequest.ContentLength = notificationMessage.Length;
using (Stream requestStream = sendNotificationRequest.GetRequestStream())
{
requestStream.Write(notificationMessage, 0, notificationMessage.Length);
}
// Sends the notification and gets the response.
HttpWebResponse response = (HttpWebResponse)sendNotificationRequest.GetResponse();
string notificationStatus = response.Headers["X-NotificationStatus"];
string notificationChannelStatus = response.Headers["X-SubscriptionStatus"];
string deviceConnectionStatus = response.Headers["X-DeviceConnectionStatus"];
return notificationStatus;
}
}
There are a few things to note with the above code. First of all, the XML should be used exactly as is. I’ve heard of a few people having trouble because they missed a capital letter, or didn’t have all of the correct parameters.
Secondly, pay close attention to the headers we are sending. The X-WindowsPhone-Target header sets the type of notification we are pushing (Toast, Live Tile or Raw) and the X-NotificationClass header sets how quickly the notification will be delivered. I’ve only ever seen people use the most urgent value.
You can find some more info about the above code from How To: Send a Push Notification for Windows Phone
Lastly, to see if our message was successfully received by Microsoft’s servers, pay attention to the three headers we receive back from our web call. I pass the X-NotificationStatus back as it gives the best indicator of whether or not the notification worked.
I encourage you to take a look at the Push Notification Service Response Codes for Windows Phone to get an idea of the kinds of responses you could receive.
Just as an example, I’m going to setup our console app so that it pushes a notification to the last device added to our database whenever you press “P”. Check out the code:
public class Program
{
static void Main(string[] args)
{
Console.WriteLine("Welcome to the sample push notification server");
Console.WriteLine("Running... Press enter to exit");
bool running = true;
while (running)
{
var key = Console.ReadKey(true);
if (key.Key == ConsoleKey.Enter)
{
running = false;
}
else if (key.Key == ConsoleKey.P)
{
using (var context = new WP7AppDBEntities())
{
// First try to find an existing device
var device = (from d in context.Devices
orderby d.Added descending
select d).FirstOrDefault();
if (device != null)
{
PushMessage(device.URI, "Success", "We sent you a message!");
}
}
}
}
}
static void PushMessage(string uri, string mainText, string secondaryText)
{
Console.WriteLine(DateTime.UtcNow.ToString("dd/MM/yyyy hh:mm:ss ") + "Ready to Push Message - " + mainText);
if (!string.IsNullOrEmpty(uri))
{
try
{
PushNotifications p = new PushNotifications();
var pushresult = p.SendToast(uri, mainText, secondaryText);
Console.WriteLine(DateTime.UtcNow.ToString("dd/MM/yyyy hh:mm:ss ") + "Push Notification Sent: " + pushresult);
}
catch (Exception ex)
{
Console.WriteLine(DateTime.UtcNow.ToString("dd/MM/yyyy hh:mm:ss ") + "Error pushing toast notification: " + ex.Message + " - " + ex.StackTrace);
}
}
}
}
Essentially the above code waits for you to press “P”, pulls the most recently added device from the database we setup earlier and then sends a toast message to the device. I’ve also added some Console.Writes around the place so you can see what’s going on.
You can also use the above code to send a Live Tile update to a device, but that’s a blog post for another day.
Send me a message and I'll get back to you.