Quickstart: Sending a toast push notification (Windows Store apps using C#/VB/C++ and XAML)
This Quickstart walks you through the steps necessary for your cloud server to send a toast push notification to your app through the Windows Push Notification Services (WNS).
Objective: To create and send a push notification.
Prerequisites
- A working knowledge of tile and notification terms and concepts, as well as XML. This topic also assumes that you know how to create a basic Windows Store app with JavaScript using Windows Runtime APIs.
- Familiarity with push notification and WNS concepts, requirements, and operation as discussed in the push notification overview.
- An authenticated cloud server in possession of an access token issued to it by WNS. For more information, see How to authenticate with the Windows Push Notification Service (WNS).
- Toast notification XML content. For details on creating the toast content, see Quickstart: Sending a toast notification.
- The Toast Capable option must be set to "Yes" in your app's manifest to send or receive toast notifications. For more information, see How to opt in for toast notifications.
Instructions
1. Include the necessary namespace references
The examples given in this topic can be used as-is, but require that your code include these namespace references:
using System.Net;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
using System.Web;
2. Create an HTTP POST request.
The uri parameter is the channel Uniform Resource Identifier (URI) requested by the app and passed to the cloud server. For more information, see How to request, create, and save a notification channel.
HttpWebRequest request = HttpWebRequest.Create(uri) as HttpWebRequest;
request.Method = "POST";
3. Add the two required headers.
The accessToken parameter is the access token (stored on the server) that was received from WNS when the cloud server authenticated. Without the access token, you cannot send a notification.
For a complete list of possible headers, see Push notification service request and response headers.
request.Headers.Add("X-WNS-Type", type);
request.Headers.Add("Authorization", String.Format("Bearer {0}", accessToken.AccessToken));
4. Add the prepared toast content.
To the HTTP request, the XML content of the toast notification itself is a black box in the request body. The content is specified as an XML payload and here is added to the request as a stream of bytes.
byte[] contentInBytes = Encoding.UTF8.GetBytes(xml);
using (Stream requestStream = request.GetRequestStream())
requestStream.Write(contentInBytes, 0, contentInBytes.Length);
5. Listen for a response from WNS acknowledging receipt of the notification
Note that you will never receive a delivery confirmation for a notification, just an acknowledgment that it was received by WNS.
using (HttpWebResponse webResponse = (HttpWebResponse)request.GetResponse())
return webResponse.StatusCode.ToString();
6. Encapsulate the code into a single function
The following example packages the code given in the steps of this procedure into a single function that could be part of your cloud server code. It composes the HTTP POST request that contains a notification to be sent to WNS. By changing the value of the type parameter and adjusting the necessary headers, this code can be used for toast, tile, or badge push notifications.
Note that the error handling in this function includes the situation where the access token has expired. In this case, it calls another cloud server function that reauthenticates with WNS to obtain a new access token, and then makes a new call to the original function.
// Post to WNS
public string PostToWns(string secret, string sid, string uri, string xml, string type = "wns/toast")
{
try
{
// You should cache this access token
var accessToken = GetAccessToken(secret, sid);
byte[] contentInBytes = Encoding.UTF8.GetBytes(xml);
HttpWebRequest request = HttpWebRequest.Create(uri) as HttpWebRequest;
request.Method = "POST";
request.Headers.Add("X-WNS-Type", type);
request.Headers.Add("Authorization", String.Format("Bearer {0}", accessToken.AccessToken));
using (Stream requestStream = request.GetRequestStream())
requestStream.Write(contentInBytes, 0, contentInBytes.Length);
using (HttpWebResponse webResponse = (HttpWebResponse)request.GetResponse())
return webResponse.StatusCode.ToString();
}
catch (WebException webException)
{
string exceptionDetails = webException.Response.Headers["WWW-Authenticate"];
if (exceptionDetails.Contains("Token expired"))
{
GetAccessToken(secret, sid);
// Implement a maximum retry policy
return PostToWns(uri, xml, secret, sid, type);
}
else
{
// Log the response
return "EXCEPTION: " + webException.Message;
}
}
catch (Exception ex)
{
return "EXCEPTION: " + ex.Message;
}
}
// Authorization
[DataContract]
public class OAuthToken
{
[DataMember(Name = "access_token")]
public string AccessToken { get; set; }
[DataMember(Name = "token_type")]
public string TokenType { get; set; }
}
private OAuthToken GetOAuthTokenFromJson(string jsonString)
{
using (var ms = new MemoryStream(Encoding.Unicode.GetBytes(jsonString)))
{
var ser = new DataContractJsonSerializer(typeof(OAuthToken));
var oAuthToken = (OAuthToken)ser.ReadObject(ms);
return oAuthToken;
}
}
protected OAuthToken GetAccessToken(string secret, string sid)
{
var urlEncodedSecret = HttpUtility.UrlEncode(secret);
var urlEncodedSid = HttpUtility.UrlEncode(sid);
var body = String.Format("grant_type=client_credentials&client_id={0}&client_secret={1}&scope=notify.windows.com",
urlEncodedSid,
urlEncodedSecret);
string response;
using (var client = new WebClient())
{
client.Headers.Add("Content-Type", "application/x-www-form-urlencoded");
response = client.UploadString("https://login.live.com/accesstoken.srf", body);
}
return GetOAuthTokenFromJson(response);
}
Summary and next steps
In this Quickstart, you composed an HTTP POST request, including the toast notification content, to send to WNS. WNS, in turn, delivers the notification to your app.
By this point, you have registered your app, authenticated your cloud server with WNS, created XML content to define your notification, and sent that notification from your server to your app. Next, you can use an almost identical procedure to send a tile notification or badge push notification.
Related topics
How to request, create, and save a notification channel
Push notification service request and response headers
Build date: 9/4/2012