My Adventures in Coding

July 5, 2012

C# – Logging Exceptions with Elmah in an MVC 4 Web API Application

Filed under: .NET,c#,MVC — Brian @ 11:08 pm
Tags: , ,

Recently, after having been away from the .NET world for several years, I have started on a new project where we are building REST APIs using MVC 4. One of the first things we wanted to find out how to do was have all exceptions written to a database, as well as have a web interface from which to view exception details. Fortunately there is a very nice open source project available called Elmah.

When I created my first MVC 4 Web API application using Elmah, I was very rusty with .NET so getting Elmah setup and working took me a little longer than expected. Part of the reason was because the setup required piecing together information from multiple sources, since things have changed a bit in MVC 4. So here is a very simple quick start tutortial to help you get up and running with Elmah. If you would like to learn more about Elmah, the following article gives a good overview: Logging Error Details with ELMAH (C#).

NOTE: If you are using NuGet, you can use the Elmah.MVC NuGet Package to install Elmah, which works great. However, if you are not using NuGet, the following instructions will walk you through the setup.

1. Create a new MVC 4 Web API Project

The following article is useful, if you have never created an MVC 4 Web API application before:
ASP.NET WebAPI: Getting Started with MVC4 and WebAPI

2. Download the latest version of Elmah

You can obtain the latest version of Elmah here. At the time of this post, I am using version 1.2 Service Pack 2.

Unpack the zip file ELMAH-1.2-sp2-bin-x64.zip and add the following dll to your project as a reference:
…\ELMAH-1.2-sp2-bin-x64\bin\net-2.0\Release\Elmah.dll

3. Setup Elmah in your Web.config file

To the configSections part of your Web.config, add an Elmah sectionGroup:

<configSections>
<sectionGroup name="elmah">
      <section name="security" requirePermission="false" type="Elmah.SecuritySectionHandler, Elmah"/>
      <section name="errorLog" requirePermission="false" type="Elmah.ErrorLogSectionHandler, Elmah" />
      <section name="errorMail" requirePermission="false" type="Elmah.ErrorMailSectionHandler, Elmah" />
      <section name="errorFilter" requirePermission="false" type="Elmah.ErrorFilterSectionHandler, Elmah"/>
    </sectionGroup>
…
</configSections>

To log to a Microsoft SQL Server database (In our case we are using SQL Server 2005), add a connection string for Elmah filling in your database server name and the name of your exceptions database:

<connectionStrings>
        <add name="elmah-sql" connectionString="Data Source=MY_DB_HOST;Initial Catalog=MY_EXCEPTIONS_DB_NAME;Integrated Security=SSPI;Connection Timeout=60;Min Pool Size=2;Max Pool Size=20;" providerName="System.Data.SqlClient" />
  </connectionStrings>

Inside the configuration tag add an Elmah section setting the “applicationName” to be some unique string to identify your application:

<configuration>
    <elmah>
        <errorLog type="Elmah.SqlErrorLog, Elmah" connectionStringName="elmah-sql" applicationName="SETMYAPPLICATIONNAME"></errorLog>
        <security allowRemoteAccess="1" />
    </elmah>
    ...
</configuration>

Inside the system.web tag add:

<system.web>
    <httpModules>
      <add name="ErrorLog" type="Elmah.ErrorLogModule, Elmah"/>
    </httpModules>
    <httpHandlers>
      <add verb="POST,GET,HEAD" path="elmah.axd" type="Elmah.ErrorLogPageFactory, Elmah" />
    </httpHandlers>
    ...
</system.web>

In the system.webServer tag add:

<system.webServer>
    <handlers>
      <add name="Elmah" verb="POST,GET,HEAD" path="elmah.axd" type="Elmah.ErrorLogPageFactory, Elmah" />
    </handlers>
    <validation validateIntegratedModeConfiguration="false" />
    <modules runAllManagedModulesForAllRequests="true">
      <add name="ErrorLog" type="Elmah.ErrorLogModule, Elmah"/>
      <add name="ErrorMail" type="Elmah.ErrorMailModule, Elmah" />
      <add name="ErrorFilter" type="Elmah.ErrorFilterModule, Elmah" />
    </modules>
    ...
</system.webServer>

4. Run the Elmah SQL Server database setup script on your Exceptions database

You need to apply the script that creates the Elmah table where exception information will be logged, as well as adds the stored procedure required by the web interface to read exception messages. The script is located in the zip file you downloaded, located at:
…\ELMAH-1.2-sp2-bin-x64\db\SQLServer.sql.

5. Create a custom ExceptionFilterAttribute class

Even though, up to this point we have completed all the required setup for Elmah, it will still not work in our MVC 4 Web API project. To log exceptions to Elmah you must create a custom ExceptionFilterAttribute class and use that to call Elmah when an exception occurs.

public class ElmahErrorAttribute : System.Web.Http.Filters.ExceptionFilterAttribute
{
    public override void OnException(
         System.Web.Http.Filters.HttpActionExecutedContext actionExecutedContext)
    {
        if (actionExecutedContext.Exception != null)
            Elmah.ErrorSignal.FromCurrentContext().Raise(actionExecutedContext.Exception);
        base.OnException(actionExecutedContext);
    }
}

6. Register the custom ExceptionFilterAttribute class in your global.ascx.cs file

Finally, you must register your custom ExceptionFilterAttribute class on startup.

protected void Application_Start()
{
    GlobalConfiguration.Configuration.Filters.Add(
        new ElmahErrorAttribute()
    );
    ….
}

That’s it! Now you should be able to run your web app and go to the page:

http://localhost:SOMEPORT/elmah.axd

Advertisements

Create a free website or blog at WordPress.com.