/// <summary> /// Parses the soap:Fault content. /// </summary> /// <param name="reader">The reader.</param> /// <param name="soapNamespace">The SOAP namespace to use.</param> /// <returns>SOAP fault details.</returns> internal static SoapFaultDetails Parse(EwsXmlReader reader, XmlNamespace soapNamespace) { SoapFaultDetails soapFaultDetails = new SoapFaultDetails(); do { reader.Read(); if (reader.NodeType == XmlNodeType.Element) { switch (reader.LocalName) { case XmlElementNames.SOAPFaultCodeElementName: soapFaultDetails.FaultCode = reader.ReadElementValue(); break; case XmlElementNames.SOAPFaultStringElementName: soapFaultDetails.FaultString = reader.ReadElementValue(); break; case XmlElementNames.SOAPFaultActorElementName: soapFaultDetails.FaultActor = reader.ReadElementValue(); break; case XmlElementNames.SOAPDetailElementName: soapFaultDetails.ParseDetailNode(reader); break; default: break; } } }while (!reader.IsEndElement(soapNamespace, XmlElementNames.SOAPFaultElementName)); return(soapFaultDetails); }
/// <summary> /// Initializes a new instance of the <see cref="ServiceResponse"/> class. /// </summary> /// <param name="soapFaultDetails">The SOAP fault details.</param> internal ServiceResponse(SoapFaultDetails soapFaultDetails) { this.result = ServiceResult.Error; this.errorCode = soapFaultDetails.ResponseCode; this.errorMessage = soapFaultDetails.FaultString; this.errorDetails = soapFaultDetails.ErrorDetails; }
/// <summary> /// Initializes a new instance of the <see cref="ServiceResponse"/> class. /// </summary> /// <param name="soapFaultDetails">The SOAP fault details.</param> internal ServiceResponse(SoapFaultDetails soapFaultDetails) { this.result = ServiceResult.Error; this.errorCode = soapFaultDetails.ResponseCode; this.errorMessage = soapFaultDetails.FaultString; this.errorDetails = soapFaultDetails.ErrorDetails; }
/// <summary> /// Reads the SOAP fault. /// </summary> /// <param name="jsonSoapFault">The json SOAP fault.</param> /// <returns></returns> private SoapFaultDetails ReadSoapFault(JsonObject jsonSoapFault) { SoapFaultDetails soapFaultDetails = null; if (jsonSoapFault.ContainsKey("Header")) { this.ReadSoapHeader(jsonSoapFault.ReadAsJsonObject("Header")); } if (jsonSoapFault.ContainsKey("Body")) { soapFaultDetails = SoapFaultDetails.Parse(jsonSoapFault.ReadAsJsonObject("Body")); } return(soapFaultDetails); }
/// <summary> /// Parses the specified json object. /// </summary> /// <param name="jsonObject">The json object.</param> /// <returns></returns> internal static SoapFaultDetails Parse(JsonObject jsonObject) { SoapFaultDetails soapFaultDetails = new SoapFaultDetails(); foreach (string key in jsonObject.Keys) { switch (key) { // TODO: Fix up? case "FaultMessage": soapFaultDetails.FaultString = jsonObject.ReadAsString(key); break; default: break; } } return(soapFaultDetails); }
/// <summary> /// Processes the web exception. /// </summary> /// <param name="webException">The web exception.</param> private void ProcessWebException(WebException webException) { if (webException.Response != null) { IEwsHttpWebResponse httpWebResponse = this.Service.HttpWebRequestFactory.CreateExceptionResponse(webException); SoapFaultDetails soapFaultDetails = null; if (httpWebResponse.StatusCode == HttpStatusCode.InternalServerError) { this.Service.ProcessHttpResponseHeaders(TraceFlags.EwsResponseHttpHeaders, httpWebResponse); // If tracing is enabled, we read the entire response into a MemoryStream so that we // can pass it along to the ITraceListener. Then we parse the response from the // MemoryStream. if (this.Service.IsTraceEnabledFor(TraceFlags.EwsResponse)) { using (MemoryStream memoryStream = new MemoryStream()) { using (Stream serviceResponseStream = ServiceRequestBase.GetResponseStream(httpWebResponse)) { // Copy response to in-memory stream and reset position to start. EwsUtilities.CopyStream(serviceResponseStream, memoryStream); memoryStream.Position = 0; } this.TraceResponseXml(httpWebResponse, memoryStream); EwsServiceXmlReader reader = new EwsServiceXmlReader(memoryStream, this.Service); soapFaultDetails = this.ReadSoapFault(reader); } } else { using (Stream stream = ServiceRequestBase.GetResponseStream(httpWebResponse)) { EwsServiceXmlReader reader = new EwsServiceXmlReader(stream, this.Service); soapFaultDetails = this.ReadSoapFault(reader); } } if (soapFaultDetails != null) { switch (soapFaultDetails.ResponseCode) { case ServiceError.ErrorInvalidServerVersion: throw new ServiceVersionException(Strings.ServerVersionNotSupported); case ServiceError.ErrorSchemaValidation: // If we're talking to an E12 server (8.00.xxxx.xxx), a schema validation error is the same as a version mismatch error. // (Which only will happen if we send a request that's not valid for E12). if ((this.Service.ServerInfo != null) && (this.Service.ServerInfo.MajorVersion == 8) && (this.Service.ServerInfo.MinorVersion == 0)) { throw new ServiceVersionException(Strings.ServerVersionNotSupported); } break; case ServiceError.ErrorIncorrectSchemaVersion: // This shouldn't happen. It indicates that a request wasn't valid for the version that was specified. EwsUtilities.Assert( false, "ServiceRequestBase.ProcessWebException", "Exchange server supports requested version but request was invalid for that version"); break; case ServiceError.ErrorServerBusy: throw new ServerBusyException(new ServiceResponse(soapFaultDetails)); default: // Other error codes will be reported as remote error break; } // General fall-through case: throw a ServiceResponseException throw new ServiceResponseException(new ServiceResponse(soapFaultDetails)); } } else { this.Service.ProcessHttpErrorResponse(httpWebResponse, webException); } } }
/// <summary> /// Reads the SOAP fault. /// </summary> /// <param name="reader">The reader.</param> /// <returns>SOAP fault details.</returns> protected SoapFaultDetails ReadSoapFault(EwsServiceXmlReader reader) { SoapFaultDetails soapFaultDetails = null; try { this.ReadXmlDeclaration(reader); reader.Read(); if (!reader.IsStartElement() || (reader.LocalName != XmlElementNames.SOAPEnvelopeElementName)) { return(soapFaultDetails); } // EWS can sometimes return SOAP faults using the SOAP 1.2 namespace. Get the // namespace URI from the envelope element and use it for the rest of the parsing. // If it's not 1.1 or 1.2, we can't continue. XmlNamespace soapNamespace = EwsUtilities.GetNamespaceFromUri(reader.NamespaceUri); if (soapNamespace == XmlNamespace.NotSpecified) { return(soapFaultDetails); } reader.Read(); // EWS doesn't always return a SOAP header. If this response contains a header element, // read the server version information contained in the header. if (reader.IsStartElement(soapNamespace, XmlElementNames.SOAPHeaderElementName)) { do { reader.Read(); if (reader.IsStartElement(XmlNamespace.Types, XmlElementNames.ServerVersionInfo)) { this.Service.ServerInfo = ExchangeServerInfo.Parse(reader); } }while (!reader.IsEndElement(soapNamespace, XmlElementNames.SOAPHeaderElementName)); // Queue up the next read reader.Read(); } // Parse the fault element contained within the SOAP body. if (reader.IsStartElement(soapNamespace, XmlElementNames.SOAPBodyElementName)) { do { reader.Read(); // Parse Fault element if (reader.IsStartElement(soapNamespace, XmlElementNames.SOAPFaultElementName)) { soapFaultDetails = SoapFaultDetails.Parse(reader, soapNamespace); } }while (!reader.IsEndElement(soapNamespace, XmlElementNames.SOAPBodyElementName)); } reader.ReadEndElement(soapNamespace, XmlElementNames.SOAPEnvelopeElementName); } catch (XmlException) { // If response doesn't contain a valid SOAP fault, just ignore exception and // return null for SOAP fault details. } return(soapFaultDetails); }
/// <summary> /// Parses the soap:Fault content. /// </summary> /// <param name="reader">The reader.</param> /// <param name="soapNamespace">The SOAP namespace to use.</param> /// <returns>SOAP fault details.</returns> internal static SoapFaultDetails Parse(EwsXmlReader reader, XmlNamespace soapNamespace) { SoapFaultDetails soapFaultDetails = new SoapFaultDetails(); do { reader.Read(); if (reader.NodeType == XmlNodeType.Element) { switch (reader.LocalName) { case XmlElementNames.SOAPFaultCodeElementName: soapFaultDetails.FaultCode = reader.ReadElementValue(); break; case XmlElementNames.SOAPFaultStringElementName: soapFaultDetails.FaultString = reader.ReadElementValue(); break; case XmlElementNames.SOAPFaultActorElementName: soapFaultDetails.FaultActor = reader.ReadElementValue(); break; case XmlElementNames.SOAPDetailElementName: soapFaultDetails.ParseDetailNode(reader); break; default: break; } } } while (!reader.IsEndElement(soapNamespace, XmlElementNames.SOAPFaultElementName)); return soapFaultDetails; }