예제 #1
0
        object[] ReadResponse(SoapClientMessage message, WebResponse response, Stream responseStream, bool asyncCall)
        {
            SoapClientMethod method = message.Method;

            // CONSIDER,yannc: use the SoapExtensionStream here as well so we throw exceptions
            //      : if the extension touches stream properties/methods in before deserialize.
            // note that if there is an error status code then the response might be content-type=text/plain.
            HttpWebResponse httpResponse = response as HttpWebResponse;
            int             statusCode   = httpResponse != null ? (int)httpResponse.StatusCode : -1;

            if (statusCode >= 300 && statusCode != 500 && statusCode != 400)
            {
                throw new WebException(RequestResponseUtils.CreateResponseExceptionString(httpResponse, responseStream), null,
                                       WebExceptionStatus.ProtocolError, httpResponse);
            }

            message.Headers.Clear();
            message.SetStream(responseStream);
            message.InitExtensionStreamChain(message.initializedExtensions);

            message.SetStage(SoapMessageStage.BeforeDeserialize);
            message.ContentType     = response.ContentType;
            message.ContentEncoding = response.Headers[ContentType.ContentEncoding];
            message.RunExtensions(message.initializedExtensions);

            if (method.oneWay && (httpResponse == null || (int)httpResponse.StatusCode != 500))
            {
                return(new object[0]);
            }

            // this statusCode check is just so we don't repeat the contentType check we did above
            if (!ContentType.IsSoap(message.ContentType))
            {
                // special-case 400 since we exempted it above on the off-chance it might be a soap 1.2 sender fault.
                // based on the content-type, it looks like it's probably just a regular old 400
                if (statusCode == 400)
                {
                    throw new WebException(RequestResponseUtils.CreateResponseExceptionString(httpResponse, responseStream), null,
                                           WebExceptionStatus.ProtocolError, httpResponse);
                }
                else
                {
                    throw new InvalidOperationException(Res.GetString(Res.WebResponseContent, message.ContentType, HttpContentType) +
                                                        "\r\n" +
                                                        RequestResponseUtils.CreateResponseExceptionString(response, responseStream));
                }
            }

            Encoding enc = RequestResponseUtils.GetEncoding(message.ContentType);

            // perf fix: changed buffer size passed to StreamReader
            int bufferSize;

            if (asyncCall || httpResponse == null)
            {
                bufferSize = 512;
            }
            else
            {
                int contentLength = (int)httpResponse.ContentLength;
                if (contentLength == -1)
                {
                    bufferSize = 8000;
                }
                else if (contentLength <= 16000)
                {
                    bufferSize = contentLength;
                }
                else
                {
                    bufferSize = 16000;
                }
            }
            XmlTextReader reader;

            if (enc != null)
            {
                reader = new XmlTextReader(new StreamReader(message.Stream, enc, true, bufferSize));
            }
            else
            {
                // CONSIDER: do i need to pass a buffer size somehow?
                reader = new XmlTextReader(message.Stream);
            }

            reader.Normalization = true;
            reader.XmlResolver   = null;
            reader.MoveToContent();
            // should be able to handle no ns, soap 1.1 ns, or soap 1.2 ns
            string encodingNs = EncodingNs;
            string envelopeNs = reader.NamespaceURI;

            if (envelopeNs == null || envelopeNs.Length == 0)
            {
                // ok to omit namespace -- assume correct version
                reader.ReadStartElement(Soap.Envelope);
            }
            else if (reader.NamespaceURI == Soap.Namespace)
            {
                reader.ReadStartElement(Soap.Envelope, Soap.Namespace);
            }
            else if (reader.NamespaceURI == Soap12.Namespace)
            {
                reader.ReadStartElement(Soap.Envelope, Soap12.Namespace);
            }
            else
            {
                throw new SoapException(Res.GetString(Res.WebInvalidEnvelopeNamespace, envelopeNs, EnvelopeNs), SoapException.VersionMismatchFaultCode);
            }

            reader.MoveToContent();
            SoapHeaderHandling headerHandler = new SoapHeaderHandling();

            headerHandler.ReadHeaders(reader, method.outHeaderSerializer, message.Headers, method.outHeaderMappings, SoapHeaderDirection.Out | SoapHeaderDirection.Fault, envelopeNs, method.use == SoapBindingUse.Encoded ? encodingNs : null);
            reader.MoveToContent();
            reader.ReadStartElement(Soap.Body, envelopeNs);
            reader.MoveToContent();
            if (reader.IsStartElement(Soap.Fault, envelopeNs))
            {
                message.SetException(ReadSoapException(reader));
            }
            else
            {
                if (method.oneWay)
                {
                    reader.Skip();
                    message.SetParameterValues(new object[0]);
                }
                else
                {
                    // SOAP12: not using encodingStyle
                    //message.SetParameterValues((object[])method.returnSerializer.Deserialize(reader, method.use == SoapBindingUse.Encoded ? encodingNs : null));
                    message.SetParameterValues((object[])method.returnSerializer.Deserialize(reader));
                }
            }

            while (reader.NodeType == XmlNodeType.Whitespace)
            {
                reader.Skip();
            }
            if (reader.NodeType == XmlNodeType.None)
            {
                reader.Skip();
            }
            else
            {
                reader.ReadEndElement();
            }
            while (reader.NodeType == XmlNodeType.Whitespace)
            {
                reader.Skip();
            }
            if (reader.NodeType == XmlNodeType.None)
            {
                reader.Skip();
            }
            else
            {
                reader.ReadEndElement();
            }

            message.SetStage(SoapMessageStage.AfterDeserialize);
            message.RunExtensions(message.initializedExtensions);
            SoapHeaderHandling.SetHeaderMembers(message.Headers, this, method.outHeaderMappings, SoapHeaderDirection.Out | SoapHeaderDirection.Fault, true);

            if (message.Exception != null)
            {
                throw message.Exception;
            }
            return(message.GetParameterValues());
        }
        object[] ReadResponse(SoapClientMessage message, WebResponse response, Stream responseStream, bool asyncCall) {
            SoapClientMethod method = message.Method;

            // 


            HttpWebResponse httpResponse = response as HttpWebResponse;
            int statusCode = httpResponse != null ? (int)httpResponse.StatusCode : -1;
            if (statusCode >= 300 && statusCode != 500 && statusCode != 400)
                throw new WebException(RequestResponseUtils.CreateResponseExceptionString(httpResponse, responseStream), null, 
                    WebExceptionStatus.ProtocolError, httpResponse);

            message.Headers.Clear();
            message.SetStream(responseStream);
            message.InitExtensionStreamChain(message.initializedExtensions);

            message.SetStage(SoapMessageStage.BeforeDeserialize);
            message.ContentType = response.ContentType;
            message.ContentEncoding = response.Headers[ContentType.ContentEncoding];
            message.RunExtensions(message.initializedExtensions, false);

            if (method.oneWay && (httpResponse == null || (int)httpResponse.StatusCode != 500)) {
                return new object[0];
            }

            // this statusCode check is just so we don't repeat the contentType check we did above
            bool isSoap = ContentType.IsSoap(message.ContentType);
            if (!isSoap || (isSoap && (httpResponse != null) && (httpResponse.ContentLength == 0))) {
                // special-case 400 since we exempted it above on the off-chance it might be a soap 1.2 sender fault. 
                // based on the content-type, it looks like it's probably just a regular old 400
                if (statusCode == 400) 
                    throw new WebException(RequestResponseUtils.CreateResponseExceptionString(httpResponse, responseStream), null, 
                        WebExceptionStatus.ProtocolError, httpResponse);
                else
                    throw new InvalidOperationException(Res.GetString(Res.WebResponseContent, message.ContentType, HttpContentType) +
                                    Environment.NewLine +
                                    RequestResponseUtils.CreateResponseExceptionString(response, responseStream));
            }
            if (message.Exception != null) {
                throw message.Exception;
            }

            // perf fix: changed buffer size passed to StreamReader
            int bufferSize;
            if (asyncCall || httpResponse == null)
                bufferSize = 512;
            else {
                bufferSize = RequestResponseUtils.GetBufferSize((int)httpResponse.ContentLength);
            }
            XmlReader reader = GetReaderForMessage(message, bufferSize);
            if (reader == null)
                throw new InvalidOperationException(Res.GetString(Res.WebNullReaderForMessage));

            reader.MoveToContent();
            int depth = reader.Depth;

            // should be able to handle no ns, soap 1.1 ns, or soap 1.2 ns
            string encodingNs = EncodingNs;
            string envelopeNs = reader.NamespaceURI;

            if (envelopeNs == null || envelopeNs.Length == 0)
                // ok to omit namespace -- assume correct version
                reader.ReadStartElement(Soap.Element.Envelope);
            else if (reader.NamespaceURI == Soap.Namespace)
                reader.ReadStartElement(Soap.Element.Envelope, Soap.Namespace);
            else if (reader.NamespaceURI == Soap12.Namespace)
                reader.ReadStartElement(Soap.Element.Envelope, Soap12.Namespace);
            else
                throw new SoapException(Res.GetString(Res.WebInvalidEnvelopeNamespace, envelopeNs, EnvelopeNs), SoapException.VersionMismatchFaultCode);

            reader.MoveToContent();
            SoapHeaderHandling headerHandler = new SoapHeaderHandling();
            headerHandler.ReadHeaders(reader, method.outHeaderSerializer, message.Headers, method.outHeaderMappings, SoapHeaderDirection.Out | SoapHeaderDirection.Fault, envelopeNs, method.use == SoapBindingUse.Encoded ? encodingNs : null, false);
            reader.MoveToContent();
            reader.ReadStartElement(Soap.Element.Body, envelopeNs);
            reader.MoveToContent();
            if (reader.IsStartElement(Soap.Element.Fault, envelopeNs)) {
                message.Exception = ReadSoapException(reader);
            } 
            else {
                if (method.oneWay) {
                    reader.Skip();
                    message.SetParameterValues(new object[0]);
                }
                else {
                    TraceMethod caller = Tracing.On ? new TraceMethod(this, "ReadResponse") : null;
                    bool isEncodedSoap = method.use == SoapBindingUse.Encoded;
                    if (Tracing.On) Tracing.Enter(Tracing.TraceId(Res.TraceReadResponse), caller, new TraceMethod(method.returnSerializer, "Deserialize", reader, isEncodedSoap ? encodingNs : null));

                    bool useDeserializationEvents = !isEncodedSoap && (WebServicesSection.Current.SoapEnvelopeProcessing.IsStrict || Tracing.On);
                    if (useDeserializationEvents) {
                        XmlDeserializationEvents events = Tracing.On ? Tracing.GetDeserializationEvents() : RuntimeUtils.GetDeserializationEvents();
                        message.SetParameterValues((object[])method.returnSerializer.Deserialize(reader, null, events));
                    }
                    else {
                        message.SetParameterValues((object[])method.returnSerializer.Deserialize(reader, isEncodedSoap ? encodingNs : null));
                    }

                    if (Tracing.On) Tracing.Exit(Tracing.TraceId(Res.TraceReadResponse), caller);
                }
            }

            // Consume soap:Body and soap:Envelope closing tags
            while (depth < reader.Depth && reader.Read()) {
                // Nothing, just read on
            }
            // consume end tag
            if (reader.NodeType == XmlNodeType.EndElement) {
                reader.Read();
            }

            message.SetStage(SoapMessageStage.AfterDeserialize);
            message.RunExtensions(message.initializedExtensions, false);
            SoapHeaderHandling.SetHeaderMembers(message.Headers, this, method.outHeaderMappings, SoapHeaderDirection.Out | SoapHeaderDirection.Fault, true);

            if (message.Exception != null) throw message.Exception;
            return message.GetParameterValues();        
        }
        object[] ReadResponse(SoapClientMessage message, WebResponse response, Stream responseStream, bool asyncCall)
        {
            SoapClientMethod method = message.Method;

            //


            HttpWebResponse httpResponse = response as HttpWebResponse;
            int             statusCode   = httpResponse != null ? (int)httpResponse.StatusCode : -1;

            if (statusCode >= 300 && statusCode != 500 && statusCode != 400)
            {
                throw new WebException(RequestResponseUtils.CreateResponseExceptionString(httpResponse, responseStream), null,
                                       WebExceptionStatus.ProtocolError, httpResponse);
            }

            message.Headers.Clear();
            message.SetStream(responseStream);
            message.InitExtensionStreamChain(message.initializedExtensions);

            message.SetStage(SoapMessageStage.BeforeDeserialize);
            message.ContentType     = response.ContentType;
            message.ContentEncoding = response.Headers[ContentType.ContentEncoding];
            message.RunExtensions(message.initializedExtensions, false);

            if (method.oneWay && (httpResponse == null || (int)httpResponse.StatusCode != 500))
            {
                return(new object[0]);
            }

            // this statusCode check is just so we don't repeat the contentType check we did above
            bool isSoap = ContentType.IsSoap(message.ContentType);

            if (!isSoap || (isSoap && (httpResponse != null) && (httpResponse.ContentLength == 0)))
            {
                // special-case 400 since we exempted it above on the off-chance it might be a soap 1.2 sender fault.
                // based on the content-type, it looks like it's probably just a regular old 400
                if (statusCode == 400)
                {
                    throw new WebException(RequestResponseUtils.CreateResponseExceptionString(httpResponse, responseStream), null,
                                           WebExceptionStatus.ProtocolError, httpResponse);
                }
                else
                {
                    throw new InvalidOperationException(Res.GetString(Res.WebResponseContent, message.ContentType, HttpContentType) +
                                                        Environment.NewLine +
                                                        RequestResponseUtils.CreateResponseExceptionString(response, responseStream));
                }
            }
            if (message.Exception != null)
            {
                throw message.Exception;
            }

            // perf fix: changed buffer size passed to StreamReader
            int bufferSize;

            if (asyncCall || httpResponse == null)
            {
                bufferSize = 512;
            }
            else
            {
                bufferSize = RequestResponseUtils.GetBufferSize((int)httpResponse.ContentLength);
            }
            XmlReader reader = GetReaderForMessage(message, bufferSize);

            if (reader == null)
            {
                throw new InvalidOperationException(Res.GetString(Res.WebNullReaderForMessage));
            }

            reader.MoveToContent();
            int depth = reader.Depth;

            // should be able to handle no ns, soap 1.1 ns, or soap 1.2 ns
            string encodingNs = EncodingNs;
            string envelopeNs = reader.NamespaceURI;

            if (envelopeNs == null || envelopeNs.Length == 0)
            {
                // ok to omit namespace -- assume correct version
                reader.ReadStartElement(Soap.Element.Envelope);
            }
            else if (reader.NamespaceURI == Soap.Namespace)
            {
                reader.ReadStartElement(Soap.Element.Envelope, Soap.Namespace);
            }
            else if (reader.NamespaceURI == Soap12.Namespace)
            {
                reader.ReadStartElement(Soap.Element.Envelope, Soap12.Namespace);
            }
            else
            {
                throw new SoapException(Res.GetString(Res.WebInvalidEnvelopeNamespace, envelopeNs, EnvelopeNs), SoapException.VersionMismatchFaultCode);
            }

            reader.MoveToContent();
            SoapHeaderHandling headerHandler = new SoapHeaderHandling();

            headerHandler.ReadHeaders(reader, method.outHeaderSerializer, message.Headers, method.outHeaderMappings, SoapHeaderDirection.Out | SoapHeaderDirection.Fault, envelopeNs, method.use == SoapBindingUse.Encoded ? encodingNs : null, false);
            reader.MoveToContent();
            reader.ReadStartElement(Soap.Element.Body, envelopeNs);
            reader.MoveToContent();
            if (reader.IsStartElement(Soap.Element.Fault, envelopeNs))
            {
                message.Exception = ReadSoapException(reader);
            }
            else
            {
                if (method.oneWay)
                {
                    reader.Skip();
                    message.SetParameterValues(new object[0]);
                }
                else
                {
                    TraceMethod caller        = Tracing.On ? new TraceMethod(this, "ReadResponse") : null;
                    bool        isEncodedSoap = method.use == SoapBindingUse.Encoded;
                    if (Tracing.On)
                    {
                        Tracing.Enter(Tracing.TraceId(Res.TraceReadResponse), caller, new TraceMethod(method.returnSerializer, "Deserialize", reader, isEncodedSoap ? encodingNs : null));
                    }

                    bool useDeserializationEvents = !isEncodedSoap && (WebServicesSection.Current.SoapEnvelopeProcessing.IsStrict || Tracing.On);
                    if (useDeserializationEvents)
                    {
                        XmlDeserializationEvents events = Tracing.On ? Tracing.GetDeserializationEvents() : RuntimeUtils.GetDeserializationEvents();
                        message.SetParameterValues((object[])method.returnSerializer.Deserialize(reader, null, events));
                    }
                    else
                    {
                        message.SetParameterValues((object[])method.returnSerializer.Deserialize(reader, isEncodedSoap ? encodingNs : null));
                    }

                    if (Tracing.On)
                    {
                        Tracing.Exit(Tracing.TraceId(Res.TraceReadResponse), caller);
                    }
                }
            }

            // Consume soap:Body and soap:Envelope closing tags
            while (depth < reader.Depth && reader.Read())
            {
                // Nothing, just read on
            }
            // consume end tag
            if (reader.NodeType == XmlNodeType.EndElement)
            {
                reader.Read();
            }

            message.SetStage(SoapMessageStage.AfterDeserialize);
            message.RunExtensions(message.initializedExtensions, false);
            SoapHeaderHandling.SetHeaderMembers(message.Headers, this, method.outHeaderMappings, SoapHeaderDirection.Out | SoapHeaderDirection.Fault, true);

            if (message.Exception != null)
            {
                throw message.Exception;
            }
            return(message.GetParameterValues());
        }