Code example
// Post to WNS
///
/// Notification Interface
///
/// Application Secrets
/// Package SID
/// Client URI
/// Notification content.xml
///
///
///
public static string PostToWns(string secret, string sid, string uri, string xml,
string notificationType = "wns/toast", string contentType = "text/xml")
{
try
{
// This access token should be cached.
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", notificationType);
request.ContentType = contentType;
request.Headers.Add("Authorization", String.Format("Bearer {0}", accessToken.AccessToken));
request.ContentLength = contentInBytes.Length;
using (Stream requestStream = request.GetRequestStream())
requestStream.Write(contentInBytes, 0, contentInBytes.Length);
using (HttpWebResponse webResponse = (HttpWebResponse)request.GetResponse())
return webResponse.StatusCode.ToString();
}
catch (WebException webException)
{
try
{
if (webException.Response == null)
return "webException: " + webException.Message;
HttpStatusCode status = ((HttpWebResponse)webException.Response).StatusCode;
if (status == HttpStatusCode.Unauthorized)
{
//The provided access token has expired. Get a new one and then try to send a notification.
//Because the cached access token expires after 24 hours, you can expect to get this response at least once a day from WNS.
GetAccessToken(secret, sid);
// We recommend that you implement a maximum retry policy.
return PostToWns(uri, xml, secret, sid, notificationType, contentType);
}
else if (status == HttpStatusCode.Gone || status == HttpStatusCode.NotFound)
{
// The channel URI is no longer valid.
// Remove this channel from the database to prevent further attempts to send notifications to it.
// The next time the user launches your app, request a new WNS channel.
// Your application should detect that its channel has changed, which should trigger the application to send a new channel URI to your application server.
return "invalid URI";
}
else if (status == HttpStatusCode.NotAcceptable)
{
// This channel was cut off by WNS.
// Implement a retry strategy to exponentially reduce the number of notifications sent to prevent further throttling.
// Also, consider the scenario that caused your notification to be throttled.
// You will provide a richer user experience by limiting the notifications sent to those that add real value.
return "WNS cut (rejected)";
}
else
{
// WNS responds with less common errors. Record this error to assist with debugging.
// You can see a full list of WNS response codes here:
// http://msdn.microsoft.com/en-us/library/windows/apps/hh868245.aspx#wnsresponsecodes
string[] debugOutput = {
status.ToString(),
webException.Response.Headers["X-WNS-Debug-Trace"],
webException.Response.Headers["X-WNS-Error-Description"],
webException.Response.Headers["X-WNS-Msg-ID"],
webException.Response.Headers["X-WNS-Status"]
};
return string.Join(" | ", debugOutput);
}
}
catch (Exception e)
{
return "EXCEPTION: WebException:" + e.Message;
}
}
catch (Exception ex)
{
return "EXCEPTION: " + ex.Message;
}
}
// authorization,approval
[DataContract]
public class OAuthToken
{
[DataMember(Name = "access_token")]
public string AccessToken { get; set; }
[DataMember(Name = "token_type")]
public string TokenType { get; set; }
}
private static 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 static 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);
}
In the App.xaml.cs code. OnActivated method. This method is performed when the user clicks on the notification. toast.Argument. You can pass parameters through this: launch="" in the notification content XML..