Регистрация результатов связывания модели ядра ASP.NET - PullRequest
0 голосов
/ 07 мая 2019

Я хотел бы увеличить / улучшить мою регистрацию.

До сих пор я имел в каждом коде действия контроллера, как

  public asyc Task<IActionResult> Action1(int id, [FromBody] RequestModel request) {
    string log = $"{nameof(Action1)}(id: {id}, request: {request?.ToJson()})";
    _logger.LogInformation(log);

Основная цель состояла в том, чтобы увидеть, что на самом деле достигает действия контроллера.

Я удалил его, так как он сильно загромождал код (например, для методов с большим количеством параметров).Но теперь я недоволен тем, что в журналах больше не отображается информация (и они нужны мне для изучения некоторых необъяснимых ошибок).

Есть ли способ подключиться к результатам связывания модели (например,через сервисный фильтр) для записи результатов связывания модели?


Работает как шарм: благодаря Шахзаду Хасану

  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();

    }

  }

1 Ответ

1 голос
/ 07 мая 2019

Я думаю, что вместо этого вы можете использовать ActionFilter. Фильтры ActionFilter выполняются после привязки модели, поэтому вы можете получить параметры из 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 в действии контроллера, чтобы его зависимости, т. Е. ILogger разрешались через DI.

[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 и запишите значение для каждого ключа. Вам нужно будет выполнить некоторые проверки типов и вызвать .ToJson(), если тип ActionArgument - это RequestModel.

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...