我需要记录用户操作,并且我不希望每个控制器都有代码,所以在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);
}
}
答案 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 Filters。 Authorize Attribute早于控制器初始化发生。
看看这篇文章: