If you are developing ASP.NET you can easily use the Application_Error event within the Global.asax Syntax file for your global exception handling needs.
However, this approach is not available for Web Services applications. The Application_Error event is not fired if your web method throws an exception. The reason for this is that the HTTP handler for XML Web services consumes any exception that occurs while an XML Web service is executing and turns it into a SOAP fault prior to the Application_Error
event is called.
To achieve global exception handling you have to build a SOAP extension. The SOAP extension can check for the existence of an exception in the ProcessMessage method.
public class SoapExceptionHandler
: System.Web.Services.Protocols.SoapExtension {
public override void ProcessMessage(
System.Web.Services.Protocols.SoapMessage message) {
if (message.Stage == SoapMessageStage.AfterSerialize) {
if (message.Exception != null) {
Logger.Write(message.Exception.InnerException);
}
}
}
public override object GetInitializer(Type serviceType) {
return null;
}
public override object GetInitializer(LogicalMethodInfo methodInfo,
SoapExtensionAttribute attribute) {
return null;
}
public override void Initialize(object initializer) {}
}
Obviously, you can do a lot more than just log the Exception.
A common approch is to add or remove information to the SoapFault Message to control what data is send over to the client. However, you should override ChainStream if you plan to do so. There is a good posting called Inside Of Chain Stream. The ChainStream methods allows your SOAP extension to access to the memory buffer containing the SOAP response.
Another good article over at haacked.com deals with excpetion injection using custom soap extensions or take a look at Jan Tielens Throwing SoapExceptions article.
Once you have your custom soap extension you can either register it in your web.config via the <soapExtensionTypes> tag or you create an SoapExtensionAttribute to get more fine grained control about the execution of the SoapExtension.
The Attribute would look like this:
[AttributeUsage(AttributeTargets.Method)]
public class ExceptionHandlingAttribute : SoapExtensionAttribute
{
public override Type ExtensionType{get { return typeof(SoapExceptionHandler); }}
public override int Priority{get{return 0;}set{}}
}
You can apply this attribute to your XML Web service methods and thus enable your newly created SoapExtension.
[WebMethod]
[ExceptionHandling]
public void Foo(){}