2 // System.Web.Services.Protocols.WebServiceHelper.cs
5 // Lluis Sanchez Gual (lluis@ximian.com)
7 // Copyright (C) Ximian, Inc. 2003
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
36 using System
.Xml
.Schema
;
37 using System
.Xml
.Serialization
;
38 using System
.Web
.Services
.Description
;
40 namespace System
.Web
.Services
.Protocols
42 internal class WebServiceHelper
44 public const string SoapEnvelopeNamespace
= "http://schemas.xmlsoap.org/soap/envelope/";
45 static readonly char [] trimChars
= { '"', '\'' }
;
46 static readonly bool prettyXml
;
48 static WebServiceHelper ()
50 string pxml
= Environment
.GetEnvironmentVariable ("MONO_WEBSERVICES_PRETTYXML");
51 prettyXml
= (pxml
!= null && pxml
!= "no");
54 public static XmlTextWriter
CreateXmlWriter (Stream s
)
56 // What a waste of UTF8encoders, but it has to be thread safe.
57 XmlTextWriter xtw
= new XmlTextWriter (s
, new UTF8Encoding (false));
60 xtw
.Formatting
= Formatting
.Indented
;
65 public static Encoding
GetContentEncoding (string cts
, out string content_type
)
69 if (cts
== null) cts
= "";
73 int idx
= cts
.IndexOf (';');
77 content_type
= cts
.Substring (0, idx
);
79 content_type
= content_type
.Trim ();
80 for (start
= idx
+ 1; idx
!= -1;)
82 idx
= cts
.IndexOf (";", start
);
85 body
= cts
.Substring (start
);
88 body
= cts
.Substring (start
, idx
- start
);
92 if (body
.StartsWith ("charset="))
94 encoding
= body
.Substring (8);
95 encoding
= encoding
.TrimStart (trimChars
).TrimEnd (trimChars
);
99 return Encoding
.GetEncoding (encoding
);
102 public static void WriteSoapMessage (XmlTextWriter xtw
, SoapTypeStubInfo info
, SoapBindingUse methodUse
, XmlSerializer bodySerializer
, object bodyContent
, SoapHeaderCollection headers
)
104 xtw
.WriteStartDocument ();
105 xtw
.WriteStartElement ("soap", "Envelope", WebServiceHelper
.SoapEnvelopeNamespace
);
106 xtw
.WriteAttributeString ("xmlns", "xsi", null, XmlSchema
.InstanceNamespace
);
107 xtw
.WriteAttributeString ("xmlns", "xsd", null, XmlSchema
.Namespace
);
112 foreach (SoapHeader header
in headers
)
114 XmlSerializer ser
= info
.GetHeaderSerializer (header
.GetType(), methodUse
);
115 xtw
.WriteStartElement ("soap", "Header", WebServiceHelper
.SoapEnvelopeNamespace
);
116 ser
.Serialize (xtw
, header
);
117 xtw
.WriteEndElement ();
122 xtw
.WriteStartElement ("soap", "Body", WebServiceHelper
.SoapEnvelopeNamespace
);
124 if (methodUse
== SoapBindingUse
.Encoded
)
125 xtw
.WriteAttributeString ("encodingStyle", WebServiceHelper
.SoapEnvelopeNamespace
, "http://schemas.xmlsoap.org/soap/encoding/");
127 bodySerializer
.Serialize (xtw
, bodyContent
);
129 xtw
.WriteEndElement ();
130 xtw
.WriteEndElement ();
134 public static void ReadSoapMessage (XmlTextReader xmlReader
, SoapTypeStubInfo typeStubInfo
, SoapBindingUse methodUse
, XmlSerializer bodySerializer
, out object body
, out SoapHeaderCollection headers
)
136 xmlReader
.MoveToContent ();
137 xmlReader
.ReadStartElement ("Envelope", WebServiceHelper
.SoapEnvelopeNamespace
);
139 headers
= ReadHeaders (typeStubInfo
, methodUse
, xmlReader
);
141 xmlReader
.MoveToContent ();
142 xmlReader
.ReadStartElement ("Body", WebServiceHelper
.SoapEnvelopeNamespace
);
143 xmlReader
.MoveToContent ();
145 if (xmlReader
.LocalName
== "Fault" && xmlReader
.NamespaceURI
== SoapEnvelopeNamespace
)
146 bodySerializer
= Fault
.Serializer
;
148 body
= bodySerializer
.Deserialize (xmlReader
);
151 static SoapHeaderCollection
ReadHeaders (SoapTypeStubInfo typeStubInfo
, SoapBindingUse methodUse
, XmlTextReader xmlReader
)
153 SoapHeaderCollection headers
= new SoapHeaderCollection ();
154 while (! (xmlReader
.NodeType
== XmlNodeType
.Element
&& xmlReader
.LocalName
== "Body" && xmlReader
.NamespaceURI
== WebServiceHelper
.SoapEnvelopeNamespace
))
156 if (xmlReader
.NodeType
== XmlNodeType
.Element
&& xmlReader
.LocalName
== "Header"
157 && xmlReader
.NamespaceURI
== WebServiceHelper
.SoapEnvelopeNamespace
&& !xmlReader
.IsEmptyElement
)
159 xmlReader
.ReadStartElement ();
160 xmlReader
.MoveToContent ();
162 while (xmlReader
.NodeType
!= XmlNodeType
.Element
&& xmlReader
.NodeType
!= XmlNodeType
.EndElement
)
165 xmlReader
.MoveToContent ();
167 if (xmlReader
.NodeType
== XmlNodeType
.Element
) {
168 XmlQualifiedName qname
= new XmlQualifiedName (xmlReader
.LocalName
, xmlReader
.NamespaceURI
);
169 XmlSerializer headerSerializer
= typeStubInfo
.GetHeaderSerializer (qname
, methodUse
);
170 if (headerSerializer
!= null)
172 SoapHeader header
= (SoapHeader
) headerSerializer
.Deserialize (xmlReader
);
173 headers
.Add (header
);
177 XmlDocument doc
= new XmlDocument ();
178 XmlElement elem
= (XmlElement
) doc
.ReadNode (xmlReader
);
179 headers
.Add (new SoapUnknownHeader (elem
));
183 while (xmlReader
.NodeType
!= XmlNodeType
.EndElement
)
186 xmlReader
.ReadEndElement ();
194 public static void InvalidOperation (string message
, WebResponse response
, Encoding enc
)
196 if (response
== null)
197 throw new InvalidOperationException (message
);
202 StringBuilder sb
= new StringBuilder ();
204 sb
.Append ("\r\nResponse error message:\r\n--\r\n");
207 StreamReader resp
= new StreamReader (response
.GetResponseStream (), enc
);
208 sb
.Append (resp
.ReadToEnd ());
209 } catch (Exception
) {
212 throw new InvalidOperationException (sb
.ToString ());