Sending a raw notification differs from sending tile and toast notifications in that there is greater flexibility over the contents of the body of the notification.
Listing 15.3 demonstrates sending an object as part of a raw notification, using a DataContractJsonSerializer
. As with tile and toast notifications, we create an HttpWebRequest
, convert the content to a byte array, and then write it to the request Stream
. Finally, we verify that the notification was correctly received by the MPNS.
public PushNotificationSendResult SendRawNotification(
object content, string url, PushNotificationPriority priority)
{
string priorityHeader;
if (priority == PushNotificationPriority.RealTime)
{
priorityHeader = "5";
}
else if (priority == PushNotificationPriority.Priority)
{
priorityHeader = "16";
}
else
{
priorityHeader = "26";
}
/* Create the http message that will be sent
* to the Microsoft hosted server. */
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
/* HTTP POST is the only allowed method to send the notification. */
request.Method = "POST";
request.ContentType = "application/json; charset=utf-8";
request.Headers = new WebHeaderCollection {
{ "X-MessageID", Guid.NewGuid().ToString()},
{ "X-NotificationClass", priorityHeader } };
/* The message will be sent as a byte array. */
byte[] contentBytes;
var serializer = new DataContractJsonSerializer(content.GetType());
using (MemoryStream stream = new MemoryStream())
{
serializer.WriteObject(stream, content);
contentBytes = stream.ToArray();
}
request.ContentLength = contentBytes.Length;
using (Stream requestStream = request.GetRequestStream())
{
requestStream.Write(contentBytes, 0, contentBytes.Length);
}
/* Get the response after the message is sent. */
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
string notificationStatus = response.Headers["X-NotificationStatus"];
string subscriptionStatus = response.Headers["X-SubscriptionStatus"];
string deviceConnectionStatus
= response.Headers["X-DeviceConnectionStatus"];
PushNotificationSendResult result = CreateSendResult(
notificationStatus, deviceConnectionStatus, subscriptionStatus);
return result;
}
The use of the DataContractJsonSerializer
is convenient because it allows you to serialize an entire object on the server in a format that is compatible with the phone. With little effort the object can be rehydrated on the client. You could, however, use another payload format, such as a string, as shown in the tile and toast notification examples.
Tip
The DataContractJsonSerializer
type, as shown in this example, was chosen over the more commonly used DataContractSerializer
because JSON serialization is more space efficient than XML, producing a payload of much smaller size. This is important because the maximum body size for a toast, tile, or raw notification is 1KB.
The DataContractJsonSerializer
approach relies on the content object’s class being decorated with DataContract
and DataMember
attributes, as shown in the following example:
[DataContract]
public class StockQuote
{
[DataMember]
public string StockSymbol { get; set; }
[DataMember]
public double LastPrice { get; set; }
[DataMember]
public double ChangeInPrice { get; set; }
}
The DataContract
and DataMember
attributes provide the DataContractJsonSerializer
with the information it needs to serialize the StockQuote
object. Neglecting to decorate a property with a DataMember
attribute causes that property to be ignored, and its value to be absent when the object is deserialized in the client application.
18.223.169.197