Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Asp.Net MVC How to log all actions being called

I need to be able to log all actions that are called from my asp.net mvc application. How and what would be the best way to achieve this? Where I log it to whether it be the console or log file doesn't matter.

like image 966
Eminem Avatar asked Sep 25 '15 08:09

Eminem


People also ask

How will you implement logging in MVC application?

Add log4net in config file config and enter the following details. Add a class Log. cs in the Utilities folder. Now, in the constructor of this class, instantiate logs for monitoring and debugger loggers.

How many action results are there in MVC?

Action Result It is a base class for all type of action results. The diagram shown below describes about abstract class of Action Result. There are two methods in Action Result. One is ActionResult() and another one is ExecuteResult().

What is nonaction in MVC?

Non-Action is another built-in attribute which indicates that a public method of a Controller is not an action method. It is used when we don't want that method to be treated as an action method. Please read my previous articles to learn more about Selectors in ASP.NET MVC.


2 Answers

Credit HeyMega for their answer. Here's an example of an expanded implementation I arrived at in MVC5.

public class LogActionAttribute : ActionFilterAttribute
{

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        var controller = filterContext.RequestContext.RouteData.Values.ContainsKey("Controller") ? filterContext.RequestContext.RouteData.Values["Controller"].ToString() : null;
        var action = filterContext.RequestContext.RouteData.Values.ContainsKey("Action") ? filterContext.RequestContext.RouteData.Values["Action"].ToString() : null;
        var area = filterContext.RequestContext.RouteData.DataTokens.ContainsKey("Area") ? filterContext.RequestContext.RouteData.DataTokens["Area"].ToString() : null;
        var user = filterContext.RequestContext.HttpContext.User.Identity.GetUserId();

        Task.Run(() => Generic().AreaActionLog(user, area, controller, action));

        base.OnActionExecuting(filterContext);
    }
}

I chose to separate the method doing the actual logging into a separate process, if anything goes wrong with the Database interaction, or the DB interaction takes several seconds, the UI is uninterrupted.

You can then decorate the entire controller with [LogAction] attribute like so.

[LogAction]
public class HomeController : Controller
{
    public ActionResult Index()
    {
        return View();
    }

    public ActionResult Contact()
    {
        return View();
    }
}

Or selectively apply the attribute by decorating individual methods:

public class HomeController : Controller
{
    [LogAction]
    public ActionResult Index_Logs_Things()
    {
        return View();
    }
}

Hope this helps someone.

like image 120
Richard Avatar answered Sep 18 '22 17:09

Richard


You could create your own class which inherits from ActionFilterAttribute and then override the OnActionExecuting method.

Example

public class LogActionAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {

        var controller = filterContext.RequestContext.RouteData.Values["Controller"];
        var action = filterContext.RequestContext.RouteData.Values["Action"];

        //
        // Perform logging here
        //

        base.OnActionExecuting(filterContext);
    }
}

public class HomeController : Controller
{
    [LogAction]
    public ActionResult Index()
    {

        return View();
    }

}

Hope this helps!

like image 33
heymega Avatar answered Sep 20 '22 17:09

heymega