X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fclass%2FSystem.Web.Services%2FSystem.Web.Services.Protocols%2FWebServiceHelper.cs;h=1861fd6b594697d693c1daf2db0220607edc0f86;hb=a57c3b9782ca02e4f060ac37dac5b2a20f16772a;hp=3c2efcfbfc1d221f89f7ded6bec9342577dabd50;hpb=b7c17c47e6b3c02192e64175cb5ee0ce7f7dda1b;p=mono.git diff --git a/mcs/class/System.Web.Services/System.Web.Services.Protocols/WebServiceHelper.cs b/mcs/class/System.Web.Services/System.Web.Services.Protocols/WebServiceHelper.cs old mode 100755 new mode 100644 index 3c2efcfbfc1..1861fd6b594 --- a/mcs/class/System.Web.Services/System.Web.Services.Protocols/WebServiceHelper.cs +++ b/mcs/class/System.Web.Services/System.Web.Services.Protocols/WebServiceHelper.cs @@ -42,6 +42,9 @@ namespace System.Web.Services.Protocols internal class WebServiceHelper { public const string SoapEnvelopeNamespace = "http://schemas.xmlsoap.org/soap/envelope/"; + public const string Soap12EnvelopeNamespace = "http://www.w3.org/2003/05/soap-envelope"; + public const string SoapEncodingNamespace = "http://schemas.xmlsoap.org/soap/encoding/"; + public const string Soap12EncodingNamespace = "http://www.w3.org/2003/05/soap-encoding"; static readonly char [] trimChars = { '"', '\'' }; static readonly bool prettyXml; @@ -66,6 +69,8 @@ namespace System.Web.Services.Protocols { string encoding; + if (cts == null) cts = ""; + encoding = "utf-8"; int start = 0; int idx = cts.IndexOf (';'); @@ -97,30 +102,41 @@ namespace System.Web.Services.Protocols return Encoding.GetEncoding (encoding); } - public static void WriteSoapMessage (XmlTextWriter xtw, SoapTypeStubInfo info, SoapBindingUse methodUse, XmlSerializer bodySerializer, object bodyContent, SoapHeaderCollection headers) + public static void WriteSoapMessage (XmlTextWriter xtw, SoapMethodStubInfo method, SoapHeaderDirection dir, object bodyContent, SoapHeaderCollection headers, bool soap12) + { + SoapBindingUse methodUse = dir == SoapHeaderDirection.Fault ? SoapBindingUse.Literal : method.Use; + XmlSerializer bodySerializer = method.GetBodySerializer (dir, soap12); + XmlSerializer headerSerializer = method.GetHeaderSerializer (dir); + object[] headerArray = method.GetHeaderValueArray (dir, headers); + WriteSoapMessage (xtw, methodUse, bodySerializer, headerSerializer, bodyContent, headerArray, soap12); + } + + public static void WriteSoapMessage (XmlTextWriter xtw, SoapBindingUse methodUse, XmlSerializer bodySerializer, XmlSerializer headerSerializer, object bodyContent, object[] headers, bool soap12) { + string ns = soap12 ? + WebServiceHelper.Soap12EnvelopeNamespace : + WebServiceHelper.SoapEnvelopeNamespace; + string encNS = soap12 ? + WebServiceHelper.Soap12EncodingNamespace : + WebServiceHelper.SoapEncodingNamespace; xtw.WriteStartDocument (); - xtw.WriteStartElement ("soap", "Envelope", WebServiceHelper.SoapEnvelopeNamespace); + xtw.WriteStartElement ("soap", "Envelope", ns); xtw.WriteAttributeString ("xmlns", "xsi", null, XmlSchema.InstanceNamespace); xtw.WriteAttributeString ("xmlns", "xsd", null, XmlSchema.Namespace); // Serialize headers if (headers != null) { - foreach (SoapHeader header in headers) - { - XmlSerializer ser = info.GetHeaderSerializer (header.GetType(), methodUse); - xtw.WriteStartElement ("soap", "Header", WebServiceHelper.SoapEnvelopeNamespace); - ser.Serialize (xtw, header); - xtw.WriteEndElement (); - } + xtw.WriteStartElement ("soap", "Header", ns); + headerSerializer.Serialize (xtw, headers); + xtw.WriteEndElement (); } // Serialize body - xtw.WriteStartElement ("soap", "Body", WebServiceHelper.SoapEnvelopeNamespace); + xtw.WriteStartElement ("soap", "Body", ns); if (methodUse == SoapBindingUse.Encoded) - xtw.WriteAttributeString ("encodingStyle", WebServiceHelper.SoapEnvelopeNamespace, "http://schemas.xmlsoap.org/soap/encoding/"); + xtw.WriteAttributeString ("encodingStyle", ns, encNS); bodySerializer.Serialize (xtw, bodyContent); @@ -129,51 +145,157 @@ namespace System.Web.Services.Protocols xtw.Flush (); } - public static void ReadSoapMessage (XmlTextReader xmlReader, SoapTypeStubInfo typeStubInfo, SoapBindingUse methodUse, XmlSerializer bodySerializer, out object body, out SoapHeaderCollection headers) + public static void ReadSoapMessage (XmlTextReader xmlReader, SoapMethodStubInfo method, SoapHeaderDirection dir, bool soap12, out object body, out SoapHeaderCollection headers) + { + XmlSerializer bodySerializer = method.GetBodySerializer (dir, false);// no need to worry about soap12 arg since no call for Fault anyways here. + XmlSerializer headerSerializer = method.GetHeaderSerializer (dir); + ReadSoapMessage (xmlReader, bodySerializer, headerSerializer, soap12, out body, out headers); + } + + public static void ReadSoapMessage (XmlTextReader xmlReader, XmlSerializer bodySerializer, XmlSerializer headerSerializer, bool soap12, out object body, out SoapHeaderCollection headers) { - xmlReader.MoveToContent (); - xmlReader.ReadStartElement ("Envelope", WebServiceHelper.SoapEnvelopeNamespace); - - headers = ReadHeaders (typeStubInfo, methodUse, xmlReader); - - xmlReader.MoveToContent (); - xmlReader.ReadStartElement ("Body", WebServiceHelper.SoapEnvelopeNamespace); + xmlReader.MoveToContent (); + string ns = xmlReader.NamespaceURI; + switch (ns) { +#if NET_2_0 + case WebServiceHelper.Soap12EnvelopeNamespace: +#endif + case WebServiceHelper.SoapEnvelopeNamespace: + break; + default: + throw new SoapException (String.Format ("SOAP version mismatch. Namespace '{0}' is not supported in this runtime profile.", ns), VersionMismatchFaultCode (soap12)); + } + xmlReader.ReadStartElement ("Envelope", ns); + + headers = ReadHeaders (xmlReader, headerSerializer, ns); + + xmlReader.MoveToContent (); + xmlReader.ReadStartElement ("Body", ns); xmlReader.MoveToContent (); - if (xmlReader.LocalName == "Fault" && xmlReader.NamespaceURI == SoapEnvelopeNamespace) - bodySerializer = Fault.Serializer; - - body = bodySerializer.Deserialize (xmlReader); + if (xmlReader.LocalName == "Fault" && xmlReader.NamespaceURI == ns) + bodySerializer = ns == Soap12EnvelopeNamespace ? Soap12Fault.Serializer : Fault.Serializer; + + body = bodySerializer.Deserialize (xmlReader); } - static SoapHeaderCollection ReadHeaders (SoapTypeStubInfo typeStubInfo, SoapBindingUse methodUse, XmlTextReader xmlReader) + static SoapHeaderCollection ReadHeaders (XmlTextReader xmlReader, XmlSerializer headerSerializer, string ns) { - SoapHeaderCollection headers = new SoapHeaderCollection (); - while (! (xmlReader.NodeType == XmlNodeType.Element && xmlReader.LocalName == "Body" && xmlReader.NamespaceURI == WebServiceHelper.SoapEnvelopeNamespace)) + SoapHeaderCollection headers = null; + while (! (xmlReader.NodeType == XmlNodeType.Element && xmlReader.LocalName == "Body" && xmlReader.NamespaceURI == ns)) { if (xmlReader.NodeType == XmlNodeType.Element && xmlReader.LocalName == "Header" - && xmlReader.NamespaceURI == WebServiceHelper.SoapEnvelopeNamespace && !xmlReader.IsEmptyElement) + && xmlReader.NamespaceURI == ns && !xmlReader.IsEmptyElement + && headerSerializer != null) { xmlReader.ReadStartElement (); xmlReader.MoveToContent (); - XmlQualifiedName qname = new XmlQualifiedName (xmlReader.LocalName, xmlReader.NamespaceURI); - XmlSerializer headerSerializer = typeStubInfo.GetHeaderSerializer (qname, methodUse); - if (headerSerializer != null) - { - SoapHeader header = (SoapHeader) headerSerializer.Deserialize (xmlReader); - headers.Add (header); - } - else - { - while (xmlReader.NodeType == XmlNodeType.EndElement) - xmlReader.Skip (); // TODO: Check if the header has mustUnderstand=true + + HeaderSerializationHelper uh = new HeaderSerializationHelper (headerSerializer); + headers = uh.Deserialize (xmlReader); + + while (xmlReader.NodeType != XmlNodeType.EndElement) xmlReader.Skip (); - } + + xmlReader.ReadEndElement (); } else xmlReader.Skip (); } - return headers; + if (headers != null) + return headers; + else + return new SoapHeaderCollection (); + } + + class HeaderSerializationHelper + { + SoapHeaderCollection headers; + XmlSerializer headerSerializer; + + public HeaderSerializationHelper (XmlSerializer headerSerializer) + { + this.headers = new SoapHeaderCollection (); + this.headerSerializer = headerSerializer; + } + + public SoapHeaderCollection Deserialize (XmlTextReader xmlReader) + { + try { + headerSerializer.UnknownElement += new XmlElementEventHandler (OnAddUnknownHeader); + object[] headerArray = (object[]) headerSerializer.Deserialize (xmlReader); + foreach (SoapHeader h in headerArray) + if (h != null) headers.Add (h); + return headers; + } finally { + headerSerializer.UnknownElement -= new XmlElementEventHandler (OnAddUnknownHeader); + } + } + + void OnAddUnknownHeader (object sender, XmlElementEventArgs e) + { + headers.Add (new SoapUnknownHeader (e.Element)); + } + } + +#if NET_2_0 + public static SoapException Soap12FaultToSoapException (Soap12Fault fault) + { + Soap12FaultReasonText text = + fault.Reason != null && + fault.Reason.Texts != null && + fault.Reason.Texts.Length > 0 ? + fault.Reason.Texts [fault.Reason.Texts.Length - 1] : null; + XmlNode detail = (fault.Detail == null) ? null : + (fault.Detail.Children != null && + fault.Detail.Children.Length > 0) ? + (XmlNode) fault.Detail.Children [0] : + (fault.Detail.Attributes != null && + fault.Detail.Attributes.Length > 0) ? + fault.Detail.Attributes [0] : null; + SoapFaultSubCode subcode = Soap12Fault.GetSoapFaultSubCode (fault.Code.Subcode); + return new SoapException ( + text != null ? text.Value : null, + fault.Code.Value, null, fault.Role, + text != null ? text.XmlLang : null, + detail, subcode, null); + } +#endif + + public static XmlQualifiedName ClientFaultCode (bool soap12) + { +#if NET_2_0 + return soap12 ? Soap12FaultCodes.SenderFaultCode : SoapException.ClientFaultCode; +#else + return SoapException.ClientFaultCode; +#endif + } + + public static XmlQualifiedName ServerFaultCode (bool soap12) + { +#if NET_2_0 + return soap12 ? Soap12FaultCodes.ReceiverFaultCode : SoapException.ServerFaultCode; +#else + return SoapException.ServerFaultCode; +#endif + } + + public static XmlQualifiedName MustUnderstandFaultCode (bool soap12) + { +#if NET_2_0 + return soap12 ? Soap12FaultCodes.ReceiverFaultCode : SoapException.MustUnderstandFaultCode; +#else + return SoapException.MustUnderstandFaultCode; +#endif + } + + public static XmlQualifiedName VersionMismatchFaultCode (bool soap12) + { +#if NET_2_0 + return soap12 ? Soap12FaultCodes.VersionMismatchFaultCode : SoapException.VersionMismatchFaultCode; +#else + return SoapException.VersionMismatchFaultCode; +#endif } public static void InvalidOperation (string message, WebResponse response, Encoding enc) @@ -186,12 +308,14 @@ namespace System.Web.Services.Protocols StringBuilder sb = new StringBuilder (); sb.Append (message); - sb.Append ("\r\nResponse error message:\r\n--\r\n"); + if (response.ContentLength > 0) { + sb.Append ("\r\nResponse error message:\r\n--\r\n"); - try { - StreamReader resp = new StreamReader (response.GetResponseStream (), enc); - sb.Append (resp.ReadToEnd ()); - } catch (Exception) { + try { + StreamReader resp = new StreamReader (response.GetResponseStream (), enc); + sb.Append (resp.ReadToEnd ()); + } catch (Exception) { + } } throw new InvalidOperationException (sb.ToString ());