Data contracts also assist in being able to notify clients of exceptions that may occur in a service. Too see how that works, follow these steps:
Listing 3.4. Anticipating a Fault
Because receiving an error message from an attempt to use the operation should be anticipated, as the FaultContract for the operation indicates, the client code is written to handle that possibility. That is accomplished using the Windows Communication Foundation's FaultException<T> generic, which was also used in the code for the service to convey information about an exception to the client. The Detail property of the FaultException<T> generic provides access to an instance of T, which, in this case, is an instance of the SomeError class that the client can interrogate for information about the error that occurred. This approach to handling exceptions provided by the Windows Communication Foundation has multiple virtues. It allows the developers of services to easily define the structure of the error messages that they want to transmit to client programmers. It also allows them to advertise to client programmers which operations of their services might return particular error messages instead of the results they would otherwise expect. The service programmers are able to easily formulate and transmit error messages to clients, and client programmers have a simple syntax, almost exactly like ordinary exception-handling syntax, for receiving and examining error messages. Most important, service programmers get to decide exactly what information about errors that occur in their services they want to have conveyed to clients. However, the design of the Windows Communication Foundation does anticipate the utility, solely in the process of debugging a service, of being able to return to a client complete information about any unanticipated exceptions that might occur within a service. That can be accomplished using the ReturnUnknownExceptionsAsFaults behavior. Behaviors are mechanisms internal to Windows Communication Foundation services or clients. They may be controlled by programmers or administrators. Those behaviors that programmers are expected to want to control are manipulated using attributes. For example, if a programmer knows that a service is thread-safe, the programmer can permit the Windows Communication Foundation to allow multiple threads to access the service concurrently by adding the ServiceBehavior attribute to the service's service type class, and setting the value of the ConcurrencyMode parameter of that attribute to the Multiple value of the ConcurrencyMode enumeration: [ServiceBehavior(ConcurrencyMode=ConcurrencyMode.Multiple)] public class DerivativesCalculator : IServiceViewOfService Behaviors that administrators are expected to want to control can be manipulated in the configuration of a service or client. The ReturnUnknownExceptionsAsFaults behavior is one of those. This configuration of a service will result in any unhandled exceptions being transmitted to the client: <?xml version="1.0" encoding="utf-8" ?> <configuration> <system.serviceModel> <services> <service type= "DerivativesCalculator.DerivativesCalculatorServiceType, DerivativesCalculatorService" behaviorConfiguration="DerivativesCalculatorBehavior"> <endpoint address="" binding="basicHttpBinding" contract= "DerivativesCalculator.IDerivativesCalculator,DerivativesCalculatorService" /> </service> </services> <behaviors> <behavior name="DerivativesCalculatorBehavior" returnUnknownExceptionsAsFaults="true"/> </behaviors> </system.serviceModel> </configuration> To reiterate, this configuration may be very useful for diagnosis in the process of debugging a service, but it is dangerous in debugging, because transmitting all the information about an exception to a client may expose information about the service that could be used to compromise it. |