如何在ASP.NET中使用Base Controller记录用户操作?

pun*_*ter 1 asp.net-mvc logging asp.net-core

我需要记录用户操作,我不希望每个控制器都有代码,所以在basecontroller中以某种方式执行此操作是否有意义?或者,还有更好的方法?

public class BaseController : Controller
{
    protected ILogger logger;

    public BaseController(ILogger<BaseController> logger)
    {
        this.logger = logger;
    }

    public override void OnActionExecuting(ActionExecutingContext context)
    {
        //How do I get the current controller? 
        //How do I get the current method being called? 
        //How can I pass in additional parameters?
        //How can I get the user? 

        logger.LogWarning("Loaded BaseController");
        base.OnActionExecuting(context);
    }

}
Run Code Online (Sandbox Code Playgroud)

Fel*_*ani 5

有很多方法可以做到这一点.

第一:你可以OnActionExecution像你一样创建自己的基本控制器并实现.请参阅下面的示例以获取信息ActionExecutingContext.

如果你采用这种方式,那么来自这个基本控制器的每个控制器都将获得记录器的实现,因为你要覆盖OnActionExecuting(这适用于你的控制器的所有动作).

public override void OnActionExecuting(ActionExecutingContext context)
{
    //How do I get the current controller? 
    string controllerName = context.ActionDescriptor.ControllerDescriptor.ControllerName

    //How do I get the current method being called? 
    string actionName = context.ActionDescriptor.ActionName;

    //How can I pass in additional parameters?
    foreach (var parameter in context.ActionParameters)
    {
        var parameterKey = parameter.Key;
        var parameterValue = parameter.Value;
    }

    //How can I get the user? 
    var user = this.User; // IPrinciple instance, explore this object

    logger.LogWarning("Loaded BaseController");
    base.OnActionExecuting(context);
}
Run Code Online (Sandbox Code Playgroud)

第二:另一方面,你可以使用ActionFilters,它是一个从ActionFilter类中强制执行的类,并在这个classe上执行相同的实现来覆盖OnActionExecuting.然后,您可以使用此属性修饰控制器以生成记录器.鉴于它是一个属性,你必须Attribute使用sufix定义类的名称,并在没有它的情况下使用它.样品:

public class LoggerAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext context)
    {
       // same code above
    }
}

[Logger]
public class CustomerController : Controller
{
   // actions code...
}
Run Code Online (Sandbox Code Playgroud)

第三步:使用相同的动作过滤器类,而不是应用所需的所有类,将其定义为全局动作过滤器,它将应用于所有控制器.你必须在它上面定义它GlobalFilter,如果你使用的是asp.net mvc的默认模板,你可以在FilterConfig.cs样本上定义它:

filters.Add(new LoggerAttribute());
Run Code Online (Sandbox Code Playgroud)