【问题标题】:Obsolete controller logging过时的控制器日志记录
【发布时间】:2018-09-18 01:46:26
【问题描述】:

我有一堆控制器,它们也提供不同版本的 API。

例如

/api/v1/controllerA/method
/api/v2/controllerA/method
/api/v1/controllerB/method

现在,我想使用提供的 .NET 属性将 /v1/controllerA/method 标记为 obsolete

但是,我还想记录对过时控制器的每次使用。澄清一下 - 这些控制器方法不会产生编译警告/错误,因为没有人直接在解决方案中引用它们。它们由 http 客户端在运行时调用。所以警告对我没有任何作用。

我知道如何进行日志记录,但我不确定拦截obsolete 控制器方法的调用的最佳方法是什么。

【问题讨论】:

  • 在哪个动作方法中?我标记为过时的每个控制器方法?我宁愿以某种方式集中它。
  • 基于向某事物添加属性的自动日志记录称为“面向方面的编程”。我的建议是对此进行一些谷歌搜索,然后找到一些您愿意使用的框架。它利用附加的编译时步骤根据您添加的属性将您的日志“编织”到应用程序中。希望对您有所帮助。
  • 我在想我会继承 ObsoleteAttribute 类并让它记录,当它装饰的方法执行时......

标签: c# asp.net-web-api


【解决方案1】:

遵循Passive Attributes by Mark Seemann的模式

他有一个完整的例子来说明如何做到这一点

这是一个可以做到这一点的类的简单实现

public class ObsoleteLoggingFilter : IActionFilter
{
    private readonly ILogger _logger;
    public ObsoleteLoggingFilter(ILogger logger)
    {
        _logger = logger;
    }
    public bool AllowMultiple { get { return true; } }

    public Task<HttpResponseMessage> ExecuteActionFilterAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)
    {
        //check the action for obsolete, if null check the controller
        var obsoleteAttribute = actionContext
            .ActionDescriptor
            .GetCustomAttributes<ObsoleteAttribute>()
            .SingleOrDefault() ?? actionContext
                .ControllerContext
                .ControllerDescriptor
                .GetCustomAttributes<ObsoleteAttribute>()
                .SingleOrDefault();

        if (obsoleteAttribute == null)
            return continuation();

        var controller = actionContext.ActionDescriptor.ControllerDescriptor.ControllerName;
        var user = actionContext.RequestContext.Principal.Identity.Name;

        return continuation().ContinueWith(t =>
        {
            _logger.WarnFormat("{0} is calling obsolete controller {1}", user, controller);
            return t.Result;
        });
    }
}

【讨论】:

  • ObsoleteAttribute 继承没有意义,因为这对我没有任何作用,对吧?如果有人直接引用该方法,.NET 编译器将无法识别它并产生警告。
  • 我喜欢他在文章中提出的使用属性作为标记,然后有一个单独的过滤器实现。这也是 DI 友好的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-24
  • 1970-01-01
  • 1970-01-01
  • 2017-03-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多