How to applying WCF Exception shielding to an existing wcf service without updating the clients.

Topics: Exception Handling Application Block
Feb 8, 2012 at 12:19 PM
Edited Feb 8, 2012 at 12:35 PM

Hi.

I’m going to implement exception handling on our wcf services using exception shielding. Today the operation contracts are not decorated by a FaultContract attribute, nor is the implementation of service contract interface decorated by a ExceptionShielding attribute.

Our service is already in use by numerous customers, so I cannot change the contract/wsdl easily and force our customers to update the service reference.

I created a small project to test if WcfExceptionShielding will break the contract/change the wsdl. The service have one method.

public decimal Devide(decimal number1, decimal number2)
{        

  return number1/number2;

}

No faultcontracts are added, to simulate the existence of our service to day.

Added one client.

Updated the service with ExceptionShielding attribute, created a FaultContract, added faultcontract attribute to the operation contract.

Created a second client.

Both client have the same code, with the exception of the first catch.

static void Main(string[] args)
                 {
                          try
                          {
                                   using (var client = new TestService.TestServiceClient())
                                   {
                                            var result = client.Devide(1, 0);
                                            Console.WriteLine(result);
                                   }
                          }
			//client2 have catch (FaultException<TestService.MyFaultContract> ex) 
                          catch (FaultException ex)
                          {
                                   Console.Write(ex.ToString());
                          }
                          catch (Exception ex)
                          {
                                   Console.Write(ex.ToString());
                          }
                          Console.ReadLine();
                 }

The results. Client 2 catches the MyFaultContract that shields the DivideByZeroException.

Client 1 catches a MessageSecurityException “No signature message parts were specified for messages with the 'http://tempuri.org/ITestService/DevideMyFaultContractFault' action.”. Clearly the deserialization failure of the faultcontract raised by the wcf exception shielding.

So the million dollar question is, how can I apply WCF Exception shielding to an existing wcf service without updating the clients?

Regards

Frode

 

Feb 8, 2012 at 10:06 PM

So the million dollar question is, how can I apply WCF Exception shielding to an existing wcf service without updating the clients?

I don't think that you can do that.  By adding FaultContracts to a service it is a breaking change for existing clients since there are new fault messages that the clients will not understand.

If you could somehow know who the client was or what version of the interface was invoked you might be able to avoid the ExceptionShielding for legacy clients.  For example: ExceptionShielding would only happen for exceptions of type MyException (which is a new exception type).   That new exception would only be created and thrown for new clients.  The new exception would be mapped to the fault contract.  But that is getting a bit messy.

Probably the easiest way (and standard way) would be expose a new version of the service for new clients.  They both could reference the same implementation but just have slightly different service interfaces.

--
Randy Levy
Enterprise Library support engineer
entlib.support@live.com