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

时间:2018-05-16 13:00:11

标签: 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);
    }

}

2 个答案:

答案 0 :(得分: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);
}

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

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

[Logger]
public class CustomerController : Controller
{
   // actions code...
}

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

filters.Add(new LoggerAttribute());

答案 1 :(得分:1)

获取控制器&amp;动作名称您可以使用ActionDescriptor

ActionExecutingContext
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
    var descriptor = filterContext.ActionDescriptor;
    var actionName = descriptor.ActionName;
    var controllerName = descriptor.ControllerDescriptor.ControllerName;
    ......
    base.OnActionExecuting(filterContext);
}

关于用户信息:控制器初始化将在授权发生之前进行。因此,您的所有控制器都将在任何OnAuthorization发生之前创建。

处理这些情况的方法是使用Action FiltersAuthorize Attribute早于控制器初始化发生。

看看这篇文章: