I have searched many articles about error handling in WCF
and found few articles which explain about the error handling in WCF. After
accomplishing my work, I thought of sharing knowledge on how to handle the
errors in WCF globally. Hope this will help someone who wants to deal the
exceptions globally in WCF.
I have explained it in just 3 Step process!
1.
Create a Class which implements “IErrorHandler” interface 2.
Create a Class which inherits “Attribute” abstract class and implement
“IServiceBehavior” interface 3.
Decorate WCF Endpoint implementation class with the
above two mentioned class.
We will see above 3 steps in detail below. 1. Implementing
“IErrorHandler” interface
In the “ProvideFault” method, log the
actual exception and provide the generic exception to the outer world.
public class GlobalErrorHandler : IErrorHandler
{
public bool HandleError(Exception error)
{
var
canReturn = true;
return
canReturn;
}
public void ProvideFault(Exception error,
System.ServiceModel.Channels.MessageVersion version, ref
System.ServiceModel.Channels.Message fault)
{
// Log your exception here.
// LogException(error);
FaultCode fc = new FaultCode("NewFaultCode");
MessageVersion ver = OperationContext.Current.IncomingMessageVersion;
fault = Message.CreateMessage(ver, fc, "Original Exception is
handled! this is customized exception!", "Out
Going Server Response");
}
}
2. Inherits “Attribute” abstract class and implement
“IServiceBehavior” interface In the “ApplyDispatchBehavior”
method, the above mentioned “GlobalErrorHandler” class needs to be added into
the “ChannelDispatcher”. So whenever error occurs in the application, it will
redirect to the class’ method which implements “IErrorHandler” interface.
public class GlobalErrorBehaviorAttribute : Attribute, IServiceBehavior
{
Type
errorHandlerType;
public
GlobalErrorBehaviorAttribute(Type errorHandlerType)
{
this.errorHandlerType
= errorHandlerType;
}
public void Validate(ServiceDescription description, ServiceHostBase serviceHostBase)
{
}
public void AddBindingParameters(ServiceDescription description, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection parameters)
{
}
public void ApplyDispatchBehavior(ServiceDescription description, ServiceHostBase serviceHostBase)
{
var errorHandler = (IErrorHandler)Activator.CreateInstance(errorHandlerType);
foreach (ChannelDispatcherBase channelDispatcherBase in
serviceHostBase.ChannelDispatchers)
{
ChannelDispatcher channelDispatcher = channelDispatcherBase as ChannelDispatcher;
channelDispatcher.ErrorHandlers.Add(errorHandler);
}
}
}
3. Decorate
WCF Endpoint implementation class with the above two mentioned class as an
attribute.
This
is the final step in this concept and it is very important! Decorate the Service
class with “GlobalErrorBehaviorAttribute” and “GlobalErrorHandler” class
[GlobalErrorBehaviorAttribute(typeof(GlobalErrorHandler))]
public class Service1 : IService1 {
public string GetData(int value)
{
if (value == 99)
{
// just throwing
exception.
throw new Exception("Method will not
accept 99");
}
if (value == 98)
{
// we Know that it
will throw error.
Convert.ToDateTime(value);
}
return string.Format("You entered:
{0}",
value);
}
}
That’s
it!! This method will throw exceptions when we pass 99 & 98 intentionally.
End Point Testing (SOAP UI):
I have used SOAP UI to test the WCF end point.
1.
Passing string
parameter – Since accepted input is “Integer”
datatype, it will throw an exception
2. Passing Correct Value and
getting the result
Conclusion
Now,
whenever exception occurred in any of the class method’s, it will get caught in the “ProvideFault” method. Hope
this article gives an idea on how an exception can handle globally. Happy
Learning! |