void SendRequest(Stream s, SoapClientMessage message, SoapExtension[] extensions) { using (s) { if (extensions != null) { s = SoapExtension.ExecuteChainStream(extensions, s); message.SetStage(SoapMessageStage.BeforeSerialize); SoapExtension.ExecuteProcessMessage(extensions, message, s, true); } XmlTextWriter xtw = WebServiceHelper.CreateXmlWriter(s); WebServiceHelper.WriteSoapMessage(xtw, message.MethodStubInfo, SoapHeaderDirection.In, message.Parameters, message.Headers, message.IsSoap12); if (extensions != null) { message.SetStage(SoapMessageStage.AfterSerialize); SoapExtension.ExecuteProcessMessage(extensions, message, s, true); } xtw.Flush(); xtw.Close(); } }
// // TODO: // Handle other web responses (multi-output?) // object [] ReceiveResponse(WebResponse response, SoapClientMessage message, SoapExtension[] extensions) { SoapMethodStubInfo msi = message.MethodStubInfo; HttpWebResponse http_response = response as HttpWebResponse; if (http_response != null) { HttpStatusCode code = http_response.StatusCode; if (!(code == HttpStatusCode.Accepted || code == HttpStatusCode.OK || code == HttpStatusCode.InternalServerError)) { string msg = "The request failed with HTTP status {0}: {1}"; msg = String.Format(msg, (int)code, code); throw new WebException(msg, null, WebExceptionStatus.ProtocolError, http_response); } if (message.OneWay && response.ContentLength <= 0 && (code == HttpStatusCode.Accepted || code == HttpStatusCode.OK)) { return(new object[0]); } } // // Remove optional encoding // string ctype; Encoding encoding = WebServiceHelper.GetContentEncoding(response.ContentType, out ctype); ctype = ctype.ToLower(CultureInfo.InvariantCulture); if ((!message.IsSoap12 || ctype != "application/soap+xml") && ctype != "text/xml") { WebServiceHelper.InvalidOperation( String.Format("Not supported Content-Type in the response: '{0}'", response.ContentType), response, encoding); } message.ContentType = ctype; message.ContentEncoding = encoding.WebName; Stream stream = response.GetResponseStream(); if (extensions != null) { stream = SoapExtension.ExecuteChainStream(extensions, stream); message.SetStage(SoapMessageStage.BeforeDeserialize); SoapExtension.ExecuteProcessMessage(extensions, message, stream, false); } // Deserialize the response SoapHeaderCollection headers; object content; using (StreamReader reader = new StreamReader(stream, encoding, false)) { XmlTextReader xml_reader = new XmlTextReader(reader); WebServiceHelper.ReadSoapMessage(xml_reader, msi, SoapHeaderDirection.Out, message.IsSoap12, out content, out headers); } if (content is Soap12Fault) { SoapException ex = WebServiceHelper.Soap12FaultToSoapException((Soap12Fault)content); message.SetException(ex); } else if (content is Fault) { Fault fault = (Fault)content; SoapException ex = new SoapException(fault.faultstring, fault.faultcode, fault.faultactor, fault.detail); message.SetException(ex); } else { message.OutParameters = (object[])content; } message.SetHeaders(headers); message.UpdateHeaderValues(this, message.MethodStubInfo.Headers); if (extensions != null) { message.SetStage(SoapMessageStage.AfterDeserialize); SoapExtension.ExecuteProcessMessage(extensions, message, stream, false); } if (message.Exception == null) { return(message.OutParameters); } else { throw message.Exception; } }
void SerializeResponse(HttpResponse response, SoapServerMessage message) { SoapMethodStubInfo methodInfo = message.MethodStubInfo; if ((message.ContentEncoding != null) && (message.ContentEncoding.Length > 0)) { response.AppendHeader("Content-Encoding", message.ContentEncoding); } response.ContentType = message.IsSoap12 ? "application/soap+xml; charset=utf-8" : "text/xml; charset=utf-8"; if (message.Exception != null) { response.StatusCode = 500; } Stream responseStream = response.OutputStream; Stream outStream = responseStream; bool bufferResponse = (methodInfo == null || methodInfo.MethodAttribute.BufferResponse); response.BufferOutput = bufferResponse; try { // While serializing, process extensions in reverse order if (bufferResponse) { outStream = SoapExtension.ExecuteChainStream(_extensionChainHighPrio, outStream); outStream = SoapExtension.ExecuteChainStream(_extensionChainMedPrio, outStream); outStream = SoapExtension.ExecuteChainStream(_extensionChainLowPrio, outStream); message.SetStage(SoapMessageStage.BeforeSerialize); SoapExtension.ExecuteProcessMessage(_extensionChainLowPrio, message, outStream, true); SoapExtension.ExecuteProcessMessage(_extensionChainMedPrio, message, outStream, true); SoapExtension.ExecuteProcessMessage(_extensionChainHighPrio, message, outStream, true); } XmlTextWriter xtw = WebServiceHelper.CreateXmlWriter(outStream); if (message.Exception == null) { WebServiceHelper.WriteSoapMessage(xtw, methodInfo, SoapHeaderDirection.Out, message.OutParameters, message.Headers, message.IsSoap12); } else if (methodInfo != null) { if (message.IsSoap12) { WebServiceHelper.WriteSoapMessage(xtw, methodInfo, SoapHeaderDirection.Fault, new Soap12Fault(message.Exception), message.Headers, message.IsSoap12); } else { WebServiceHelper.WriteSoapMessage(xtw, methodInfo, SoapHeaderDirection.Fault, new Fault(message.Exception), message.Headers, message.IsSoap12); } } else { if (message.IsSoap12) { WebServiceHelper.WriteSoapMessage(xtw, SoapBindingUse.Literal, Soap12Fault.Serializer, null, new Soap12Fault(message.Exception), null, message.IsSoap12); } else { WebServiceHelper.WriteSoapMessage(xtw, SoapBindingUse.Literal, Fault.Serializer, null, new Fault(message.Exception), null, message.IsSoap12); } } if (bufferResponse) { message.SetStage(SoapMessageStage.AfterSerialize); SoapExtension.ExecuteProcessMessage(_extensionChainLowPrio, message, outStream, true); SoapExtension.ExecuteProcessMessage(_extensionChainMedPrio, message, outStream, true); SoapExtension.ExecuteProcessMessage(_extensionChainHighPrio, message, outStream, true); } xtw.Flush(); } catch (Exception ex) { // If the response is buffered, we can discard the response and // serialize a new Fault message as response. if (bufferResponse) { throw ex; } // If it is not buffered, we can't rollback what has been sent, // so we can only close the connection and return. responseStream.Close(); return; } }
SoapServerMessage DeserializeRequest(HttpContext context) { HttpRequest request = context.Request; Stream stream = request.InputStream; //using (stream) //{ string soapAction = null; string ctype; Encoding encoding = WebServiceHelper.GetContentEncoding(request.ContentType, out ctype); if (ctype != "text/xml" && ctype != "application/soap+xml") { throw new WebException("Content is not XML: " + ctype); } object server = CreateServerInstance(); SoapServerMessage message = new SoapServerMessage(request, server, stream); message.SetStage(SoapMessageStage.BeforeDeserialize); message.ContentType = ctype; object soapVer = context.Items ["WebServiceSoapVersion"]; if (soapVer != null) { message.SetSoapVersion((SoapProtocolVersion)soapVer); } // If the routing style is SoapAction, then we can get the method information now // and set it to the SoapMessage if (_typeStubInfo.RoutingStyle == SoapServiceRoutingStyle.SoapAction) { string headerName = message.IsSoap12 ? "action" : "SOAPAction"; soapAction = message.IsSoap12 ? WebServiceHelper.GetContextAction(request.ContentType) : request.Headers [headerName]; if (soapAction == null) { if (!message.IsSoap12) { throw new SoapException("Missing SOAPAction header", WebServiceHelper.ClientFaultCode(message.IsSoap12)); } } else { methodInfo = _typeStubInfo.GetMethodForSoapAction(soapAction); if (methodInfo == null) { throw new SoapException("Server did not recognize the value of HTTP header " + headerName + ": " + soapAction, WebServiceHelper.ClientFaultCode(message.IsSoap12)); } message.MethodStubInfo = methodInfo; } } // Execute the high priority global extensions. Do not try to execute the medium and // low priority extensions because if the routing style is RequestElement we still // don't have method information _extensionChainHighPrio = SoapExtension.CreateExtensionChain(_typeStubInfo.SoapExtensions[0]); stream = SoapExtension.ExecuteChainStream(_extensionChainHighPrio, stream); SoapExtension.ExecuteProcessMessage(_extensionChainHighPrio, message, stream, false); // If the routing style is RequestElement, try to get the method name from the // stream processed by the high priority extensions if (_typeStubInfo.RoutingStyle == SoapServiceRoutingStyle.RequestElement || (message.IsSoap12 && soapAction == null)) { MemoryStream mstream; byte[] buffer = null; if (stream.CanSeek) { buffer = new byte [stream.Length]; for (int n = 0; n < stream.Length;) { n += stream.Read(buffer, n, (int)stream.Length - n); } mstream = new MemoryStream(buffer); } else { buffer = new byte [500]; mstream = new MemoryStream(); int len; while ((len = stream.Read(buffer, 0, 500)) > 0) { mstream.Write(buffer, 0, len); } mstream.Position = 0; buffer = mstream.ToArray(); } soapAction = ReadActionFromRequestElement(new MemoryStream(buffer), encoding, message.IsSoap12); stream = mstream; methodInfo = (SoapMethodStubInfo)_typeStubInfo.GetMethod(soapAction); message.MethodStubInfo = methodInfo; } // Whatever routing style we used, we should now have the method information. // We can now notify the remaining extensions if (methodInfo == null) { throw new SoapException("Method '" + soapAction + "' not defined in the web service '" + _typeStubInfo.LogicalType.WebServiceName + "'", WebServiceHelper.ClientFaultCode(message.IsSoap12)); } _extensionChainMedPrio = SoapExtension.CreateExtensionChain(methodInfo.SoapExtensions); _extensionChainLowPrio = SoapExtension.CreateExtensionChain(_typeStubInfo.SoapExtensions[1]); stream = SoapExtension.ExecuteChainStream(_extensionChainMedPrio, stream); stream = SoapExtension.ExecuteChainStream(_extensionChainLowPrio, stream); SoapExtension.ExecuteProcessMessage(_extensionChainMedPrio, message, stream, false); SoapExtension.ExecuteProcessMessage(_extensionChainLowPrio, message, stream, false); // Deserialize the request StreamReader reader = new StreamReader(stream, encoding, false); XmlTextReader xmlReader = new XmlTextReader(reader); try { object content; SoapHeaderCollection headers; WebServiceHelper.ReadSoapMessage(xmlReader, methodInfo, SoapHeaderDirection.In, message.IsSoap12, out content, out headers); message.InParameters = (object [])content; message.SetHeaders(headers); } catch (Exception ex) { throw new SoapException("Could not deserialize Soap message", WebServiceHelper.ClientFaultCode(message.IsSoap12), ex); } // Notify the extensions after deserialization message.SetStage(SoapMessageStage.AfterDeserialize); SoapExtension.ExecuteProcessMessage(_extensionChainHighPrio, message, stream, false); SoapExtension.ExecuteProcessMessage(_extensionChainMedPrio, message, stream, false); SoapExtension.ExecuteProcessMessage(_extensionChainLowPrio, message, stream, false); return(message); //} }