I have been getting my hands Dirty in WCF. Now one of the question which comes to my mind is regarding Fault Contracts in WCF.
I would like to know why we would be needing it. Consider a Sample Application where I am adding 2 Numbers.
So in the Response I have like 2 Fields
Result - Success/Error
Error - Error Details (Code + Text)
Now if my WCF service had any Exception I can catch it in the catch block and assign values to Response object
Result - Success/Error
Error - Error Details (Code + Text)
So where does Fault Contract come into the picture?
What you are doing in your example is you're indicating to the caller that an error has occurred via a "return code". Fault Contracts represent a different approach to doing this: exceptions.
There are many reasons why exceptions are considered better than return codes. Read this for example: Which, and why, do you prefer Exceptions or Return codes? . This is why WCF's architects chose to provide the Fault Contract mechanism, rather than implement the same functionality via return codes.
In your case the Fault Contract approach would mandate that you shouldn't return a response object. You should simply return an int. If anything exceptional happens that prevents you from returning the int, your code would throw a strongly typed Fault indicating to the caller what went wrong and how to, possibly, overcome it.
This is a old question, but I still wish to post some answers for future readers.
Found this website http://www.c-sharpcorner.com/UploadFile/aravindbenator/wcf-exception-handling-best-ways/.
The Author said, if we do not use Fault Contract, the response data (from service to client) will include some sensitive data.
If we do not have Fault Contract, in WCF app.config or web.config, and we still want Fault Exceptions or Web Fault Exceptions, we will set as:
<serviceDebug includeExceptionDetailInFaults="true" />, however, if we set <serviceDebug includeExceptionDetailInFaults="false" />, we must have Fault Contract above service operations.
Related
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.
I am thinking in use some exceptions to from service to client.
I am thinking for example in this case. The client try to insert a register in the database. This register has a value for e filed that exists in the database, and how it has a unique constraint, when I do the savechanges I get an updateException.
I am thinking to use exceptions (faultException) to warn to client of the error, and use a custom class to send to the client the actual data of the register, so in this way the client does not to make other query for the register.
However, in this link, it says that exceptions only should be used in development, no in production, so, without exceptions, how could I do what I want to do?
Perhaps I could use a custom class, that have one list property for each type of entities, and a property bool, that indicates if the operation is right or wrong, other property with an arbitrary code to indicate the type of error... etc. This is a good alternative?
In summary, really is better avoid exceptions in production? how I could communicate to the client errors from the service?
You have 2 options:
Throw exceptions and return WCF faults
Attach error information to you return objects
I personally favour throwing exceptions and returning WCF faults. I dont like the idea of attaching error information to return objects, I feel it violoates object oriented principals. For example a field called 'ErrorCode' has no place on a 'CustomerAddress' object.
I believe that if exceptional circustances arise, then an exception should be thrown. This will also simplfy your code as you wont have to wrap everything in try catch blocks in order to attach error information to your return object. Although you may want to catch unexpected exceptions and then throw a more appropriate exception with a more useful message.
when calling a state changing service e.g.
void SaveCustomer(Customer customer)
the following may happen
the parameters are invalid
an exception occurs
authorisation is not successful
a business rule(s) is violated
everything is ok
For conditions 1-3 I think the service should return an appropriate exception
For #4 I also think the service should return an exception but some believe it should return an object that reflects the success or otherwise of the call (a response object).
In our case a business rule violation is an opportunity for an end user to choose an alternative action. I think a custom exception that lists error codes can be parsed by a client and localised. A response object can do the same but in a more strongly typed way.
With a response object we need to cater for a path back up the stack to the service (if(ok) etc) and we can't rely on an exception unwiniding a transaction.
Is either of these options an anti-pattern?
There is also third approach not mentioned by your listing. The approach is called expected exception. Request-response operations in web services offers definition of three types of messages:
Input = request. Can be defined only once for each operation.
Output = successful response. Can be defined only once for each operation.
Fault = expected unsuccessful response. You can have zero or more faults defined for each operation.
When using faults you tell client that the operation can fail due to some well defined reason. For example incomplete customer definition and client can handle this fault in different way than common unexpected SOAP fault.
In WCF expected faults are handled through FaultContract and generic FaultException<>. Check this article and its subarticles for introduction to fault handling.
The implementation of error handling is mostly up to you. Returning custom object is especially helpful in complex scenarios where the operation can succeed only partially and you must report both success and parts which failed.
I'm not sure if there's a best practice for Response Message in WCF. Could anyone please guide me to right direction please?
I've a BlaResponse Object with following attributes:
1. dateTime
2. sucessfailureMessage.
is there anything else I need to add e.g. number of errors, details of errors. Number of success correlationID etc etc?
Thank you in advance.
Why do you have such attributes. You must have some real requirement for introducing these parameters in your response - for example response grouping both successful and failed operations. If your response is just for single operation you should get rid of that and use exceptions for propagating faults.
WCF has very big support for typed exceptions - FaultContracts. You can create special FaultContract type for any expected exception and throw it with typed FaultException. Client can catch each expected exception separately and handle it.
It is generally considered good practice to hide technical details of errors, or any information that discloses details about the server / architecture from the clients (unless you are debugging of course), as this might compromise your security.
It really depends what you are doing, so I don't think I can say what additional info you might need without more information about your implementation. Even the standard Fault Contract is pretty much just a wrapper for your own custom data.
I am working on a project that is using NetTcp bindings for talking to some WCF services. When first starting out we took a bad practice example from another application that made WCF calls by using the following:
EntityObject sample = new ServiceProxy().GetEntity();
That worked great until we realized WCF was holding onto the connections even though the aspx page had been sent to the client (which I naively assumed would clean up any connections). While the connections were held on causing things to eventually slow down, ELMAH logged any errors and sent us full stack traces. To resolve the performance issues we changed to this:
using (ServiceProxy proxy = new ServiceProxy())
{
sample = proxy.GetEntity();
}
This made performance rock comparatively. The downside to this method is whenever an error is received on the proxy the only thing ELMAH can catch is that the channel is now faulted. We then have to dig through logs (the WCF ones setup with sharedListeners in ) to figure out what happened and if it's a serialization error the odds of actually find it become much lower, despite the listeners being setup on both client and server. I've explored the IErrorHandler interface and am going to add support for it to our services, but I was wondering if there are other ways to get detailed errors out of WCF instead of it just saying it faulted with no real information as to why it faulted. This would be especially beneficial if it dies on serializing the object that it could tell us WHY it couldn't serialize.
I think if you call Close() explicitly on the proxy, and put that in a try-catch, you'll get what you want.
See especially this sample:
http://msdn.microsoft.com/en-us/library/aa355056.aspx
Well, you can tell the WCF servive to send back more information than just "something bad happened" by using the serviceDebug behavior.
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="ExceptionDetails">
<serviceDebug includeExceptionDetailInFaults="True" />
</behavior>
</serviceBehaviors>
</behaviors>
This is OK as long as it's a dev/test environment, or an in-house app. But really, service error should be caught (and logged) on the server side - you're on the right path with the IErrorHandler interface.
The client needs to handle client-side exceptions, like TimeoutException and CommunicationException to deal with security exceptions or networks going down and such. Just standard .NET exception handling, really.
Also, the using() is a good idea in general - but not necessarily here, since you could encounter an exception when the ServiceProxy is being disposed of (at the end of the using() {} block), and that won't be caught in this case. You might just need to use a try {...} catch {...} finally {...} block for your service proxies instead.
Marc