Silverlight 3 and WCF Faults

On  a previous project that utilised WCF and Silverlight 2, I began implementing an error handling strategy that was going to rely on certain FaultExceptions being propagated to the Silverlight client. Well it turned out that Silverlight 2 does not support FaultExceptions so that was not going to fly and a custom solution was built.

Well Silverlight 3 does change this to some degree. Silverlight 3 now supports to the notion of Fault Contracts and FaultExceptions. In your Silverlight client code, if I have a WCF service called ThrowExceptionMethod (which as you may have guessed throws a FaultException) you can do something like this:

First wire up the service call:

private void Button_Click_1(object sender, RoutedEventArgs e)
    TestRef.TestServiceClient client = new TestSilverlightApplication3.TestRef.TestServiceClient();
    client.ThrowExceptionMethodCompleted += new EventHandler<System.ComponentModel.AsyncCompletedEventArgs>(client_ThrowExceptionMethodCompleted);

Then handle any error situation in the completed event:

void client_ThrowExceptionMethodCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
    if (e.Error == null)
        MessageBox.Show("Call sucessfull");
        string msg;
        FaultException<ExceptionDetail> fex = e.Error as FaultException<ExceptionDetail>;
        if (fex != null)
            msg = string.Format("Fault Exception recevied. Reason: {0}, Message: {1}", fex.Reason, e.Error.Message);
            msg = string.Format("Error recevied of type: {0}, Message: {1}",e.Error.GetType(),e.Error.Message);

Here you can see that we test the ‘e.Error’ property to see if its an exception of type FaultException, otherwise the error will flow through generally as a CommunicationException as per normal WCF behaviour.

That all sounds easy, however you still need to tell the WCF service (or more specifically WCF itself) to return the fault using a HTTP status code of 200 (OK) instead of a HTTP status code of 500 (server error) which is the default. If you don’t do this, then the error will always come through as a CommunicationException .

You need a little bit of code and configuration for this. First you need to define a custom behaviour like so:

public class SilverlightFaultBehavior : BehaviorExtensionElement, IEndpointBehavior
        public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
            SilverlightFaultMessageInspector inspector = new SilverlightFaultMessageInspector();

        public class SilverlightFaultMessageInspector : IDispatchMessageInspector
            public void BeforeSendReply(ref Message reply, object correlationState)
                if (reply.IsFault)
                    HttpResponseMessageProperty property = new HttpResponseMessageProperty();

                    // Here the response code is changed to 200.
                    property.StatusCode = System.Net.HttpStatusCode.OK;
                    reply.Properties[HttpResponseMessageProperty.Name] = property;
            public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
                // Do nothing to the incoming message.
                return null;

        // The following methods are stubs and not relevant. 
        public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
        public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
        public void Validate(ServiceEndpoint endpoint)
        public override System.Type BehaviorType
            get { return typeof(SilverlightFaultBehavior); }
        protected override object CreateBehavior()
            return new SilverlightFaultBehavior();

Then some config:

        <add name=”silverlightFaults” 
          <behavior name=”SilverlightFaultBehavior”>
        <service name=”Calculator.Web.Service”>
            <endpoint address=”” 
                      behaviorConfiguration=”SilverlightFaultBehavior” />

So, its still not quite there yet, but its better. It would be nice if this status code behaviour were part of the default Silverlight service template and that it was a provided behaviour, rather than a roll your own custom one.

Note: The custom behaviour, as well as more information on this subject, can and was taken from this article here.


Comments have been disabled for this content.