无法发送 WNS 推送通知
WNS push notification cannot be sent
我正在使用以下代码向我的应用程序发送推送原始通知。该代码取自 official documentation.
中给出的示例
public string PostToWns(string secret, string sid, string uri, string xml, string notificationType, string contentType)
{
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));
using (Stream requestStream = request.GetRequestStream())
requestStream.Write(contentInBytes, 0, contentInBytes.Length);
using (HttpWebResponse webResponse = (HttpWebResponse)request.GetResponse())
// ^^^^^ This throws an exception ^^^^^
return webResponse.StatusCode.ToString();
}
catch (WebException webException)
{
HttpStatusCode status = ((HttpWebResponse)webException.Response).StatusCode;
if (status == HttpStatusCode.Unauthorized)
{
GetAccessToken(secret, sid);
return PostToWns(uri, xml, secret, sid, notificationType, contentType);
}
else if (status == HttpStatusCode.Gone || status == HttpStatusCode.NotFound)
{
return "";
}
else if (status == HttpStatusCode.NotAcceptable)
{
return "";
}
else
{
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 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);
}
服务器总是returnsUnauthorized
。但是,我能够毫无问题地获得令牌,并且使用的通道 URL 是在 official example.
中获得的
整个代码一次执行,所以我怀疑令牌每次都过期。
我尝试使用在线工具检查推送通知是否有效,但同样的 Unauthorized
错误发生在那里。
我必须在某个地方注册 WNS 吗?我的应用程序已经在应用商店中,并且我从 Live Services 网站获得了 ID 和密码。我使用这些作为凭证来获取令牌并且每次都获取令牌。我将此描述为相关问题的一部分:Proper WNS credentials.
有没有人有任何想法或解决方案?
我在另一个问题中找到了答案:Windows Notifications Service: 401 Invalid Token when trying to create a Toast notification in PHP。
client_id
必须是完整的 SID(包括协议前缀)和 client_secret
密码。
我正在使用以下代码向我的应用程序发送推送原始通知。该代码取自 official documentation.
中给出的示例public string PostToWns(string secret, string sid, string uri, string xml, string notificationType, string contentType)
{
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));
using (Stream requestStream = request.GetRequestStream())
requestStream.Write(contentInBytes, 0, contentInBytes.Length);
using (HttpWebResponse webResponse = (HttpWebResponse)request.GetResponse())
// ^^^^^ This throws an exception ^^^^^
return webResponse.StatusCode.ToString();
}
catch (WebException webException)
{
HttpStatusCode status = ((HttpWebResponse)webException.Response).StatusCode;
if (status == HttpStatusCode.Unauthorized)
{
GetAccessToken(secret, sid);
return PostToWns(uri, xml, secret, sid, notificationType, contentType);
}
else if (status == HttpStatusCode.Gone || status == HttpStatusCode.NotFound)
{
return "";
}
else if (status == HttpStatusCode.NotAcceptable)
{
return "";
}
else
{
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 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);
}
服务器总是returnsUnauthorized
。但是,我能够毫无问题地获得令牌,并且使用的通道 URL 是在 official example.
整个代码一次执行,所以我怀疑令牌每次都过期。
我尝试使用在线工具检查推送通知是否有效,但同样的 Unauthorized
错误发生在那里。
我必须在某个地方注册 WNS 吗?我的应用程序已经在应用商店中,并且我从 Live Services 网站获得了 ID 和密码。我使用这些作为凭证来获取令牌并且每次都获取令牌。我将此描述为相关问题的一部分:Proper WNS credentials.
有没有人有任何想法或解决方案?
我在另一个问题中找到了答案:Windows Notifications Service: 401 Invalid Token when trying to create a Toast notification in PHP。
client_id
必须是完整的 SID(包括协议前缀)和 client_secret
密码。