I need to capture the user visited page and action performed on that page
You can implement an HttpModule which logs all the visited pages within your .NET MVC application.
With an HttpModule you have access to all the Request/Response properties, including Headers, Cookies, FormData parameters.
namespace MyApplication
{
public class DatabaseAuditHttpModule : IHttpModule
{
private class Properties
{
public string Url { get; set; }
public string HttpMethod { get; set; }
public int StatusCode { get; set; }
// add other important HTTP properties
}
public void Init(HttpApplication context)
{
context.BeginRequest += BeginRequest;
context.EndRequest += EndRequest;
}
private void BeginRequest(object sender, EventArgs e)
{
HttpContext ctx = HttpContext.Current;
var request = ctx.Request;
var requestHeaders = request.Unvalidated.Headers;
var requestFormData = request.Unvalidated.Form;
var properties = new Properties
{
Url = request.Url.ToString(),
HttpMethod = request.HttpMethod
};
ctx.Items["X-Properties"] = properties;
}
private void EndRequest(object sender, EventArgs e)
{
HttpContext ctx = HttpContext.Current;
// get the properties for the current HTTP request
Properties properties = (Properties)HttpContext.Current.Items["X-Properties"];
properties.StatusCode = ctx.Response.StatusCode;
// TODO:
// log these values in the database
}
public void Dispose()
{
}
}
}
Registering the HttpModule in Global.asax:
namespace MyApp.Mvc
{
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
}
// register DatabaseAuditHttpModule
public static DatabaseAuditHttpModule AuditHttpModule = new DatabaseAuditHttpModule();
public override void Init()
{
base.Init();
AuditHttpModule.Init(this);
}
}
}
Logging stored procedures execution example:
public class DatabaseService
{
public static async Task ExecuteStoredProcedureAsync(string connectionString, string storedProcedureName, ILogger logger)
{
logger.LogTrace($"'{storedProcedureName}' Stored Procedure executing");
long totalDuration = 0;
Stopwatch sw = new Stopwatch();
sw.Start();
using(var connection = new SqlConnection(connectionString))
{
connection.Open();
sw.Stop();
totalDuration += sw.ElapsedMilliseconds;
logger.LogTrace($"connection.Open() Duration:{sw.ElapsedMilliseconds}");
sw.Restart();
using (var command = SqlCommand(storedProcedureName, connection))
{
command.CommandType = CommandType.StoredProcedure;
using (var reader = await command.ExecuteReaderAsync())
{
sw.Stop();
totalDuration += sw.ElapsedMilliseconds;
logger.LogTrace($"'{storedProcedureName}' Stored Procedure ExecuteReader Duration:{sw.ElapsedMilliseconds}");
sw.Restart();
do
{
while (await reader.ReadAsync())
{
// read the data
}
} while (await reader.NextResultAsync());
}
sw.Stop();
totalDuration += sw.ElapsedMilliseconds;
logger.LogTrace($"'{storedProcedureName}' Stored Procedure executed. Duration:{totalDuration}");
return result;
}
}
}
}