Microsoft’s ASP.Net Web API 2.2 allows you to easily create REST style APIs on an IIS website. Microsoft has some great documentation on how to get started with it, so I won’t rehash that here. Instead, I’m going to go a little deeper into some powerful features that can be used with Web API.
- Part 1 - Customizing auto-generated documentation
- Part 2 - HTTP Response Codes
- Part 3 - HTTP Error Codes from Exceptions (this article)
- Part 4 - OData URL Query Options
- Part 5 - DTO Transformations and Automapper
- Part 6 - Testing with EF Rollbacks across HTTP
In the last post, we looked at how you can specify HTTP Response codes to return from your API controller when everything is working properly. However, sometimes a problem will occur deep inside your code. Continuing down the REST path, when problems occur, you should use the semantics of HTTP by returning an HTTP status code that reflects the error. When problems occur in your code, exceptions are typically thrown. This week we will be looking at how we can specify the HTTP Response code and content to return depending on the exception that is thrown.
Feb 10, 2016 Update - Fixed bug in second code block
This is a matter of style, but the first thing that I like to do is to create a custom exception, so that I know that what I’m doing will only apply when I specifically raise my custom exception.
public class OrderTotalWrongException : Exception
Next, create an ExceptionFilterAttribute. An ExceptionFilterAttribute allows you to handle a exception that is not handled by a controller action. Please note that this attribute can be used with multiple exception types you want to use by adding an ‘
else‘ statement after the first ‘
public class OrderingExceptionResponseAttribute : ExceptionFilterAttribute
Let’s dig into this code. We’re creating an Exception Filter. This is an attribute that, when applied to a controller or action method, will give this code a chance to handle unexpected exceptions.
We only care about the specific custom exception I created earlier. When it is thrown, we create a
HttpResponseMessage - this is the response that will be sent to the client that called our API. Our normal controller and action method can’t help us, because they weren’t able to handle this exception, so it’s up to us to construct a meaningful response. We set the HTTP Status Code - in this case we’re using HTTP 409, Conflict, because there is a conflict with the total amount of the order. http://httpstatus.es has a helpful listing of the available HTTP status codes. I then add some textual description of the error that is built from the properties on the custom Exception type we created earlier, and we set the response on the context object so that the
HttpResponseMessage we created will be returned to the client.
Now you have created the attribute that can be added to any controller or action method. Next, you can either manually add it to the controllers you want to add it to, or you can add it to all controllers, all actions, by opening up App_Start\WebApiConfig.cs and adding this line:
config.Filters.Add(new OrderingExceptionResponseAttribute ());
You have now wired up a global exception handler that will kick in and provide a specific HTTP response when an action is called, the custom exception is thrown, and you don’t handle the exception in the action. The nice part about this is that your actions and anything that your actions call don’t need to know that this is in place. All they have to do is throw your custom exception.