【问题标题】:Example code to send push notification from remote server to universal windows app?将推送通知从远程服务器发送到通用 Windows 应用程序的示例代码?
【发布时间】:2017-08-23 16:58:38
【问题描述】:

我正在尝试从一个用 c# 编写的小代码发送推送通知,代码如下:

public void Launch()
    {
            string channelUri = "channel uri";
            string sid = "sid package";
            string secret = "client secret";

            // toast notification
            var toast = @"<toast><visual><binding template=""ToastText01""><text id=""1"">Hello!</text></binding></visual></toast>";
            Console.WriteLine(this.PostToWns(secret, sid, channelUri, toast));

            Console.ReadLine();

    }

    // 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"] ?? string.Empty;
            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);
    }

其中 channelUri、sid 和 secret 是我之前获得的固定变量。问题是远程服务器返回 400 错误(错误请求),但我不知道为什么。频道创建成功,我遵循了这个指南:https://msdn.microsoft.com/en-us/library/windows/apps/xaml/hh868221.aspx 和 sid 和 secret 变量是指之前在微软开发者仪表板中创建的应用程序。 有人可以帮助我吗?

【问题讨论】:

    标签: c# push-notification win-universal-app windows-10-universal


    【解决方案1】:

    HTTP 400 error表示Bad Request,表示由于语法错误,服务器无法理解该请求。也就是说,客户端发出的请求不符合服务器的规则。

    所有推送通知中必须包含四个必需的标头:X-WNS-TypeContent-TypeContent-Length,以及授权

    在使用HttpWebResponse时,它应该可以自动为您设置Content-Length,但您仍然需要手动设置Content-Type。对于 toast、tile 和徽章通知,此标头必须设置为 "text/xml"。更多信息请见Send notification request

    HttpWebRequest request = HttpWebRequest.Create(uri) as HttpWebRequest;
    request.Method = "POST";
    
    request.Headers.Add("X-WNS-Type", type);
    request.ContentType = "text/xml";
    request.Headers.Add("Authorization", String.Format("Bearer {0}", accessToken.AccessToken));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-24
      • 2019-09-11
      • 1970-01-01
      • 1970-01-01
      • 2010-11-06
      相关资源
      最近更新 更多