Deborah's Developer MindScape






         Tips and Techniques for Web and .NET developers.

September 25, 2012

Adding Simple Exception Handling to your Web API Service

Filed under: ASP.NET,ASP.NET Web API,C#,VB.NET @ 1:47 am

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).

image

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.

image 

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.

image

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:

image

Notice that the Result is now a 404: Not found. Looking at the detail, there is no body to display.

image

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.

image

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:

image

Use the HttpResponseException whenever you want to control the exception information passed to your ASP.NET Web service clients.

Enjoy!

RSS feed for comments on this post. TrackBack URI

Leave a comment

© 2019 Deborah's Developer MindScape   Provided by WPMU DEV -The WordPress Experts   Hosted by Microsoft MVPs