Handling WCF Faults
I am working on a client that is consuming a WCF service. In various cases, the service simply raises a FaultException with an associated message informing of the reason behind the given fault.
Some of these faults are things that can be handled by our client application, but I'm hesitant to simply try and perform some string matching on the FaultExceptions Message or Reason to determine if it is something we can cater for or not.
I was hoping that the FaultCode on FaultException could be used to identify a sp开发者_JAVA百科ecific type of Fault that we could handle, but it seems that this is purely to identify a handful of SOAP faults. Please correct me if my interpretation of this is incorrect.
I know that it could be that a FaultException could be raised, but I feel it is unrealistic to expect that a new type should be created for each reason behind a fault.
How do you handle this situation. As a contrived example. Consider a service that provides the following methods;
RecordDetails GetRecordById(string id)
void Add(RecordDetails record)
void Update(RecordDetailsUpdateRequest rdur)
Now in the example above, if you call GetRecordById with an id that doesn't exist, you receive a FaultException with a Message stating "Record cannot be found". Similarly, if you call Add for a record that already exists, or Update for a record that doesn't exist, you simply get a FaultException with a Message/Reason detailing the reason for failure. I need to know if a record exists or not to determine whether I should update or insert. As I mentioned, I'm hesitant to simply match on strings as I have no control over whether they will remain the same or not.
What would you expect in this situation (a type associated with the FaultException detailing RecordNotFoundException etc) or some generic type associated with FaultException that defines specific details relating to the error. For example, a RecordOperationExcpetion class with members Code (a constant or enum identifier of the reason for failure), along with a user friendly message.
At least this way, I could identify the error cause without having to resort to string matching.
Your thoughts are appreciated.
I would go with what you said above - a type associated with the FaultException. You can create any number of classes represented as a DataContract to handle various faults, and then assign them to the WCF Service operations.
[DataContract]
public class RecordOperationException
{
private int code;
private string message;
[DataMember]
public int Code
{
get
{
return code;
}
set
{
code = value;
}
}
[DataMember]
public string Message
{
get
{
return message;
}
set
{
message = value;
}
}
}
Then you can assign the this class as a FaultException:
[OperationContract]
[FaultContract(typeof(RecordOperationException))]
RecordDetails GetRecordById(string id)
[OperationContract]
[FaultContract(typeof(RecordOperationException))]
void Add(RecordDetails record)
[OperationContract]
[FaultContract(typeof(RecordOperationException))]
void Update(RecordDetailsUpdateRequest rdur)
You can then throw the appropriate FaultException in your methods, as desired.
This will eliminate the need to compare strings (which is a good idea, IMO).
I always use FaultExceptions and advertise them as part of the OperationContract, as your code does.
However, I think that there is more to it than this.
We all know that separation of concerns is a good thing, and the way you can achieve this with your services is by created classes that implement IErrorHandler.
These can then be used with your class and your error handling can be separated from your logic, making a cleaner way to do this. It also means that you don't have to repeat identical blocks all over your code.
This can be used with the generic FaultException as well.
A good resource is: http://msdn.microsoft.com/en-us/library/system.servicemodel.dispatcher.ierrorhandler.aspx
精彩评论