When we build services, or write any code for that matter, error can occur and we have to cater for those. With SOAP service we gibe a calling application information about the error by returning a SOAP fault. This SOAP fault is just another piece of XML informing the calling application about whatever was wrong. Now the HTTP protocol also contains a way of sending status information back to the client but when using SOAP that is mostly ignored, all we use is a 200 OK or an 500 Internal Server Error error status. And for one returning a 500 Internal Server Error is really a shame if the error is actually a client problem. But there are far more status codes we can use.
When we are building REST service we embrace HTTP and as a result we also embrace all the HTTP status codes, not just 200 and 500. And that doesn’t just mean with errors but also when everything works as expected as there is a whole range of status codes dealing with success.
In general status code are grouped into a few different categories:
A few success status codes:
A few client failure status codes:
A few service failure status codes:
Check here for a complete list of all HTTP status codes.
Using HTTP status codes with the WCF Web API
returning custom HTTP status codes with the WCF Web API is quite easy. Lets start with the following very simple example function:
[WebGet(UriTemplate = "/{id}")]
Book GetBook(int id)
{
var result = _repo.GetBook(id);
return result;
}
If I request the books resource using the URL http://localhost:28330/books/1 I get the following.
That’s just fine and exactly what I would expect. However if I use the URL http://localhost:28330/books/999 to get a book with id 999 which doesn’t exist I see the following:
Not exactly what I want, there is no book found and yet it returns a null book resource.
The fix is quite simple. If we want more control over the response we don’t just return the resource but we return a HttpResponseMessage<T>. Using the HttpResponseMessage<T> we can set all sorts of headers but in this case we are only interested in setting the HttpStatusCode to NotFound if the requested book doesn’t exist.
HttpResponseMessage<Book> GetBook(int id)
HttpResponseMessage<Book> result;
var book = _repo.GetBook(id);
if (book != null)
result = new HttpResponseMessage<Book>(book);
else
result = new HttpResponseMessage<Book>(HttpStatusCode.NotFound);
When we try the same URL again with the new function we get the following result:
Note that Internet Explorer is focused on web pages not books so it tells us that the webpage is not found and the page header contains the actual HttpStatusCode returned, 404 Not Found in this case.
Besides setting the HttpStatusCode instead of a resource in the constructor we can also set it as a property like this:
result.StatusCode = HttpStatusCode.Created;
Just remember that setting a resource, even a null one, will return that to the calling application so in this case where we want to make sure there is no body we have to be very explicit about it.
Enjoy!
www.TheProblemSolver.nl www.dotnetevents.nl