The Exception handling application block also provides a handler to shield exceptions for Windows Communication Foundation (WCF) services. It is very important to implement an Exception Shielding pattern at service boundary level and this handler makes it very easy to prevent any sensitive information crossing the service boundary. This is implemented as part of the Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.WCF
assembly, which needs to be referenced to leverage the functionality. We have to create a fault contract for our WCF service, configure the exception handling policy to use the fault contract exception handler, and map the created fault contract type.
Imagine we have a WCF service called BlogService
and we want to prevent all original exceptions from being thrown to the service consumer. We also want to replace such exceptions with a generic fault contract providing a generic error message and an error code. In order to satisfy such a requirement, we will implement a fault contract called GenericFaultContract
and configure the Exception Policy to replace all exceptions with an instance of GenericFaultContract.
We will create a simple fault contract to hold the error code and the message. A simple GenericFaultContract
class is given next. This fault contract will be used to configure the exception handlers section mapped to an exception type.
The following code snippet shows the GenericFaultContract
class:
using System; using System.Runtime.Serialization; namespace EntLibBook.ExceptionHandling.ServiceLayer { [DataContract] public class GenericFaultContract { [DataMember] public Guid FaultID { get; set; } [DataMember] public string FaultMessage { get; set; } } }
As we have the fault contract ready, we will use the configuration editor to edit the WCF service configuration file and add a BlogServicePolicy policy that handles all exceptions with a post-handling action to throw new exception.
The following screenshot shows the Exception Handling Settings with a configured policy named BlogServicePolicy and exception type as All Exceptions:
Alright, now we have the exception policy and type in place, let us add the fault contract exception handler and configure it to use the GenericFaultContract
class. The following screenshot shows the configured handler called Fault Contract Exception Handler.
There are two important things to notice in the handler configuration. The exception message contains a token {handlingInstanceID}, which is replaced by a Guid
generated by the application block. This Guid
can be very useful if the exceptions are logged, since the support staff can look into the configured log store for more information on what went wrong using the handling instance identifier. Another important aspect in the configuration is the property mappings; we are mapping the tokens to the property of our GenericFaultContract
class. The generated fault contract will have both the properties populated based on the configured tokens.
Now the final task in the WCF service is to apply the ExceptionShielding
attribute either to the ServiceContract
interface or to the class. The ExceptionShielding
attribute instructs the Exception Handling Application Block to handle exceptions based on the configured exception policy.
The following code snippet shows the ExceptionShielding
attribute in action:
using EntLibBook.ExceptionHandling.BusinessEntities; using Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.WCF; namespace EntLibBook.ExceptionHandling.ServiceLayer { [ExceptionShielding("BlogServicePolicy")] public class BlogService : IBlogService { public BlogPost GetBlogPost(int id) { // Code to get Blog Post return null; } } }
The WCF Service consumer will be able to handle the Fault Exception by specifying the GenericFaultContract
type and will be able to access the FaultID
and FaultMessage
properties.
The following code snippet shows the catch
block with the FaultException
as GenericFaultContract
type:
try { ServiceProxy.BlogServiceClient client = new ServiceProxy.BlogServiceClient(); client.GetBlogPost(1); } catch (FaultException<ServiceProxy.GenericFaultContract> faultException) { // Note: Just to demonstrate this scenario we are assigning the property // We can use Exception Handling Application Block to manage the exception here as well. // Retrieving FaultID and FaultMessage Guid handlingInstanceID = faultException.Detail.FaultID; string faultMessage = faultException.Detail.FaultMessage; }
Whenever the call to GetBlogPost
throws an exception, the client code will receive a FaultException
of GenericFaultContract
type, which will be handled by the client code as part of the structured exception handling.
3.138.106.233