Elmah not logging exceptions for http post requests in MVC app - if the request contains XML

Viewed 3354

I've come across a weird problem in my MVC4 (RC) application. (running on .NET 4.0)

I have just setup Elmah for logging exceptions / errors.

I basically installed the Elmah.MVC and elmah.sqlserver NuGet packages. (versions 2.0.0 and 1.2 respectively)

It seemed to work fine out of the box - I can go to the elmah page and view errors:

http://myserver/elmah

for example, if I create some 404 errors, they appear in this log.

What is not working is this: I have a standard MVC controller with a [HttpPost] action. I've set it up so it will always throw an exception:

public class TestController : Controller
{
    [HttpPost]
    [ValidateInput(false)]
    public void Testing()
    {
        throw new Exception("uh oh");
    }
}

I then try to post data to this controller via jQuery:

$.post('/Test/Testing', {test_data: 'This is some test data'});

Ok, this works. The response returns the typical yellow screen of death, and the error is caught and logged in Elmah.

However, if I try to post something like XML/HTML the error is not logged in Elmah. I still get the same response from the server back (yellow screen of death), but nothing in Elmah.

$.post('/Test/Testing', {test_data: '<test><test1>This is some test data</test1></test>'});

Why? It doesn't make sense.

Notice I have already turned off the request validation on the action. If I didn't do that, then posting XML/HTML data would cause this exception:

A potentially dangerous Request.Form value was detected from the client

NuGet would also refuse to log that exception too - which I believe is a bug:

http://code.google.com/p/elmah/issues/detail?id=217

So what is the cause of this problem that I'm experiencing? It it a bug related to the issue I found above?

It just seems quite an unfortunate situation that I can't log exceptions just because the request contained XML/HTML.

Surely there is a way around this?

7 Answers

With thanks to Amarisi for the code, I've reworked it into my Global.asax.cs files Application_Error method to log all the exceptions Elmah fails to log.

It looks like this (edited down but should work):

protected void Application_Error(object sender, EventArgs e)
    {
        Exception exception = Server.GetLastError();

        // ELMAH will not log exceptions arising from POST requests
        // when the form values contains 'potentially dangerous' chars
        // e.g. html tags

        // Adding this explicit ELMAH logging because of ELMAH bug:
        // https://code.google.com/p/elmah/issues/detail?id=217
        // Waiting for a new ELMAH release with the fix

        // get form object
        System.Collections.Specialized.NameValueCollection RequestForm = Request.Unvalidated.Form;

        // get combined text of form values
        string formValues = string.Join(",", RequestForm.AllKeys.Select(key => RequestForm[key])); 

        // is this the type of POST that Elmah fails on?
        if (formValues.Contains("<")) 
        {
            // log the exception manually
            var elmahError = new Elmah.Error(exception);
            var elmahLog = Elmah.ErrorLog.GetDefault(Context);
            elmahLog.Log(elmahError);
        }
    }
}

Contains("<") isn't the best test. I doubt it covers everything that Elmah fails to log.

Would love to see if anyone can improve this further.

Related