Question

Using WCF in a RESTful way seems great. I’m a big fan of the big guns like simplicity and flexibility, but I also love the way the Urls end up looking. What can I say, I’m a programmer.

The simple API for retrieving and editing resources is matched by an almost equally simple set of possible error responses, and I can’t help feeling that to keep to a “pure” RESTful approach I may be cutting my nose off to spite by face, or more specifically, the nose of my web service consumers. I could be wrong, but there doesn’t seem to be very many Http error codes that I can use, and no ways to pass back a custom error message.

To clarify, I am talking about proper exceptional errors and not expected errors. I want to actually communicate a problem to the user to help them identify what they need to do to correct it.

Possible options I am considering...

  1. Just use the Http error codes – This seem like it would be too restrictive in what I am able to express, and won’t allow me to supply a custom message. Please(!) correct me if I am wrong.

  2. Always return Http Success but return custom error objects – Obviously the most flexible but certainly not the most RESTful.

I would really appreciate it if anyone could share some real world experience of this particular problem.


Update

Thanks for the suggestion of using the StatusDescription property of the OutgoingWebResponseContext object. It seemed at first to be something that I could use.

I have come to the conclusion that my second option above is not for me. I want to stick to the what Http can give me.

I am having problems getting it to work, however. Regardless of the value I supply for this property, it doesn’t get returned in the response.

My service method looks like this

public MyType GetMyTypes(string criteria)
{
    try
    {
        return GetMyTypes();
    }
    catch (Exception ex)
    {
        OutgoingWebResponseContext response = WebOperationContext.Current.OutgoingResponse;
        response.StatusCode = HttpStatusCode.Forbidden;
        response.StatusDescription = "A Big fat error occurred";
        return null;
    }
}

And here is the raw response message. There is no mention of the custom message...

HTTP/1.1 403 Forbidden
Server: ASP.NET Development Server/9.0.0.0
Date: Wed, 07 Jan 2009 14:01:20 GMT
X-AspNet-Version: 2.0.50727
Cache-Control: private
Content-Length: 0
Connection: Close

It's not as if I just need to access the correct property on the client. The information is simply not being sent across the link.

What does this StatusDescription property actually do?


Update

I never did find out how to set the StatusDescription property. I ended up not including any error message at all, and going solely with the Http status codes. I have chosen to expose both Soap and Restful endpoints for my services, and so clients can choose which they prefer to use – the simple Restful messages or the relatively richer Soap messages.

Was it helpful?

Solution

Send the proper response code and you can supply the custom error message in the body of the response.

OTHER TIPS

With .net 4, throw a WebFaultException<T>(T errorDetail, HttpResponseCodecode)

Here you set your response type to another object type, which makes sense, and also you set the ResponseCode that you want.

The errorDetail must be serializable

http://blogs.msdn.com/b/endpoint/archive/2010/01/21/error-handling-in-wcf-webhttp-services-with-webfaultexception.aspx

I add the error code both as above (in the status description) and in the body of the returned page in my REST services as:

OutgoingWebResponseContext response = WebOperationContext.Current.OutgoingResponse;
response.StatusCode = HttpStatusCode.Unauthorized;
response.StatusDescription = "You are not authorized.";
HttpContext.Current.Response.Write("You are not authorized.");
return null;

See this thread for a similar question.

In a nutshell I believe you can set the HTTP status code (to one of the error codes), and provide your custom message in the StatusDescription property:

OutgoingWebResponseContext response = WebOperationContext.Current.OutgoingResponse;
response.StatusCode = System.Net.HttpStatusCode.Forbidden;
response.StatusDescription = "Custom";

I don't know much about the prevalence of this technique in the real world unfortunately.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top