Is it possible to configure a WCF service client to throw a custom FaultException? - wcf

I was wondering if it was possible to configure a WCF service client to use a custom type instead of FaultException when throwing faults. The custom type would inherit from FaultException, but also have some additional details about the error.
The reason I want to use a custom FaultException is so I can store a GUID from the SOAP Header which is otherwise lost.
I know I could manually catch and rethrow any faults my service client returns, but that's flimsy. I have no way of guaranteeing future developers will do the same.
I've thought about subclassing the generated service client class and putting the error handling in there, but that generates a lot of work whenever the target service changes.
So, is it possible to configure a WCF service client to throw a custom FaultException type for Faults?

You can create your own IErrorHandler implementation:
http://msdn.microsoft.com/en-us/library/system.servicemodel.dispatcher.ierrorhandler.aspx
Override ProvideFault and then do conversion from regular exceptions (including plain FaultException) to your own custom based FaultException<T>, where T is your own type that you can define to include custom properties.
After that, you have to register your implementation of IErrorHandler as service behavior, either in code or in web/app config.

Related

Can I inherit FaultException in WCF to throw custom faults?

Strangely I can't find anything on google for this. When doing regular exception stuff you'd create a MyCustomException : Exception and I assumed the same applied to ExceptionFaults.
When someone calls my service with an invalid api key, I wanted to throw an InvalidApiKeyExceptionFault. I can't seem to find an example online of how to set this up and have the client be able to catch it (presumably an attribute somewhere to include it into the WSDL).
Any suggestions where to look, or am I trying something that's not possible?
You should use FaultException<TDetail> and put your specific information in the serializable TDetail type.
Your service contract should have a fault contract specifying the TDetail type.
This technique enables you to communicate error information in an interoperable way, including to clients that know nothing about .NET exceptions.
If for some reason you don't want to use fault contracts, you could consider using the non-generic FaultException, and communicate additional information about the error in the fault reason and/or fault code / subcode.

Include exception information in return values in WCF

I am implementing an IErrorHandler for a set of WCF services. I configure the WCF services to use this error handler via the configuration file, using a custom behavior.
All methods in all services return a value that is derived from a common base class.
What I want to do is to include information about the error in the return value if the error handler gets called.
Any ideas on how to do this elegantly would be much appreciated.
You just need to create the message manually which complies with your return SOAP data. You can implement your own body writer and use it for the Message.Create function. Here is a good example of how to accomplish what you basically need Simple custom error handler for webHttpBinding in WCF
However if I were you I would choose fault approach when you just return void or some data if everything succeeds and fault message if it fails. Of course if there are no strict requirements to return operation status in the response object or if you are not refactoring an existing system.
Hope it helps.

Turn off WCF SOAP Service for Maintenance and provide friendly message

I'm hosting some SOAP services with WCF. How can I turn off these services via config for the purposes of maintenance, etc., and provide a friendly message to the service consumer with something like "The service you've requested is down for maintenance."?
You would have to have a second service, that offered the same interface, same methods etc., that would all return that friendly message instead of a real result.
That might get a bit trickier when those service methods don't just return a string but a complex data object - where do you put that "friendly" message??
In reality I think this cannot really be done - since your services typically aren't "seen" by actual people, you cannot just put up an app_offline.htm file or anything like that.
Try to have as little downtime as possible, by e.g. setting up your new version of the service on a new port and testing it there, until you're confident enough to switch over.
With WCF, it's mostly an exercise of updating / copying around the appropriate config, so your service should never really be unavailable for any extended period of time (hopefully!).
If you really must, what you could do, is just have a replacement service that will always throw a FaultContract<ServiceDownForMaintenance> - but then all the clients calling your service would have to know about this and they would have to handle this case and present an error or information message. Your service can't really provide that...
How about this: create a custom ServiceBehavior to intercept my incoming requests to the service. Then, have the custom behavior check a user-defined flag in my config file, something like <add key="IsMyServiceUp" value="true" /> and if that value returns as false then throw a ServiceException with my friendly message and HTTP code of 503 - Service Unavailable.
Does that sound reasonable? Then all I have to do is change the flag in my config file to specify where the service is up or down.
Okay, so I've created a new Custom Behavior that implements IOperationBehavior. In the Validate method, I've got
public void Validate(OperationDescription operationDescription)
{
bool isServiceUp = Boolean.Parse(ConfigurationManager.AppSettings["IsOrderServiceUp"].ToString());
if (!isServiceUp)
{
throw new ServiceException(ServiceErrorCode.Generic_Server_Exception,
ServiceErrors.Generic_Server_Exception,
SoapFaultCode.Server);
}
}
The other implemented methods ApplyClientBehavior, ApplyDispatchBehavior and AddBindingParameters are all empty.
I have decorated one of my service operations with [ServiceStatusValidation] which is the class name of my custom behavior.
When I start the service and navigate to the operation with this decoration, I do NOT get the exception I've thrown. SOAP UI shows nothing as returned in the response pane, and my consuming REST facade gives a generic 400 error with The exception message is 'The server did not provide a meaningful reply; this might be caused by a contract mismatch, a premature session shutdown or an internal server error.'.
Any ideas? Should I be doing this logic in one of the other methods that I didn't implement instead of the Validate method?

Should constructors for WCF Services use faults for error handling?

I have a wcf service. The service itself (class that inherits the ServiceContract) has a constructor that sometimes throws exceptions. I want to present the user a message if the service fails. Should I use faults like I would for a service method?
A fault is generally meant to provide error information across service boundaries, and in most cases, a fault is sent as a response to a malformed or invalid request message. Given that, I would say a fault doesn't make sense here.
I agree with the above commenter that a constructor for a service class should avoid throwing exceptions. If your service is sessionful, you may want to consider a design where you do this type of initialization as the result of a specific service operation. This can be done in WCF by marking such a service operation with "IsInitiating = true" in the [OperationContract] attribute. At that point, you would be able to generate a fault and have some hope of it reaching the intended client.

FaultException handling in BizTalk

The FaultContract from my WCF service doesn't have a datacontract members; thus when the service is consumed in BizTalk, the generated schema doesn't show up any members. How do I handle in BizTalk?
While consuming this WCF service from a .NET client, the implementation provides the exception along with Class library ( of data objects) and I catch the fault of that exception type.
I am not sure if this is possible. But to get it to work biztalk must have access to the dll with your data objects. You could try referencing the dll from your biztalk project.
If you are consuming the service from an orchestration you could try the following steps:
Add an XSD representation of your
FaultContract to the project and use
this as message type on your fault
operation.
Add an exception handler block to
the orchestration using this fault
operation as message type
On your two-way WCF SendPort go to
the Messages tab and then on
'Inbound BizTalk Message Body'
change the radio button to Path.
On 'Body path expression' add
something like this:
/* [namespace-uri()='http://myservice.namespace/'] | /* [local-name()='Fault'] /* [local-name()='Detail']/*
These two xpaths separated by a '|' will make the adapter depending on what it receives publish either the correct service reply or the content of the details node which is where the WCF FaultContract is placed. This will allow the disassembler to work when trying to identify the message.
A side effect of this is that you will have a problem catching SOAP-faults in the orchestration but this is solved by creating a schema representation of a SOAP-fault (http://schemas.datacontract.org/2004/07/System.ServiceModel#ExceptionDetail) and use that as a second fault operation.
I have found issue. Our web service return fault XML in lower case. So correct XPath is
/*[local-name()='Fault']/*[local-name()='detail']/*