0

私はC#で小さなコードの書き込みからのプッシュ通知を送信しようとしているが、ここでのコードは次のとおりです。リモートサーバーからユニバーサルWindowsアプリケーションにプッシュ通知を送信するコード例

channelUri、SIDと秘密は、私が以前に取得した変数を固定している
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); 
    } 

。問題は、リモートサーバーが400エラー(Bad Request)を返すことですが、理由はわかりません。チャンネルの作成は成功し、私はこのガイドに従っています:https://msdn.microsoft.com/en-us/library/windows/apps/xaml/hh868221.aspxとsidとsecret変数は、以前にマイクロソフトの開発者ダッシュボードで作成されたアプリを参照しています。 誰かが私を助けることができますか?

答えて

0

HTTP 400 errorを示しています。不正リクエストは、不正な構文のために要求がサーバーによって理解できないことを意味します。つまり、クライアントから送信されたリクエストはサーバーのルールに従いません。

すべてのプッシュ通知に含まれなければならない4つの必須のヘッダーがあります。X-WNS-TypeでのContent-TypeのContent-Length、および認証が。

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)); 
関連する問題