Log all data in ASP.Net MVC POST Requests

Today for debugging purposes I had to capture all the information submitted by users in a specific controller. Turned out that there was nothing readily implemented or provided by framework that I could use.

But implementation turned out quite simple. It is just another Action Filter that can be applied globally, per controller or per action:

using System.Linq;
using System.Web.Mvc;
using Newtonsoft.Json;

public class DebuggingFilter : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (!filterContext.HttpContext.Request.IsPost())
        {
            return;
        }

        // I use instance wrapper around NLog logger. Apply your own logic here for creating logger.
        var logger = DependencyResolver.Current.GetService<ILoggingService>();

        var form = filterContext.HttpContext.Request.Form;

        // need to convert Form object into dictionary so it can be converted to json properly
        var dictionary = form.AllKeys.ToDictionary(k => k, k => form[k]);

        // You'll need Newtonsoft.Json nuget package here.
        var jsonPostedData = JsonConvert.SerializeObject(dictionary);

        logger.Debug(jsonPostedData);

        base.OnActionExecuting(filterContext);
    }
}

And then apply this attribute on top of your controller or action you’d like to monitor:

[DebuggingFilter]
public partial class MyController : Controller
{
    //... actions
}

This will put all POSTed data into your logs formatted as JSON – later it will be relatively easy to reproduce user actions and re-submit the data for debugging.

Word of a Warning

adding this filter to a global filter collection can lead to a significant performance problem in your application. I’ve set up logging into files (as a temp solution) and without measuring I could see the application was slower to respond with this filter.

Another warning – you don’t want to have this attribute on controller that takes passwords. Passwords are usually stored salted-and-hashed and never in plain text. But if you have this attribute on a controller that takes passwords – user passwords will end up in plain text in your logs. That’s a pretty big NO-NO, so don’t do it.