WCF Web API Plays Nice With ELMAH - A Quick Introduction to WCF Web API HttpErrorHandler

See how WCF Web API Plays Nice With ELMAH. This blog post is a Quick introduction to WCF Web API HttpErrorHandler
2011-11-22 14:09
Tugberk Ugurlu


imageHow many times you face an error message like this one when you are working with WCF? Many times I guess.

On WCF Web API, this is not a big deal on the development stage because Web API runs on core ASP.NET and debugging is not a big deal (maybe it is not a big deal on WCF as well but it always for me, anybody knows a good debugging scenario on WCF, please let me know).

But when you expose your data and your customers starts to consume your service, you will pull your hairs when you see this screen.

WCF Web API has been built extensibility and testability in mind so it is real easy to plug things into the framework. One of the extensibility points is ErrorHandlers and in this quick blog post I will show you how to handle error nicely on WCF Web API.

If you haven’t seen my previous blog post on Introduction to WCF Web API - New REST Face of .NET, I encourage you to check that out. What I do here will be addition to that.

When somebody tells me the words “Error Handling” and “.NET” in the same sentence, I tell him/her ELMAH in response. ELMAH (Error Logging Modules and Handlers) is is an application-wide error logging facility that is completely pluggable. It can be dynamically added to a running ASP.NET web application, or even all ASP.NET web applications on a machine, without any need for re-compilation or re-deployment. These are the official words.

In order to integrate ELMAH with our Web API application, we need to bring down the ELMAH via NuGet as we always do for open source libraries.

Scott Hanselman has a great blog post on how ELMAH gets into your application via NuGet Package Manager. You should check that out if you are interested:

http://www.hanselman.com/blog/IntroducingNuGetPackageManagementForNETAnotherPieceOfTheWebStack.aspx

Open up you PMC and type Install-Package ELMAH:

image

After you install the package successfully, it doesn’t need any extra configuration to work but you would probably want to secure your error logging page. Check it out how on Phil Haack’s blog post: http://haacked.com/archive/2007/07/24/securely-implement-elmah-for-plug-and-play-error-logging.aspx

When you go to http://localhost:{port_number}/elmah.axd, you will see the error list page:

image

I added a new method for PeopleApi in order to be able to reach single person data:

[WebGet(UriTemplate = "{id}")]
public HttpResponseMessage<Person> GetSingle(int id) {

    var person = _repo.GetSingle(id);

    if (person == null) {
        var response = new HttpResponseMessage();
        response.StatusCode = HttpStatusCode.NotFound;
        response.Content = new StringContent("Country not found");
        throw new HttpResponseException(response);
    }

    var personResponse = new HttpResponseMessage<Models.Person>(person);
    personResponse.Content.Headers.Expires = new DateTimeOffset(DateTime.Now.AddHours(6));
    return personResponse;
}

It is a simple method. It returns a single Person data wrapped up inside HttpResponseMessage if there is one and returns 404 if there is no person with the given id value.

imageimage

Let’s send a string value instead of int32 and see what happens:

image

It is an error so ELMAH should have logged this, right? It didn’t because WCF Web API handles exceptions on its own but good news is you can get in there and plug your own stuff into it.

Disclaimer:

I am still a newbie on WCF Web API and learning it day by day. Also, the framework is at the preview stage (not even Alpha) so the things I explain and show might be not entirely the best case scenarios.

In WCF Web API preview 5, you can use the ErrorHandler, which is the recommended way to do error handling. In order to implement your own error handler, your class needs to derived from HttpErrorHandler class. Here is the implementation I use:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web;
using Microsoft.ApplicationServer.Http.Dispatcher;

namespace VeryFirstWcfWebAPI.Handlers {

    public class GlobalErrorHandler : HttpErrorHandler {

        protected override bool OnTryProvideResponse(Exception exception, ref System.Net.Http.HttpResponseMessage message) {

            if(exception != null) // Notify ELMAH
                Elmah.ErrorSignal.FromCurrentContext().Raise(exception);

            message = new HttpResponseMessage {
                StatusCode = HttpStatusCode.InternalServerError
            };

            return true;
        }
    }
}

Pretty straight forward implementation. The last step is to register this handler. We will do that inside the Global.asax file as below:

protected void Application_Start(object sender, EventArgs e) {

    RouteTable.Routes.SetDefaultHttpConfiguration(new Microsoft.ApplicationServer.Http.WebApiConfiguration() { 
        CreateInstance = (serviceType, context, request) => GetKernel().Get(serviceType),
        ErrorHandlers = (handlers, endpoint, description) => handlers.Add(new GlobalErrorHandler())
    });

    RouteTable.Routes.MapServiceRoute<People.PeopleApi>("Api/People");
}

Now, hit your service and cause an error. After that go back to elmah.axd page to see what we got there:

image

image

We totally nailed it! Now, you can configure ELMAH to send you an e-mail when an error occurred or you can log the error inside an XML file, SQL Server Database, wherever you what.

As I said at the end of my previous post, there is so much to cover about WCF Web API. I hope I will blog about it more.

You can find the full code on GitHub: https://github.com/tugberkugurlu/VeryFirstWcfWebAPI



Comments

tomasz kubacki
by tomasz kubacki on Wednesday, Nov 23 2011 11:52:31 +02:00

Just use servicestack.net ( http://www.servicestack.net/ ) it's just way better than wcf- faster easier to use and upcoming release will have profiler.  :) 

Raju Golla
by Raju Golla on Thursday, Nov 24 2011 00:08:16 +02:00

Good one.

I described utilising Enterprise Library: Logging application to log data through WCF Service at

http://weblogs.asp.net/sukumarraju/archive/2011/11/07/configuring-wcf-service-to-utilise-enterprise-library-logging-application-to-log-data-to-database.aspx

Bryant
by Bryant on Thursday, Dec 08 2011 18:37:06 +02:00

Great post- encountered this problem with ELMAH about an hour ago. You saved me a lot of time!

jeffa
by jeffa on Saturday, Dec 31 2011 01:06:06 +02:00

I'm not using nInject (yet)...

In RegisterRoutes of Global.asax.cs I added:  

 

            routes.SetDefaultHttpConfiguration(new WebApiConfiguration() { EnableTestClient = true,
                ErrorHandlers = (handlers, endpoint, description) => handlers.Add(new GloablErrorHandler()) });
Works great! Thanks for the post. Now back to debugging! 

 

Andrew Cohen
by Andrew Cohen on Tuesday, Feb 05 2013 14:52:14 +02:00

Is this still best practice?  I couldn't find the HttpErrorHandler class in the latest WebApi bits.

New Comment