/// <summary> /// Builds the IEwsHttpWebRequest object for current service request with exception handling. /// </summary> /// <returns>An IEwsHttpWebRequest instance</returns> protected async Task <IEwsHttpWebRequest> BuildEwsHttpWebRequest() { IEwsHttpWebRequest request = null; try { request = this.Service.PrepareHttpWebRequest(this.GetXmlElementName()); this.Service.TraceHttpRequestHeaders(TraceFlags.EwsRequestHttpHeaders, request); bool needSignature = this.Service.Credentials != null && this.Service.Credentials.NeedSignature; bool needTrace = this.Service.IsTraceEnabledFor(TraceFlags.EwsRequest); // The request might need to add additional headers this.AddHeaders(request.Headers); // If tracing is enabled, we generate the request in-memory so that we // can pass it along to the ITraceListener. Then we copy the stream to // the request stream. if (needSignature || needTrace) { await this.TraceAndEmitRequest(request, needSignature, needTrace).ConfigureAwait(false); } else { await this.EmitRequest(request).ConfigureAwait(false); } return(request); } catch (WebException ex) { if (ex.Status == WebExceptionStatus.ProtocolError && ex.Response != null) { this.ProcessWebException(ex); } // Wrap exception if the above code block didn't throw throw new ServiceRequestException(string.Format(Strings.ServiceRequestFailed, ex.Message), ex); } catch (IOException e) { if (request != null) { request.Abort(); } // Wrap exception. throw new ServiceRequestException(string.Format(Strings.ServiceRequestFailed, e.Message), e); } }
/// <summary> /// Emits the request. /// </summary> /// <param name="request">The request.</param> private void EmitRequest(IEwsHttpWebRequest request) { try { using (Stream requestStream = this.GetWebRequestStream(request)) { using (EwsServiceXmlWriter writer = new EwsServiceXmlWriter(this.Service, requestStream)) { this.WriteToXml(writer); } } } catch (Exception e) { //FJC: We found that if the Xml generation generated an exception, then the request would be left in a // non-usable state since the requestStream in the request wasn't fully closed? // I'm not 100% sure I understand that part... but I found that calling .Abort on the request would force // the request/connection to be reinitialized the next time it was used after a Xml exception. request.Abort(); throw e; } }