Introduction
Sometimes in ASP.NET applications, there is a need to log HTTP POST data for future analysis (incident management, statistics, etc.). IIS logs HTTP GET parameters out of the box, using Standard Logging functionality, but this tip is about storing HTTP POST data, that is little bit trickier. There is another feature, called Advanced Logging, that allows you to store any data in IIS log, but in this case you need to post data manually, that is not very useful, when you do not want to change the existing web application.
Background
Fortunately, there are two great features you can use use to solve this problem. The first is Response.AppendToLog, that instructs ASP.NET to append user provided data to standard IIS log, generated by the server (you can call it at any point in ASP.NET net pipeline). The second one is HttpModule that can be used to do the trick without changing the existing web application.
Using the Code
Just create a new Class Library in your solution and add a new class, that implements IHttpModule
. Subscribe to BeginRequest
event in Init
method and process data you want to be appended to the log. The following example logs all data for every POST
request:
using System;
using System.Web;
namespace MySolution.HttpModules
{
public class HttpPOSTLogger : IHttpModule
{
public void Dispose()
{
}
public void Init(HttpApplication context)
{
context.BeginRequest += new EventHandler(context_BeginRequest);
}
private void context_BeginRequest(object sender, EventArgs e)
{
if (sender != null && sender is HttpApplication)
{
var request = (sender as HttpApplication).Request;
var response = (sender as HttpApplication).Response;
if (request != null && response != null && request.HttpMethod.ToUpper() == "POST")
{
var body = HttpUtility.UrlDecode(request.Form.ToString());
if (!string.IsNullOrWhiteSpace(body))
response.AppendToLog(body);
}
}
}
}
}
Do not forget to register a newly created module in web.config of your application:
Use system.WebServer section for IIS Integrated Model.
<system.webServer>
<modules>
<add name="HttpPOSTLogger"
type="MySolution.HttpModules.HttpPOSTLogger, MySolution.HttpModules" />
</modules>
</system.webServer>
Use system.web section for IIS Classic Model.
<system.web>
<httpModules>
<add name="HttpPOSTLogger"
type="MySolution.HttpModules.HttpPOSTLogger, MySolution.HttpModules"/>
</httpModules>
</system.web>
After you are set up, start your application and perform some POST
activity. Now you will see that log files created by IIS (c:\inetput\Logs directory by default) now contain POST
data as well, instead of "-
" sign.
Before:
::1, -, 10/31/2017, 10:53:20, W3SVC1, machine-name, ::1, 5, 681, 662, 200, 0, POST,
/MySolution/MyService.svc/MyMethod, -,
After:
::1, -, 10/31/2017, 10:53:20, W3SVC1, machine-name, ::1, 5, 681, 662, 200, 0, POST,
/MySolution/MyService.svc/MyMethod,
{"model":{"Platform":"Mobile","EntityID":"420003"}},
Applications
Please be careful, using this solution, because storing POST
data for every request would be very expensive in terms of disk storage. In our case, we were interested in storing extremely small JSON data posted to web-service.
Notes
If IIS logging is not set up yet, you can add it manually from Add/Remove Windows Features or Server Manager. After doing this, IIS console should look something like this:
Samples of log output are provided in "IIS" format, but you can use "W3C" as well.