Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Elmah: How to get JSON HTTP request body from error report

I'm using Elmah to log exceptions. Elmah is great at logging request bodies if the request is a Form-based request (i.e. Content-Type: application/x-www-form-urlencoded), but with JSON based requests where the content type is application/json, the request body is nowhere to be found in the error reports. Anyone know where I can find this request body so that I can properly diagnose my exceptions?

UPDATE: 2012-01-03

As a clarification on what I mean by JSON based requests, here's an example raw HTTP request with JSON as the request body:

PUT http://mycompany.com/api/v1.0/me HTTP/1.1
Host: mycompany.com
Content-Length: 20
Content-Type: application/json

{"city":"Vancouver"}
like image 662
Johnny Oshika Avatar asked Dec 31 '11 05:12

Johnny Oshika


3 Answers

ELMAH so far only logs the context or information that is peripheral to the request and which can be conveniently captured in a standard way. Forms are arguably a special treatment because ASP.NET already does the job of decoding and memorizing request entities when the MIME type is application/x-www-form-urlencoded. JSON requests on the other hand are prolematic because at the time an exception occurs, the input stream (HttpRequest.InputStream) may have been partially or completely consumed by a JSON decoder. ELMAH would not be able to get a second crack at it for the purpose of logging. You will therefore have to make sure that you buffer the input stream or text before passing it through any JSON decoder and stash it away somewhere like HttpContext.Items. You could then try to recover the buffered data and attach it to an outgoing mail at the time of an error. ELMAH currently does not support attaching arbitrary data to a logged error. There is however the ErrorLogModule that has a Logged event and which supplies the Id of the logged error. This could be used to store the input data elsewhere (perhaps in another table if you are using a back-end database for the error logs) but tie it back to the logged error by maintaining an association via the Id.

like image 96
Atif Aziz Avatar answered Nov 05 '22 09:11

Atif Aziz


first install nuget package : Newtonsoft.Json

install-package Newtonsoft.Json

then:

 public override void OnException(HttpActionExecutedContext filterContext)
        {
    var message = new StringBuilder();
            foreach (var param in filterContext.ActionContext.ActionArguments)
            {
                message.Append(string.Format("{0}:{1}\r\n", param.Key, Newtonsoft.Json.JsonConvert.SerializeObject(param.Value)));
            }
            var ex = new Exception(message.ToString(), filterContext.Exception);
            var context = HttpContext.Current;
            ErrorLog.GetDefault(context).Log(new Error(ex, context));
}
like image 44
Ammaroff Avatar answered Nov 05 '22 08:11

Ammaroff


Further to Atif's answer here, there is a way to add additional details to ELMAH log by manually throwing a new Exception. It's not particularly elegant but it seems to do the job!

I'd be interested to hear any comments from the man himself...

like image 1
Oliver Gray Avatar answered Nov 05 '22 08:11

Oliver Gray