1 //----------------------------------------------------------------------------- 2 // Copyright (c) Microsoft Corporation. All rights reserved. 3 //----------------------------------------------------------------------------- 4 5 namespace System.ServiceModel.Channels 6 { 7 using System; 8 using System.Globalization; 9 10 public abstract class FaultConverter 11 { GetDefaultFaultConverter(MessageVersion version)12 public static FaultConverter GetDefaultFaultConverter(MessageVersion version) 13 { 14 return new DefaultFaultConverter(version); 15 } 16 OnTryCreateException(Message message, MessageFault fault, out Exception exception)17 protected abstract bool OnTryCreateException(Message message, MessageFault fault, out Exception exception); OnTryCreateFaultMessage(Exception exception, out Message message)18 protected abstract bool OnTryCreateFaultMessage(Exception exception, out Message message); 19 TryCreateException(Message message, MessageFault fault, out Exception exception)20 public bool TryCreateException(Message message, MessageFault fault, out Exception exception) 21 { 22 if (message == null) 23 { 24 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("message"); 25 } 26 if (fault == null) 27 { 28 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("fault"); 29 } 30 31 bool created = this.OnTryCreateException(message, fault, out exception); 32 33 if (created) 34 { 35 if (exception == null) 36 { 37 string text = SR.GetString(SR.FaultConverterDidNotCreateException, this.GetType().Name); 38 Exception error = new InvalidOperationException(text); 39 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(error); 40 } 41 } 42 else 43 { 44 if (exception != null) 45 { 46 string text = SR.GetString(SR.FaultConverterCreatedException, this.GetType().Name); 47 Exception error = new InvalidOperationException(text, exception); 48 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(error); 49 } 50 } 51 52 return created; 53 } 54 TryCreateFaultMessage(Exception exception, out Message message)55 public bool TryCreateFaultMessage(Exception exception, out Message message) 56 { 57 bool created = this.OnTryCreateFaultMessage(exception, out message); 58 59 if (created) 60 { 61 if (message == null) 62 { 63 string text = SR.GetString(SR.FaultConverterDidNotCreateFaultMessage, this.GetType().Name); 64 Exception error = new InvalidOperationException(text); 65 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(error); 66 } 67 } 68 else 69 { 70 if (message != null) 71 { 72 string text = SR.GetString(SR.FaultConverterCreatedFaultMessage, this.GetType().Name); 73 Exception error = new InvalidOperationException(text); 74 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(error); 75 } 76 } 77 78 return created; 79 } 80 81 class DefaultFaultConverter : FaultConverter 82 { 83 MessageVersion version; 84 DefaultFaultConverter(MessageVersion version)85 internal DefaultFaultConverter(MessageVersion version) 86 { 87 this.version = version; 88 } 89 OnTryCreateException(Message message, MessageFault fault, out Exception exception)90 protected override bool OnTryCreateException(Message message, MessageFault fault, out Exception exception) 91 { 92 exception = null; 93 94 // SOAP MustUnderstand 95 if (string.Compare(fault.Code.Namespace, version.Envelope.Namespace, StringComparison.Ordinal) == 0 96 && string.Compare(fault.Code.Name, MessageStrings.MustUnderstandFault, StringComparison.Ordinal) == 0) 97 { 98 exception = new ProtocolException(fault.Reason.GetMatchingTranslation(CultureInfo.CurrentCulture).Text); 99 return true; 100 } 101 102 bool checkSender; 103 bool checkReceiver; 104 FaultCode code; 105 106 if (version.Envelope == EnvelopeVersion.Soap11) 107 { 108 checkSender = true; 109 checkReceiver = true; 110 code = fault.Code; 111 } 112 else 113 { 114 checkSender = fault.Code.IsSenderFault; 115 checkReceiver = fault.Code.IsReceiverFault; 116 code = fault.Code.SubCode; 117 } 118 119 if (code == null) 120 { 121 return false; 122 } 123 124 if (code.Namespace == null) 125 { 126 return false; 127 } 128 129 if (checkSender) 130 { 131 // WS-Addressing 132 if (string.Compare(code.Namespace, version.Addressing.Namespace, StringComparison.Ordinal) == 0) 133 { 134 if (string.Compare(code.Name, AddressingStrings.ActionNotSupported, StringComparison.Ordinal) == 0) 135 { 136 exception = new ActionNotSupportedException(fault.Reason.GetMatchingTranslation(CultureInfo.CurrentCulture).Text); 137 return true; 138 } 139 else if (string.Compare(code.Name, AddressingStrings.DestinationUnreachable, StringComparison.Ordinal) == 0) 140 { 141 exception = new EndpointNotFoundException(fault.Reason.GetMatchingTranslation(CultureInfo.CurrentCulture).Text); 142 return true; 143 } 144 else if (string.Compare(code.Name, Addressing10Strings.InvalidAddressingHeader, StringComparison.Ordinal) == 0) 145 { 146 if (code.SubCode != null && string.Compare(code.SubCode.Namespace, version.Addressing.Namespace, StringComparison.Ordinal) == 0 && 147 string.Compare(code.SubCode.Name, Addressing10Strings.InvalidCardinality, StringComparison.Ordinal) == 0) 148 { 149 exception = new MessageHeaderException(fault.Reason.GetMatchingTranslation(CultureInfo.CurrentCulture).Text, true); 150 return true; 151 } 152 } 153 else if (version.Addressing == AddressingVersion.WSAddressing10) 154 { 155 if (string.Compare(code.Name, Addressing10Strings.MessageAddressingHeaderRequired, StringComparison.Ordinal) == 0) 156 { 157 exception = new MessageHeaderException(fault.Reason.GetMatchingTranslation(CultureInfo.CurrentCulture).Text); 158 return true; 159 } 160 else if (string.Compare(code.Name, Addressing10Strings.InvalidAddressingHeader, StringComparison.Ordinal) == 0) 161 { 162 exception = new ProtocolException(fault.Reason.GetMatchingTranslation(CultureInfo.CurrentCulture).Text); 163 return true; 164 } 165 } 166 else 167 { 168 if (string.Compare(code.Name, Addressing200408Strings.MessageInformationHeaderRequired, StringComparison.Ordinal) == 0) 169 { 170 exception = new ProtocolException(fault.Reason.GetMatchingTranslation(CultureInfo.CurrentCulture).Text); 171 return true; 172 } 173 else if (string.Compare(code.Name, Addressing200408Strings.InvalidMessageInformationHeader, StringComparison.Ordinal) == 0) 174 { 175 exception = new ProtocolException(fault.Reason.GetMatchingTranslation(CultureInfo.CurrentCulture).Text); 176 return true; 177 } 178 } 179 } 180 } 181 182 if (checkReceiver) 183 { 184 // WS-Addressing 185 if (string.Compare(code.Namespace, version.Addressing.Namespace, StringComparison.Ordinal) == 0) 186 { 187 if (string.Compare(code.Name, AddressingStrings.EndpointUnavailable, StringComparison.Ordinal) == 0) 188 { 189 exception = new ServerTooBusyException(fault.Reason.GetMatchingTranslation(CultureInfo.CurrentCulture).Text); 190 return true; 191 } 192 } 193 } 194 195 return false; 196 } 197 OnTryCreateFaultMessage(Exception exception, out Message message)198 protected override bool OnTryCreateFaultMessage(Exception exception, out Message message) 199 { 200 // WSA 201 if (this.version.Addressing == AddressingVersion.WSAddressing10) 202 { 203 if (exception is MessageHeaderException) 204 { 205 MessageHeaderException mhe = exception as MessageHeaderException; 206 if (mhe.HeaderNamespace == AddressingVersion.WSAddressing10.Namespace) 207 { 208 message = mhe.ProvideFault(this.version); 209 return true; 210 } 211 } 212 else if (exception is ActionMismatchAddressingException) 213 { 214 ActionMismatchAddressingException amae = exception as ActionMismatchAddressingException; 215 message = amae.ProvideFault(this.version); 216 return true; 217 } 218 } 219 if (this.version.Addressing != AddressingVersion.None) 220 { 221 if (exception is ActionNotSupportedException) 222 { 223 ActionNotSupportedException anse = exception as ActionNotSupportedException; 224 message = anse.ProvideFault(this.version); 225 return true; 226 } 227 } 228 229 // SOAP 230 if (exception is MustUnderstandSoapException) 231 { 232 MustUnderstandSoapException muse = exception as MustUnderstandSoapException; 233 message = muse.ProvideFault(this.version); 234 return true; 235 } 236 237 message = null; 238 return false; 239 } 240 } 241 } 242 } 243