Adding System.Data..., System.ServiceModel..., and System.Web...
[mono.git] / mcs / class / referencesource / System.Web.Services / System / Web / Services / Protocols / SoapException.cs
1 //------------------------------------------------------------------------------
2 // <copyright file="SoapException.cs" company="Microsoft">
3 //     Copyright (c) Microsoft Corporation.  All rights reserved.
4 // </copyright>                                                                
5 //------------------------------------------------------------------------------
6
7 namespace System.Web.Services.Protocols {
8     using System;
9     using System.Collections;
10     using System.Reflection;
11     using System.Security.Permissions;
12     using System.Xml;
13     using System.Xml.Serialization;
14     using System.Runtime.InteropServices;
15     using System.Runtime.Serialization;
16
17     /// <include file='doc\SoapException.uex' path='docs/doc[@for="SoapException"]/*' />
18     /// <devdoc>
19     ///    <para>SoapException is the only mechanism for raising exceptions when a Web
20     ///       Method is called over SOAP. A SoapException can either be generated
21     ///       by the .Net Runtime or by a Web Service Method.
22     ///       The .Net Runtime can generate an SoapException, if a response to a request
23     ///       that is malformed. A Web Service Method can generate a SoapException by simply
24     ///       generating an Exception within the Web Service Method, if the client accessed the method
25     ///       over SOAP. Any time a Web Service Method throws an exception, that exception
26     ///       is caught on the server and wrapped inside a new SoapException.</para>
27     /// </devdoc>
28     [Serializable]
29     public class SoapException : SystemException {
30         XmlQualifiedName code = XmlQualifiedName.Empty;
31         string actor;
32         string role;
33         System.Xml.XmlNode detail;
34         SoapFaultSubCode subCode;
35         string lang;
36
37
38         /// <include file='doc\SoapException.uex' path='docs/doc[@for="SoapException.ServerFaultCode"]/*' />
39         /// <devdoc>
40         ///    <para>[To be supplied.]</para>
41         /// </devdoc>
42         public static readonly XmlQualifiedName ServerFaultCode = new XmlQualifiedName(Soap.Code.Server, Soap.Namespace);
43         /// <include file='doc\SoapException.uex' path='docs/doc[@for="SoapException.ClientFaultCode"]/*' />
44         /// <devdoc>
45         ///    <para>[To be supplied.]</para>
46         /// </devdoc>
47         public static readonly XmlQualifiedName ClientFaultCode = new XmlQualifiedName(Soap.Code.Client, Soap.Namespace);
48         /// <include file='doc\SoapException.uex' path='docs/doc[@for="SoapException.VersionMismatchFaultCode"]/*' />
49         /// <devdoc>
50         ///    <para>[To be supplied.]</para>
51         /// </devdoc>
52         public static readonly XmlQualifiedName VersionMismatchFaultCode = new XmlQualifiedName(Soap.Code.VersionMismatch, Soap.Namespace);
53         /// <include file='doc\SoapException.uex' path='docs/doc[@for="SoapException.MustUnderstandFaultCode"]/*' />
54         /// <devdoc>
55         ///    <para>[To be supplied.]</para>
56         /// </devdoc>
57         public static readonly XmlQualifiedName MustUnderstandFaultCode = new XmlQualifiedName(Soap.Code.MustUnderstand, Soap.Namespace);
58         /// <include file='doc\SoapException.uex' path='docs/doc[@for="SoapException.DetailElementName"]/*' />
59         /// <devdoc>
60         ///    <para>[To be supplied.]</para>
61         /// </devdoc>
62         // NOTE, [....]: The SOAP 1.1 is unclear on whether the detail element can or should be qualified.
63         // Based on consensus about the intent, we will not qualify it.
64         public static readonly XmlQualifiedName DetailElementName = new XmlQualifiedName(Soap.Element.FaultDetail, "");
65
66         /// <include file='doc\SoapException.uex' path='docs/doc[@for="SoapException.IsServerFaultCode"]/*' />
67         public static bool IsServerFaultCode(XmlQualifiedName code) {
68             return code == ServerFaultCode || code == Soap12FaultCodes.ReceiverFaultCode;
69         }
70
71         /// <include file='doc\SoapException.uex' path='docs/doc[@for="SoapException.IsClientFaultCode"]/*' />
72         public static bool IsClientFaultCode(XmlQualifiedName code) {
73             return code == ClientFaultCode || code == Soap12FaultCodes.SenderFaultCode;
74         }
75
76         /// <include file='doc\SoapException.uex' path='docs/doc[@for="SoapException.IsVersionMismatchFaultCode"]/*' />
77         public static bool IsVersionMismatchFaultCode(XmlQualifiedName code) {
78             return code == VersionMismatchFaultCode || code == Soap12FaultCodes.VersionMismatchFaultCode;
79         }
80
81         /// <include file='doc\SoapException.uex' path='docs/doc[@for="SoapException.IsMustUnderstandFaultCode"]/*' />
82         public static bool IsMustUnderstandFaultCode(XmlQualifiedName code) {
83             return code == MustUnderstandFaultCode || code == Soap12FaultCodes.MustUnderstandFaultCode;
84         }
85
86         /// <include file='doc\SoapException.uex' path='docs/doc[@for="SoapException.SoapException9"]/*' />
87         public SoapException() : base(null) {
88         }
89
90         /// <include file='doc\SoapException.uex' path='docs/doc[@for="SoapException.SoapException"]/*' />
91         /// <devdoc>
92         /// <para>Initializes a new instance of the <see cref='System.Web.Services.Protocols.SoapException'/> class, setting <see cref='System.Exception.Message'/> to <paramref name="message"/>, <see cref='System.Web.Services.Protocols.SoapException.Code'/> to
93         /// <paramref name="code"/> and <see cref='System.Web.Services.Protocols.SoapException.Actor'/> to <paramref name="actor"/>.</para>
94         /// </devdoc>
95         public SoapException(string message, XmlQualifiedName code, string actor) : base(message) { 
96             this.code = code;
97             this.actor = actor;
98         }
99
100         /// <include file='doc\SoapException.uex' path='docs/doc[@for="SoapException.SoapException1"]/*' />
101         /// <devdoc>
102         /// <para>Initializes a new instance of the <see cref='System.Web.Services.Protocols.SoapException'/> class, setting <see cref='System.Exception.Message'/> to 
103         /// <paramref name="message"/>, <see cref='System.Web.Services.Protocols.SoapException.Code'/> to <paramref name="code, 
104         ///    "/><see cref='System.Web.Services.Protocols.SoapException.Actor'/> to <paramref name="actor
105         ///    "/>and <see cref='System.Exception.InnerException'/> to <paramref name="innerException"/> .</para>
106         /// </devdoc>
107         public SoapException(string message, XmlQualifiedName code, string actor, Exception innerException) : base(message, innerException) { 
108             this.code = code;
109             this.actor = actor;
110         }
111
112         /// <include file='doc\SoapException.uex' path='docs/doc[@for="SoapException.SoapException2"]/*' />
113         /// <devdoc>
114         /// <para>Initializes a new instance of the <see cref='System.Web.Services.Protocols.SoapException'/> class, setting <see cref='System.Exception.Message'/> to
115         /// <paramref name="message "/>and<paramref name=" "/>
116         /// <see cref='System.Web.Services.Protocols.SoapException.Code'/> 
117         /// to <paramref name="code"/>.</para>
118         /// </devdoc>
119         public SoapException(string message, XmlQualifiedName code) : base(message) { 
120             this.code = code;
121         }
122
123         /// <include file='doc\SoapException.uex' path='docs/doc[@for="SoapException.SoapException3"]/*' />
124         /// <devdoc>
125         /// <para>Initializes a new instance of the <see cref='System.Web.Services.Protocols.SoapException'/> class, setting <see cref='System.Exception.Message'/> to
126         /// <paramref name="message"/>, <see cref='System.Web.Services.Protocols.SoapException.Code'/> to <paramref name="code "/>and 
127         /// <see cref='System.Exception.InnerException'/> 
128         /// to <paramref name="innerException"/>.</para>
129         /// </devdoc>
130         public SoapException(string message, XmlQualifiedName code, Exception innerException) : base(message, innerException) { 
131             this.code = code;
132         }
133
134         /// <include file='doc\SoapException.uex' path='docs/doc[@for="SoapException.SoapException4"]/*' />
135         /// <devdoc>
136         ///    <para>[To be supplied.]</para>
137         /// </devdoc>
138         public SoapException(string message, XmlQualifiedName code, string actor, System.Xml.XmlNode detail) : base(message) {
139             this.code = code;
140             this.actor = actor;
141             this.detail = detail;
142         }
143
144         /// <include file='doc\SoapException.uex' path='docs/doc[@for="SoapException.SoapException5"]/*' />
145         /// <devdoc>
146         ///    <para>[To be supplied.]</para>
147         /// </devdoc>
148         public SoapException(string message, XmlQualifiedName code, string actor, System.Xml.XmlNode detail, Exception innerException) : base(message, innerException) {
149             this.code = code;
150             this.actor = actor;
151             this.detail = detail;
152         }
153
154         /// <include file='doc\SoapException.uex' path='docs/doc[@for="SoapException.SoapException6"]/*' />
155         /// <devdoc>
156         ///    <para>[To be supplied.]</para>
157         /// </devdoc>
158         public SoapException(string message, XmlQualifiedName code, SoapFaultSubCode subCode) : base(message) {
159             this.code = code;
160             this.subCode = subCode;
161         }
162
163         /// <include file='doc\SoapException.uex' path='docs/doc[@for="SoapException.SoapException7"]/*' />
164         /// <devdoc>
165         ///    <para>[To be supplied.]</para>
166         /// </devdoc>
167         public SoapException(string message, XmlQualifiedName code, string actor, string role, System.Xml.XmlNode detail, SoapFaultSubCode subCode, Exception innerException) : base(message, innerException) {
168             this.code = code;
169             this.actor = actor;
170             this.role = role;
171             this.detail = detail;
172             this.subCode = subCode;
173         }
174
175         /// <include file='doc\SoapException.uex' path='docs/doc[@for="SoapException.SoapException8"]/*' />
176         /// <devdoc>
177         ///    <para>[To be supplied.]</para>
178         /// </devdoc>
179         public SoapException(string message, XmlQualifiedName code, string actor, string role, string lang, System.Xml.XmlNode detail, SoapFaultSubCode subCode, Exception innerException) : base(message, innerException) {
180             this.code = code;
181             this.actor = actor;
182             this.role = role;
183             this.detail = detail;
184             this.lang = lang;
185             this.subCode = subCode;
186         }
187
188         protected SoapException(SerializationInfo info, StreamingContext context) : base(info, context) {
189             IDictionary list = base.Data;
190             code = (XmlQualifiedName)list["code"];
191             actor = (string)list["actor"];
192             role = (string)list["role"];
193             
194             // Bug: 323493: XmlNode is not serializable, and I don't think we want to really want to create
195             // an XmlDocument just to read a XmlNode from string to get the deserialized instance back.
196             // detail = (XmlNode)list["detail"];
197
198             subCode = (SoapFaultSubCode)list["subCode"];
199             lang = (string)list["lang"];
200         }
201
202         /// <include file='doc\SoapException.uex' path='docs/doc[@for="SoapException.Actor"]/*' />
203         /// <devdoc>
204         ///    The piece of code that caused the exception.
205         ///    Typically, an URL to a Web Service Method.
206         /// </devdoc>
207         public string Actor {
208             get { return actor == null ? string.Empty : actor; }
209         }
210
211         /// <include file='doc\SoapException.uex' path='docs/doc[@for="SoapException.Code"]/*' />
212         /// <devdoc>
213         ///    <para>The type of error that occurred.</para>
214         /// </devdoc>
215         public XmlQualifiedName Code {    
216             get { return code; }
217         }
218
219         // the <soap:detail> element. If null, the <detail> element was not present in the <fault> element.
220         /// <include file='doc\SoapException.uex' path='docs/doc[@for="SoapException.Detail"]/*' />
221         /// <devdoc>
222         ///    <para>[To be supplied.]</para>
223         /// </devdoc>
224         public System.Xml.XmlNode Detail {
225             get {
226                 return detail;
227             }
228         }
229
230         /// <include file='doc\SoapException.uex' path='docs/doc[@for="SoapException.Lang"]/*' />
231         /// <devdoc>
232         ///    <para>[To be supplied.]</para>
233         /// </devdoc>
234         [ComVisible(false)]
235         public string Lang {
236             get { return lang == null ? string.Empty : lang; }
237         }
238
239         // this is semantically the same as Actor so we use the same field but we offer a second property
240         // in case the user is thinking in soap 1.2
241         /// <include file='doc\SoapException.uex' path='docs/doc[@for="SoapException.Node"]/*' />
242         /// <devdoc>
243         ///    <para>[To be supplied.]</para>
244         /// </devdoc>
245         [ComVisible(false)]
246         public string Node {
247             get { return actor == null ? string.Empty : actor; }
248         }
249
250         /// <include file='doc\SoapException.uex' path='docs/doc[@for="SoapException.Role"]/*' />
251         /// <devdoc>
252         ///    <para>[To be supplied.]</para>
253         /// </devdoc>
254         [ComVisible(false)]
255         public string Role {
256             get { return role == null ? string.Empty : role; }
257         }
258
259         /// <include file='doc\SoapException.uex' path='docs/doc[@for="SoapException.SubCode"]/*' />
260         /// <devdoc>
261         ///    <para>[To be supplied.]</para>
262         /// </devdoc>
263         [ComVisible(false)]
264         public SoapFaultSubCode SubCode {
265             get {
266                 return subCode; 
267             }
268         }
269
270         // helper function that allows us to pass dummy subCodes around but clear them before they get to the user
271         internal void ClearSubCode() {
272             if (subCode != null)
273                 subCode = subCode.SubCode;
274         }
275
276         [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.SerializationFormatter)]
277         public override void GetObjectData(SerializationInfo info, StreamingContext context) {
278             IDictionary list = Data;
279             list["code"] = Code;
280             list["actor"] = Actor;
281             list["role"] = Role;
282             
283             // Bug: 323493: XmlNode is not serializable, and I don't think we want to really want to create
284             // an XmlDocument just to read a XmlNode from string to get the deserialized instance back.
285             // list["detail"] = Detail;
286             
287             list["subCode"] = SubCode;
288             list["lang"] = Lang;
289
290             base.GetObjectData(info, context);
291         }
292
293         static SoapException CreateSuppressedException(SoapProtocolVersion soapVersion, string message, Exception innerException) {
294             return new SoapException(Res.GetString(Res.WebSuppressedExceptionMessage), 
295                 soapVersion == SoapProtocolVersion.Soap12 
296                 ? new XmlQualifiedName(Soap12.Code.Receiver, Soap12.Namespace) 
297                 : new XmlQualifiedName(Soap.Code.Server, Soap.Namespace));
298         }
299
300         internal static SoapException Create(SoapProtocolVersion soapVersion, string message, XmlQualifiedName code, 
301                                                        string actor, string role, System.Xml.XmlNode detail,
302                                                        SoapFaultSubCode subCode, Exception innerException) {
303             if (System.Web.Services.Configuration.WebServicesSection.Current.Diagnostics.SuppressReturningExceptions) {
304                 return CreateSuppressedException(soapVersion, Res.GetString(Res.WebSuppressedExceptionMessage), innerException);
305             }
306             else {
307                 return new SoapException(message, code, actor, role, detail, subCode, innerException);
308             }
309         }
310         internal static SoapException Create(SoapProtocolVersion soapVersion, string message, XmlQualifiedName code, Exception innerException) { 
311             if (System.Web.Services.Configuration.WebServicesSection.Current.Diagnostics.SuppressReturningExceptions) {
312                 return CreateSuppressedException(soapVersion, Res.GetString(Res.WebSuppressedExceptionMessage), innerException);
313             }
314             else {
315                 return new SoapException(message, code, innerException);
316             }
317         }
318     }
319 }
320