我具有如下所示的自定义日志记录属性:
public class LoggerAttribute: ActionFilterAttribute
{
private readonly IHttpLogService _httpLogService;
private readonly ILogService _logService;
public LoggerAttribute(IHttpLogService httpLogService, ILogService logService)
{
_httpLogService = httpLogService;
_logService = logService;
}
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
LogDetails(filterContext);
}
private void LogDetails(ActionExecutingContext filterContext)
{
try
{
HttpLogService httpService = new HttpLogService();
var httplogger = new LogMetaData()
{
RequestParams = filterContext,
ResponseParams = filterContext
};
_httpLogService.Emit("source", "", "Name", httplogger);
}
catch (Exception ex)
{
_logService.Emit(Core.Enums.LogLevel.Error, "token", "Error encountered while trying to execute the request.", ex);
throw new Exception("An error occurred. Please try again later.");
}
}
}
以下是控制器操作方法中的代码,在该代码中,我需要执行上面的过滤器,但是下面的代码不起作用,因为我不确定如何通过属性传递服务:
[LoggerAttribute]
public int testMethod(RequestObject obj)
{
-----
}
IHttpLogService和ILogService是我需要注入到自定义过滤器属性中的一个。但是我不太确定如何做到这一点。有人可以帮我吗?
您必须将属性与actionfilter分开。保持属性简单明了:
[AttributeUsage(AttributeTargets.Method)]
public class LoggerAttribute : Attribute
{
}
然后让您的actionfilter发挥作用:
public class LoggerActionFilter : IActionFilter
{
// Can inject stuff in the constructor
public void OnActionExecuting(ActionExecutingContext context)
{
// You may need some more null checking here...
var attribute = ((ReflectedActionDescriptor)filterContext.ActionDescriptor).MethodInfo.GetCustomAttributes(true).OfType<LoggerAttribute>().FirstOrDefault();
if (attribute is null)
{
return;
}
// Work your logger magic here.
}
}
不要忘记在启动时注册您的actionfilter:
services.AddControllersWithViews(options =>
{
options.Filters.Add(typeof(LoggerActionFilter));
});
甚至更好:您现在可以使用IAsyncActionFilter!
根据我的第一个分析,您的代码不应该编译,您尝试使用的代码在ASP.Net中称为过滤器。
过滤器定义:
ASP.NET MVC筛选器是一个自定义类,您可以在其中编写要在执行操作方法之前或之后执行的自定义逻辑。可以以声明或编程方式将过滤器应用于操作方法或控制器。声明方法是通过将过滤器属性应用于动作方法或控制器类,编程方法是通过实现相应的接口。
1-第一步:(创建您的过滤器)
public class TestFilter : ActionFilterAttribute
{
private readonly ILoggerService loggerService;
public TestFilter():this(new LoggerService())
{
}
public TestFilter(ILoggerService loggerService)
{
this.loggerService = loggerService;
}
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
base.OnActionExecuting(filterContext);
}
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
base.OnActionExecuted(filterContext);
}
}
2-第二步:(注册您的过滤器)
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
filters.Add(new TestFilter());
}
3-第三步:(将过滤器集成到控制器或操作中)
[TestFilter]
public class CustomerController : Controller
{
.....
}
第一步,我手动实例化了我的记录器,但是在您的情况下,您应该通过界面自动解决记录器,您可以做的是用您自己的代码替换这段代码。