0

我試圖從一個小的代碼編寫C#發送推送通知,這裏是代碼:從遠程服務器向通用Windows應用程序發送推送通知的示例代碼?

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和祕密是固定的,我早些時候獲得的變量。問題是遠程服務器返回400錯誤(錯誤的請求),但我不知道爲什麼。頻道創建成功,我遵循本指南:https://msdn.microsoft.com/en-us/library/windows/apps/xaml/hh868221.aspx和sid和祕密變量是指以前在Microsoft開發人員儀表板中創建的應用程序。 有人可以幫助我嗎?

回答

0

HTTP 400 error表示錯誤請求,這表示由於格式錯誤導致請求無法被服務器理解。換句話說,客戶端發送的請求並不遵循服務器的規則。

有跡象表明,必須包括在所有推送通知四個必需頭:X-WNS型內容類型內容長度,並授權

在使用HttpWebResponse,它應能自動設定的Content-Length你,但你仍然需要手動設置的Content-Type。對於烤麪包,平鋪和徽章通知,此標頭必須設置爲「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)); 
相關問題