具体代码如下
// Post to WNS
///
/// 推送接口
///
/// 应用程序机密
/// 程序包 SID
/// 客户端URI
/// 推送的内容.xml格式
///
///
///
public static string PostToWns(string secret, string sid, string uri, string xml,
string notificationType = "wns/toast", string contentType = "text/xml")
{
try
{
// 应该缓存此访问令牌。
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)
{
//提供的访问令牌已过期。获得一个新的,然后再尝试发送通知。
//因为缓存的访问令牌在24小时后过期,所以你可以期望每天至少从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)
{
// 通道URI不再有效。
// 从数据库中删除此通道,以防止向其发送通知的进一步尝试。
// 下次这个用户启动你的应用程序时,请求一个新的WNS频道。
// 你的应用程序应该检测到它的频道已经改变了,这应该会触发应用程序将新的通道URI发送到你的应用服务器。
return "无效的URI";
}
else if (status == HttpStatusCode.NotAcceptable)
{
// 这个频道被WNS切断了。
// 实现重试策略,以指数方式减少发送通知的数量,以防止再次节流。
// 此外,考虑导致您的通知被节流的方案。
// 您将通过限制发送给那些增加真正价值的通知来提供更丰富的用户体验。
return "WNS切断(被拒绝)";
}
else
{
// WNS以较不常见的错误作出响应。记录此错误以协助调试。
// 您可以在这里看到WNS响应代码的完整列表:
// 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;
}
}
// 授权,批准
[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);
}
App.xaml.cs 代码中。OnActivated 方法。用户点击推送消息后,会执行此方法。toast.Argument 。为 推送内容XML中的 launch=""。可以通过这个进行 传参数。