why can't I send WNS toast notification from c# to windows phone 8.1

时间:2016-07-11 19:08:42

标签: c# push-notification windows-phone toast wns

I have followed these two guides: https://msdn.microsoft.com/en-us/library/windows/apps/hh202945(v=vs.105).aspx https://msdn.microsoft.com/library/windows/apps/xaml/hh868252

The resulting code is the following. Despite it all seems right, it returns a 404 error. How can this be? Any help will delay my suicide.

public static void PushToWindows2()
    {
        try
        {
            var accessToken = GetAccessToken("Nhz******************XkwX", "ms-app://s-1-15-2-***************-2150981501");

            byte[] contentInBytes = Encoding.UTF8.GetBytes("<toast launch=\"\"><visual lang=\"en-US\"><binding template=\"ToastImageAndText01\"><image id=\"1\" src=\"World\" /><text id=\"1\">Hello</text></binding></visual></toast>");

            HttpWebRequest request = HttpWebRequest.Create("https://db5.notify.windows.com/?token=awyaaaborhlhub%2bfxeytzjnz****************pftroh5l18sgorvgrkq%3d") as HttpWebRequest;
            request.Method = "POST";
            request.ContentLength = contentInBytes.Length;
            request.ContentType= "text/xml";
            request.Headers.Add("X-WindowsPhone-Target", "token");
            request.Headers.Add("X-NotificationClass", "1"); ;
            request.Headers.Add("X-WNS-Type", "wns/toast");
            request.Headers.Add("Authorization", String.Format("Bearer {0}", accessToken.AccessToken.ToString()));


            using (Stream requestStream = request.GetRequestStream())
                requestStream.Write(contentInBytes, 0, contentInBytes.Length);

            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            string notificationStatus = response.Headers["X-NotificationStatus"];
            string notificationChannelStatus = response.Headers["X-SubscriptionStatus"];
            string deviceConnectionStatus = response.Headers["X-DeviceConnectionStatus"];
        }
        catch (Exception ex)
        {
            Console.Write("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; }
    }

    public 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;
        }
    }

    public 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);
    }

I have also tried to go the PushSharp route, in which case, I get the "Device subscription has expired" error. Here goes:

 var config = new WnsConfiguration("424****.*******nts", "ms-app://s-1-15-2-***************1501", "Nhz************XkwX");
        // Create a new broker
        var wnsBroker = new WnsServiceBroker (config);
        wnsBroker.QueueNotification(new WnsToastNotification {
                ChannelUri = deviceId,
                Payload = XElement.Parse (@"
                    <toast>
                        <visual>
                            <binding template=""ToastText01"">
                                <text id=""1"">WNS_Send_Single</text>
                            </binding>  
                        </visual>
                    </toast>")
        });
    }

Update:

It is not encoding related either. I've used both the unencoded token with = and + signs and the encoding one. Still 404

1 个答案:

答案 0 :(得分:0)

WNS的HTTP 404错误意味着渠道URI本身已被包含,因此WNS无法理解它。从您的代码看起来,通道URI在某处得到了tolower()ed - 通常令牌开始于&#34; AwYAAAD&#34;。尝试删除低通道URI的任何内容。

此外,当您需要WNS时,您似乎正在混合使用WNS和MSDN文档(尽管这不会导致您的404错误)。 This是WNS,但this是MPNS文档。具体来说,这些标题用于MPNS,WNS将忽略或失败:

  • X-WindowsPhone的-目标
  • X-NotificationClass
  • X-NotificationStatus
  • X-SubscriptionStatus
  • X-DeviceConnectionStatus

您想要使用these WNS标头。