ASP.NET 核心模型活页夹结果记录
ASP.NET Core model binder result logging
我想增加/改进我的日志记录。
到目前为止,我在每个控制器操作代码中都有
public asyc Task<IActionResult> Action1(int id, [FromBody] RequestModel request) {
string log = $"{nameof(Action1)}(id: {id}, request: {request?.ToJson()})";
_logger.LogInformation(log);
主要目的是查看实际到达控制器操作的内容。
我删除了它,因为它严重扰乱了代码(例如,对于具有大量参数的方法)。但是现在我对日志不再显示信息的结果感到不满意(我需要他们调查一些无法解释的错误)。
有没有办法连接到模型绑定器结果(例如通过服务过滤器)以记录模型绑定器结果?
像魅力一样工作:感谢 Shahzad Hassan
public class MethodCallParameterLogger : IAsyncActionFilter
{
public ILoggerFactory LoggerFactory { get; set; }
public MethodCallParameterLogger(ILoggerFactory loggerFactory)
{
LoggerFactory = loggerFactory;
}
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
LoggerFactory
// the display name contains the controller name space, controller name, method name and the postfix " (ActionLogger)"
.CreateLogger(context.ActionDescriptor.DisplayName.Split(" ")[0])
// MIND THAT THIS LOGS EVEN SENSITIVE DATA (e.g. credentials) !!!
.LogInformation(JsonConvert.SerializeObject(context.ActionArguments));
var resultContext = await next();
}
}
我认为您可以改用 ActionFilter。 ActionFilters 在模型绑定后执行,因此您可以从 ActionExecutingContext
中检索参数。您可以覆盖 OnActionExecuting
方法并记录所需的任何内容:
public class LogParamsFilter : ActionFilterAttribute
{
private readonly ILogger<LogsParamsFilter> _logger;
public LogParamsFilter (ILogger<LogsParamsFilter> logger)
{
_logger = logger;
}
public override void OnActionExecuting(ActionExecutingContext context)
{
var id = (int)context.ActionArguments["id"];
var request = context.ActionArguments["request"] as RequestModel;
var action = context.ActionDescriptor.DisplayName;
string log = $"{action)}(id: {id}, request: {request?.ToJson()})";
_logger.LogInformation(log);
base.OnActionExecuting(context);
}
}
您需要在控制器操作上将其用作 TypeFilter,以便通过 DI 解析其依赖项,即 ILogger。
[TypeFilter(typeof(LogParamsFilter))]
public asyc Task<IActionResult> Action1(int id, [FromBody] RequestModel request)
{
...
}
或者您可以在所有控制器的启动中全局注册它:
services.AddMvc(options => options
.Filters.Add(new TypeFilterAttribute(typeof(LogParamsFilter))));
为了将其用作所有控制器操作的通用过滤器,遍历 context.ActionArguments.Keys
属性 并记录每个键的值。如果 ActionArgument
的类型是 RequestModel.
,您需要进行一些类型检查并调用 .ToJson()
希望对您有所帮助。
我想增加/改进我的日志记录。
到目前为止,我在每个控制器操作代码中都有
public asyc Task<IActionResult> Action1(int id, [FromBody] RequestModel request) {
string log = $"{nameof(Action1)}(id: {id}, request: {request?.ToJson()})";
_logger.LogInformation(log);
主要目的是查看实际到达控制器操作的内容。
我删除了它,因为它严重扰乱了代码(例如,对于具有大量参数的方法)。但是现在我对日志不再显示信息的结果感到不满意(我需要他们调查一些无法解释的错误)。
有没有办法连接到模型绑定器结果(例如通过服务过滤器)以记录模型绑定器结果?
像魅力一样工作:感谢 Shahzad Hassan
public class MethodCallParameterLogger : IAsyncActionFilter
{
public ILoggerFactory LoggerFactory { get; set; }
public MethodCallParameterLogger(ILoggerFactory loggerFactory)
{
LoggerFactory = loggerFactory;
}
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
LoggerFactory
// the display name contains the controller name space, controller name, method name and the postfix " (ActionLogger)"
.CreateLogger(context.ActionDescriptor.DisplayName.Split(" ")[0])
// MIND THAT THIS LOGS EVEN SENSITIVE DATA (e.g. credentials) !!!
.LogInformation(JsonConvert.SerializeObject(context.ActionArguments));
var resultContext = await next();
}
}
我认为您可以改用 ActionFilter。 ActionFilters 在模型绑定后执行,因此您可以从 ActionExecutingContext
中检索参数。您可以覆盖 OnActionExecuting
方法并记录所需的任何内容:
public class LogParamsFilter : ActionFilterAttribute
{
private readonly ILogger<LogsParamsFilter> _logger;
public LogParamsFilter (ILogger<LogsParamsFilter> logger)
{
_logger = logger;
}
public override void OnActionExecuting(ActionExecutingContext context)
{
var id = (int)context.ActionArguments["id"];
var request = context.ActionArguments["request"] as RequestModel;
var action = context.ActionDescriptor.DisplayName;
string log = $"{action)}(id: {id}, request: {request?.ToJson()})";
_logger.LogInformation(log);
base.OnActionExecuting(context);
}
}
您需要在控制器操作上将其用作 TypeFilter,以便通过 DI 解析其依赖项,即 ILogger。
[TypeFilter(typeof(LogParamsFilter))]
public asyc Task<IActionResult> Action1(int id, [FromBody] RequestModel request)
{
...
}
或者您可以在所有控制器的启动中全局注册它:
services.AddMvc(options => options
.Filters.Add(new TypeFilterAttribute(typeof(LogParamsFilter))));
为了将其用作所有控制器操作的通用过滤器,遍历 context.ActionArguments.Keys
属性 并记录每个键的值。如果 ActionArgument
的类型是 RequestModel.
.ToJson()
希望对您有所帮助。