Home > C#, REST, WCF > WCF REST tip 2: WebFaultException

WCF REST tip 2: WebFaultException

Introduction

SOAP supports propagating exceptions from the service to the client. This is called “faults” and in WCF this is represented by the FaultException class. Exceptions in REST services are represented by a HTTP status code >= 400. Not a lot of people seem to be aware that WCF supports setting HTTP status error codes by throwing a WebFaultException. Most people doing REST in WCF seem to use the StatusCode property of the OutgoingResponse object that can be accessed from the WebOperationContext.

Because the WebFaultException derives from the regular FaultException, it has the advantage that it results in service implementations that can use SOAP based bindings or HTTP based bindings by just changing the web.config or app.config. Just like the regular FaultException, the WebFaultException exists in two versions: a non generic version and a generic version. The non generic version only supports setting the HTTP status code, while the generic version allows to specify a DataContract class that should be send to the client.

Demo WCF service

We will create a small sample WCF service to show usage of the WebFaultException class. The WCF service will always return a HTTP 401 status code along with some more detailed information about the error in JSON format.

The detail for the WebFaultException is very simple, it consists of 2 properties: a reason field and a detailed information field.

namespace JsonErrorMessage.Service
{
    [DataContract]
    public class ErrorData
    {
        public ErrorData(string reason, string detailedInformation)
        {
            Reason = reason;
            DetailedInformation = detailedInformation;
        }

        [DataMember]
        public string Reason { get; private set; }

        [DataMember]
        public string DetailedInformation { get; private set; }
    }
}

The interface of the service is very simple; it consist of only one method:

namespace JsonErrorMessage.Service
{
    [ServiceContract]
    public interface IHelloService
    {
        [WebGet(ResponseFormat = WebMessageFormat.Json)]
        [OperationContract]
        void Hello();
    }
}

The implementation of the service is of course very simple:

namespace JsonErrorMessage.Service
{
    public class HelloService : IHelloService
    {
        public void Hello()
        {
            ErrorData errorData = new ErrorData("You are not allowed to access this service.",
                "We don't allow anybody to access this service.");

            throw new WebFaultException<ErrorData>(errorData,
                HttpStatusCode.Unauthorized);
        }
    }
}

And finally the following configuration needs to be added into the web.config or app.config file:

<system.serviceModel>
  <services>
    <service name="JsonErrorMessage.Service.HelloService">
      <endpoint address=""
                binding="webHttpBinding"
                contract="JsonErrorMessage.Service.IHelloService" />
    </service>
  </services>
</system.serviceModel>

Testing the demo WCF service

I will use Fiddler to test the implementation of the WCF service. Fiddler is a free tool to debug HTTP traffic and I highly recommend using it.

Fiddler has a request builder that allows creating HTTP requests very easily:

Fiddler Request Builder

When we execute this HTTP request we get the following result back:

Response Unauthorized JSon

The server returned a 401 error code and the body is our DataContract in JSON format. This is the result that we wanted.

Advertisements
Categories: C#, REST, WCF
  1. rolo
    September 14, 2011 at 19:20

    I tried to follow the example you provided and fiddler throws an exception that the response header excepted a content length of a certain type but the server return a different value.

    The actual error message is:

    Fiddler has detected a protocol violation in session #276.
    Content-Length mismatch: Response Header indicated 82 bytes, but server sent 306 bytes.

    • pieterderycke
      September 14, 2011 at 20:03

      This is not caused by the WebFaultException.

      Some questions:
      Are you using intermediary proxy servers or routers? Because they could be the cause of the error.
      Are you using the latest version of Fiddler?

      Regards,
      Pieter

      • Jeremy
        October 29, 2015 at 19:43

        Pieter, we are experiencing the same error. Can you elaborate on how the proxy servers can cause this issue?

  2. Taylor
    February 1, 2012 at 13:48

    I tried to follow the example in my code as well, however my output from fiddler just shows this:

    HTTP/1.1 400 Bad Request
    Content-Length: 24
    Content-Type: application/json
    Server: Microsoft-IIS/7.5
    X-Powered-By: ASP.NET
    Date: Wed, 01 Feb 2012 12:45:11 GMT

    {“Detail”:”Bad Request”}

    I even tried changing the WebProtocolException to just do this and still had the same result:

    throw new WebFaultException(“hello world”, System.Net.HttpStatusCode.BadRequest);

    Any ideas?

  3. October 19, 2012 at 11:56

    Doesn’t work with HTTPS for me, worked fine in HTTP to a javascript client

    • pieterderycke
      October 19, 2012 at 13:49

      I would recommend to inspect the network traffic with Fiddler to see if everything is occurring correctly over the wire. Fiddler can as a proxy to intercept HTTPS traffic.

  4. Felix
    December 27, 2012 at 17:16

    Okay, I am a bit baffled…

    I copied the code into a new solution to try it out but I cannot seem to get it to work. The response I get through Fiddler is:

    ///////////////////////////////////////////////
    HTTP/1.1 500 Internal Server Error
    Server: ASP.NET Development Server/10.0.0.0
    Date: Thu, 27 Dec 2012 15:11:36 GMT
    X-AspNet-Version: 4.0.30319
    jsonerror: true
    Content-Length: 88
    Cache-Control: private
    Content-Type: application/json; charset=utf-8
    Connection: Close

    {“ExceptionDetail”:null,”ExceptionType”:null,”Message”:”Unauthorized”,”StackTrace”:null}
    ///////////////////////////////////////////////

    Which isn’t anywhere near as cool as getting actual details as shown in the example. Seems like it should be easy and “just work” but I must be not getting something correct.

    I am using Web Developer Express 2010 if it matters.

    regards,

  5. KCornwell
    April 1, 2014 at 17:20

    I only get back a 500 status code with the ErrorData sent as XML. I have triple checked everything. Any suggestions?

    • pieterderycke
      April 2, 2014 at 09:52

      what does the error data say? Also check the event viewer for more information about the error.

  6. KCornwell
    April 4, 2014 at 17:05

    I figured it out. The faultExceptionEnabled has to be false in the web.config in the Thanks anyway!

  7. Alex
    September 27, 2014 at 06:26

    Hello Everyone,
    This solution works fine in Fiddler but when I consume this rest service in windows application I cant get the actual exception using this WebFaultException

  1. July 10, 2011 at 02:10

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: