I have a very simple 3-tier project. There is a DAL (data access layer) WCF service interacting with a data store; a BLL (business logic layer) WCF service as an intermediary between the DAL service and a client UI, and a Windows Forms client layer.
I declare a DataContract in my DAL service to act as a fault contract:
[DataContract]
public class ValidationFault
{
[DataMember]
public String Message { get; set; }
[DataMember]
public String PropertyName { get; set; }
...
}
My DAL service has an operation decorated with a FaultContract attribute:
[OperationContract]
[FaultContract(typeof(ValidationFault))]
Patient CreatePatient(Patient patient);
The implementation of CreatePatient throws a strongly-typed FaultException like this:
throw new FaultException<ValidationFault>(new ValidationFault("Patient last name cannot be empty.", "LastName"));
My BLL service acts as a client for the DAL service, and a service for the UI layer. In my BLL service I call the CreatePatient method of the DAL service, and if I catch the FaultException fault, I simply want to re-throw it to be handled by the client. The relevant BLL code looks like this:
...
catch (FaultException<ValidationFault>)
{
throw;
}
I can inspect the exception in the BLL and can confirm that it is a strongly-typed FaultException and the Detail section passed from the DAL intact. The BLL method attempting to rethrow the exception is decorated with the same [FaultContract] attribute as the DAL method above.
The UI client, which is a client of the BLL service, tries to handle the exception and log/display the appropriate information. Trouble is, when this fault reaches the client, it is no longer a strongly-typed FaultException, but instead a general FaultException with a null Detail section.
I did find that if instead of just rethrowing the fault in the BLL method, I instead recreate it with the same parameters like this:
catch (FaultException<ValidationFault> valEx)
{
throw new FaultException<ValidationFault>(new ValidationFault(valEx.Detail.Message, valEx.Detail.PropertyName));
}
then it reaches the client as a strongly-typed FaultException as expected.
My question is: why do I need to recreate this exception in the BLL service? Why can't I just pass through the strongly-typed FaultException thrown by the DAL service? I got the code to work but would like to understand what is going on. I imagine it's something that's staring me in the face but I can't for the life of me figure it out.