I figured I could use actionfilters in MVC 4 to log when someone create, edits or deletes a row from the database. I can log the controller name, action name, IP and Identity no problem. But I also want to write to the database, the entire row that has been deleted. I also want to write to the database, the changes that have been made to the row. I want this filter to be reusable for multiple controllers.
I wrote some code, but I pretty much got stuck.
public class ActivityLog : ActionFilterAttribute, IActionFilter
{
private readonly DbContext1 _db = new DbContext1();
void IActionFilter.OnActionExecuted(ActionExecutedContext filterContext)
{
if (!filterContext.Controller.ViewData.ModelState.IsValid) return;
string parameters;
var formParams = filterContext.HttpContext.Request.Form;
switch (filterContext.ActionDescriptor.ActionName.ToUpper())
{
case "CREATE": //show created object in log parameters
parameters = "{" +
String.Join(", ",
formParams.Cast<string>()
.Where(
x =>
x != "__RequestVerificationToken" &&
!String.IsNullOrWhiteSpace(formParams[x]))
.Select(x => x + ":" + formParams[x])) + "}";
break;
case "EDIT": //show only changes in object in log parameters
parameters = JsonConvert.SerializeObject(/*dunno what to put here*/);
break;
case "DELETE": //show deleted object in log parameters
parameters = JsonConvert.SerializeObject(/*dunno what to put here*/);
break;
default:
return;
}
var log = new Models.ActivityLog()
{
DateTime = filterContext.HttpContext.Timestamp,
Controller = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName,
Action = filterContext.ActionDescriptor.ActionName,
UserId = filterContext.HttpContext.User.Identity.Name,
IP = filterContext.HttpContext.Request.UserHostAddress,
Parameters = parameters
};
_db.ActivityLog.Add(log);
_db.SaveChanges();
base.OnActionExecuted(filterContext);
}
}