private static string NotificationLogMessage(string message, string description, NotificationSendResult result, string payload, WebRequest request, WebResponse response) { var sb = new StringBuilder(); sb.AppendFormat("{0}: {1}", message, description); sb.AppendLine(); sb.AppendLine(result.ToString()); sb.AppendLine(); if (request != null) { sb.AppendLine("- REQUEST ------------------------------------------------------------------"); HttpHeaders(sb, request.Headers); sb.AppendLine(); } sb.AppendLine(payload); if (response != null) { sb.AppendLine(); sb.AppendLine("- RESPONSE -----------------------------------------------------------------"); HttpHeaders(sb, response.Headers); if (response.ContentLength > 0) { var responseStream = response.GetResponseStream(); using (var reader = new StreamReader(responseStream)) { var responseBody = reader.ReadToEnd(); if (!string.IsNullOrEmpty(responseBody)) { sb.AppendLine(); sb.AppendLine(responseBody); } } } } return sb.ToString(); }
public static NotificationSendResult Send(Uri channelUri, IAccessTokenProvider accessTokenProvider, string payload, NotificationType type, int? secondsTTL = null, bool? cache = null, bool? requestForStatus = null, string tag = null, NotificationPriority priority = NotificationPriority.Normal, int tokenRetry = 0) { NotificationSendResult result; byte[] payloadBytes; HttpWebRequest request = null; try { WnsDiagnostics.TraceVerbose( DiagnosticsConstants.SendingWNSNotificationID, "Sending WNS notification.\r\n\r\n{0}", NotificationRequestStatus(channelUri.ToString(), payload, secondsTTL, cache, requestForStatus, tag, priority, tokenRetry)); var accessToken = string.Empty; try { accessToken = accessTokenProvider.GetAccessToken(true); } catch (WebException e) { if (e.Response != null) { var accessTokenError = GetAccessTokenError(e.Response); WnsDiagnostics.TraceError(DiagnosticsConstants.WnsAccessTokenSendResultErrorID, AccessTokenLogMessage(e.Response, accessTokenError)); return new WnsAccessTokenSendResult(channelUri, e, accessTokenError); } else { WnsDiagnostics.TraceError(DiagnosticsConstants.ServiceUnavailableErrorID, e.Message); return new NotificationSendResult(channelUri, e.Message, HttpStatusCode.ServiceUnavailable); } } request = CreateWebRequest(channelUri, accessToken, payload, type, secondsTTL, cache, requestForStatus, tag, priority, out payloadBytes); using (Stream requestStream = request.GetRequestStream()) { requestStream.Write(payloadBytes, 0, payloadBytes.Length); } var response = (HttpWebResponse)request.GetResponse(); result = new NotificationSendResult(channelUri, response); WnsDiagnostics.TraceInformation(DiagnosticsConstants.SentWNSNotificationID, NotificationLogMessage("Sent WNS notification", result.NotificationStatus.ToString(), result, payload, request, response)); } catch (WebException e) { if (e.Response != null) { string exceptionDetails = e.Response.Headers[WnsHeaders.WWWAuthenticate]; if (!string.IsNullOrWhiteSpace(exceptionDetails) && exceptionDetails.Contains("Token expired")) { accessTokenProvider.ResetCachedToken(); tokenRetry++; if (tokenRetry <= MaxSendRetries) { result = Send(channelUri, accessTokenProvider, payload, type, secondsTTL, cache, requestForStatus, tag, priority, tokenRetry); } else { result = new NotificationSendResult(channelUri, e); } } else { result = new NotificationSendResult(channelUri, e); } WnsDiagnostics.TraceError(DiagnosticsConstants.WNSNotificationFailureID, NotificationLogMessage("WNS notification failure", e.Message, result, payload, request, e.Response)); } else { WnsDiagnostics.TraceError(DiagnosticsConstants.ServiceUnavailableErrorID, e.Message); return new NotificationSendResult(channelUri, e.Message, HttpStatusCode.ServiceUnavailable); } } catch (Exception e) { result = new NotificationSendResult(channelUri, e); WnsDiagnostics.TraceException(DiagnosticsConstants.WNSNotificationFailureID, e, "WNS notification failure: {0}\r\n\r\n{1}", e.Message, result); } return result; }
public static void SendAsynchronously(Uri channelUri, IAccessTokenProvider accessTokenProvider, string payload, Action<NotificationSendResult> sent, Action<NotificationSendResult> error, NotificationType type, int? secondsTTL = null, bool? cache = null, bool? requestForStatus = null, string tag = null, NotificationPriority priority = NotificationPriority.Normal, int tokenRetry = 0) { byte[] payloadBytes; try { WnsDiagnostics.TraceVerbose( DiagnosticsConstants.SendingWNSNotificationID, "Sending WNS notification.\r\n\r\n{0}", NotificationRequestStatus(channelUri.ToString(), payload, secondsTTL, cache, requestForStatus, tag, priority, tokenRetry)); var accessToken = string.Empty; try { accessToken = accessTokenProvider.GetAccessToken(true); } catch (WebException e) { if (e.Response != null) { var accessTokenError = GetAccessTokenError(e.Response); WnsDiagnostics.TraceError(DiagnosticsConstants.WnsAccessTokenSendResultErrorID, AccessTokenLogMessage(e.Response, accessTokenError)); error(new WnsAccessTokenSendResult(channelUri, e, accessTokenError)); } else { WnsDiagnostics.TraceError(DiagnosticsConstants.ServiceUnavailableErrorID, e.Message); error(new NotificationSendResult(channelUri, e.Message, HttpStatusCode.ServiceUnavailable)); } } if (!string.IsNullOrEmpty(accessToken)) { var request = CreateWebRequest(channelUri, accessToken, payload, type, secondsTTL, cache, requestForStatus, tag, priority, out payloadBytes); // Get the request stream asynchronously. request.BeginGetRequestStream( requestAsyncResult => { try { using (Stream requestStream = request.EndGetRequestStream(requestAsyncResult)) { // Start writing the payload to the stream. requestStream.Write(payloadBytes, 0, payloadBytes.Length); } // Switch to receiving the response from WNS asynchronously. request.BeginGetResponse( responseAsyncResult => { try { using ( var response = (HttpWebResponse)request.EndGetResponse(responseAsyncResult)) { var result = new NotificationSendResult(channelUri, response); if (result.StatusCode == HttpStatusCode.OK) { WnsDiagnostics.TraceInformation(DiagnosticsConstants.SentWNSNotificationID, NotificationLogMessage("Sent WNS notification", result.NotificationStatus.ToString(), result, payload, request, response)); sent(result); } else { error(result); WnsDiagnostics.TraceError(DiagnosticsConstants.WNSNotificationFailureID, "WNS notification failure:\r\n\r\n{0}", result); } } } catch (WebException e) { if (e.Response != null) { var result = new NotificationSendResult(channelUri, e); string exceptionDetails = e.Response.Headers[WnsHeaders.WWWAuthenticate]; if (!string.IsNullOrWhiteSpace(exceptionDetails) && exceptionDetails.Contains("Token expired")) { accessTokenProvider.ResetCachedToken(); tokenRetry++; if (tokenRetry <= MaxSendRetries) { SendAsynchronously(channelUri, accessTokenProvider, payload, sent, error, type, secondsTTL, cache, requestForStatus, tag, priority, tokenRetry); } else { WnsDiagnostics.TraceError(DiagnosticsConstants.WNSNotificationFailureID, NotificationLogMessage("WNS notification failure", e.Message, result, payload, request, e.Response)); error(result); } } else { WnsDiagnostics.TraceError(DiagnosticsConstants.WNSNotificationFailureID, NotificationLogMessage("WNS notification failure", e.Message, result, payload, request, e.Response)); error(result); } } else { WnsDiagnostics.TraceError(DiagnosticsConstants.ServiceUnavailableErrorID, e.Message); error(new NotificationSendResult(channelUri, e.Message, HttpStatusCode.ServiceUnavailable)); } } catch (Exception ex3) { var result = new NotificationSendResult(channelUri, ex3); WnsDiagnostics.TraceException(DiagnosticsConstants.GeneralNotificationFailureID, ex3, "WNS notification failure: {0}\r\n\r\n{1}", ex3.Message, result); error(result); } }, null); } catch (Exception ex2) { var result = new NotificationSendResult(channelUri, ex2); WnsDiagnostics.TraceException(DiagnosticsConstants.GeneralNotificationFailureID, ex2, "WNS notification failure: {0}\r\n\r\n{1}", ex2.Message, result); error(result); } }, null); } } catch (Exception ex1) { var result = new NotificationSendResult(channelUri, ex1); WnsDiagnostics.TraceException(DiagnosticsConstants.GeneralNotificationFailureID, ex1, "WNS notification failure: {0}\r\n\r\n{1}", ex1.Message, result); error(result); } }