Adding Simple Exception Handling to your Web API Service
There is nothing perfect in life, not even an ASP.NET Web API service. The service may not understand the provided parameters, or may not find the requested data, or may have trouble connecting to the database. Whatever the issue, if the service cannot return the desired data it would be nice to instead return an appropriate exception notification.
[See this prior post for an introduction to building an ASP.NET Web API service. The service created in that post is the example service used here.]
The following code is the ASP.NET Web API service controller from the example mentioned above, but with a simple exception.
In C#:
using ACMService.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
namespace ACMService.Controllers
{
public class CustomerController : ApiController
{
// GET api/customer
public IEnumerable<Customer> Get()
{
return Customer.Retrieve();
}
// GET api/customer/5
public Customer Get(int id)
{
List<Customer> customerList = Customer.Retrieve();
Customer customerInstance = customerList.FirstOrDefault(
c => c.CustomerId == id);
if (customerInstance == null)
{
throw new ApplicationException("Customer not found");
}
return customerInstance;
}
}
}
In VB:
Imports System.Net
Imports System.Net.Http
Imports System.Web.Http
Public Class CustomerVBController
Inherits ApiController
‘ GET api/customerVB
Public Function [Get]() As IEnumerable(Of CustomerVB)
Return CustomerVB.Retrieve()
End Function
‘ GET api/customerVB/2
Public Function [Get](id As Integer) As CustomerVB
Dim customerList = CustomerVB.Retrieve()
Dim customerInstance = customerList.FirstOrDefault(
Function(c) c.CustomerId = id)
If customerInstance Is Nothing Then
Throw New ApplicationException("Customer not found")
End If
Return customerInstance
End Function
End Class
Run the application. Press F12 to launch the F12 developer tools. Select the Network tab and the Start capturing button. [For more information on the F12 tools, see this prior post.]
Then add to the address bar the following: api/customer/10 (api/customerVB/10 in the VB example).
The F12 window displays the request with a result of 500: Internal Server Error. When an exception is thrown in a Web API controller, by default the response is returned with a status code of 500.
Select the request and click the Go to detailed view button to see the details. Click on the Response body tab to see the error message as a JSON string.
Notice that it provides the full stack trace. This can be helpful when debugging the application, but may provide more information than you want to share when your service goes live.
As an alternative, you could use the provided HttpResponseException. By default, this has a header but no content. And instead of always returning a 500 status code, it returns the code you specify.
Change the exception thrown in the example above to instead throw a new HttpResponseException.
In C#:
throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.NotFound));
In VB:
throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.NotFound))
Repeat the steps above to look at the result with the F12 developer tool:
Notice that the Result is now a 404: Not found. Looking at the detail, there is no body to display.
But what if you do want to provide more information, such as a more detailed message? The HttpResponseException provides properties that allow you to specify more information.
The Content property allows you to provide a response body.
The ReasonPhrase property is a textual description of the status code. You can add any text you would like, such as "Customer Id not found". This may be more useful to the client applications than getting a 404.
Change the exception in the prior example as shown below.
In C#:
throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.NotFound)
{
Content = new StringContent("Could not locate a customer with id: "
+ id),
ReasonPhrase = "Customer Id not found"
});
In VB:
Throw New HttpResponseException(New HttpResponseMessage(HttpStatusCode.NotFound) With
{
.Content = New StringContent("Could not locate a customer with id: " &
id),
.ReasonPhrase = "Customer Id not found"
})
Repeating the F12 process one more time… Notice that the Response Body now includes the information provided in the Content property.
If you developed the JavaScript client as shown in this prior post, you’ll notice that it already has code to handle an exception. The result is shown below:
Use the HttpResponseException whenever you want to control the exception information passed to your ASP.NET Web service clients.
Enjoy!