Silverlight and FaultExceptions

Earlier today, I blogged about a reusable behavior extension to make debugging Silverlight apps a little easier. I wrote most of that article months ago and in the meantime I've added a second behavior extension to support Silverlight software development. I included it with the download, but some explanation about its purpose might be in order.

A proper web service will provide the consumer with a useful error message when something unexpected happens, or when the client sends requests that are invalid for whatever reason. The usual way of going about this is by throwing a FaultException of some kind.

When an exception of any kind is thrown by the web service, it will respond to the client with a HTTP 500 status code (internal server error). This is fine for .NET clients, but it is a problem for Silverlight. Any HTTP requests from an in-browser Silverlight application are in fact made by the browser. When it sees the HTTP 500 status code, it will not send the full response body back to the Silverlight plugin. In fact, it will tell Silverlight that a 404 error (not found) occurred. Silverlight will throw a CommunicationException that reflects this, not very useful.

This behavior extension provides a simple solution. It will change the HTTP 500 status code to a HTTP 200 status code on the server side. The browser will pass the full response body to Silverlight, where the WCF implementation will raise the appropriate exception.

The implementation is similar to my other behavior extension, so I'll try to make this short.

public class SilverlightFaultBehavior : BehaviorExtensionElement, IEndpointBehavior
{
    void IEndpointBehavior.ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
    {
        endpointDispatcher.DispatchRuntime.MessageInspectors.Add(
            new ServiceFaultMessageInspector());
    }

    // Some uninteresting method implementations omitted
}

We're adding a so called message inspector, which allows us to modify in- or outbound messages by implementing the IDispatchMessageInspector interface.

In this case, we're only interested in outbound messages. We only need a minimal amount of code to change the status code:


internal class ServiceFaultMessageInspector : IDispatchMessageInspector
{
    public void BeforeSendReply(ref Message reply, object correlationState)
    {
        if (reply.IsFault)
        {
            reply.Properties[HttpResponseMessageProperty.Name] =
                new HttpResponseMessageProperty()
                {
                    StatusCode = System.Net.HttpStatusCode.OK
                };
        }
    }

    // AfterReceiveRequest does nothing but return null
}

That's pretty much it. A full implementation, sample application and a short description about how to configure a service to use this behavior extension is available in the download below.

Files:

Add comment

Loading