【问题标题】:Override global action filter in controller/action in ASP.NET Core MVC 1.0.1 (ASP.NET Core 1.1)在 ASP.NET Core MVC 1.0.1 (ASP.NET Core 1.1) 中的控制器/操作中覆盖全局操作过滤器
【发布时间】:2017-03-09 14:00:07
【问题描述】:

我正在构建一个 ASP.NET Core MVC 应用程序,并尝试创建一个全局操作过滤器,用于记录执行操作所花费的时间(仅当花费的时间超过某个阈值时才应该记录)。我已经成功地做到了这一点,但现在我想说单个动作或单个控制器应该有不同的阈值。当我尝试这个时,我的动作过滤器被应用了两次(这不是我想要的),但使用了正确的两个不同的阈值。

我已经尝试了很多东西并四处搜索。在 MVC 3 和 MVC 4 项目中,我已经使用 Global.asax 中的 RegisterGlobalFilters() 成功完成了这项工作,当我在控制器/动作上使用该属性时,它会自动覆盖全局。我也尝试了这篇文章中列出的方法,但没有运气:

Override global authorize filter in ASP.NET Core MVC 1.0

我的 ActionFilterAttribute 代码:

public class PerformanceLoggingAttribute : ActionFilterAttribute
{
    public int ExpectedMax = -1; // Log everything unless this is explicitly set
    private Stopwatch sw;

    public override void OnActionExecuting(ActionExecutingContext context)
    {
        sw = Stopwatch.StartNew();
    }

    public override void OnActionExecuted(ActionExecutedContext context)
    {
        sw.Stop();
        if (sw.ElapsedMilliseconds >= ExpectedMax)
        {
            // Log here
        }
    }

    //public override Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
    //{
    //    // If there is another performance filter, do nothing
    //    if (context.Filters.Any(item => item is PerformanceLoggingAttribute && item != this))
    //    {
    //        return Task.FromResult(0);
    //    }
    //    return base.OnActionExecutionAsync(context, next);
    //}
}

我在我的 Startup.cs 中应用这个全局过滤器:

services.AddMvc(options =>
            {
                if (_env.IsProduction()) options.Filters.Add(new RequireHttpsAttribute());
                //options.Filters.Add(new PerformanceLoggingFilter() { ExpectedMax = 1 }); // Add Performance Logging filter
                options.Filters.Add(new PerformanceLoggingAttribute() { ExpectedMax = 1 }); // Add Performance Logging filter
            });

在我的控制器中,我正在应用属性:

//[TypeFilter(typeof(PerformanceLoggingFilter))]
[PerformanceLogging(ExpectedMax = 2)]
public IActionResult Index()
{
    var vm = _performanceBuilder.BuildPerformanceViewModel();
    return View(vm);
}

从上面的代码 sn-ps 可以看出,我尝试了 OnActionExecutionAsync 方法,我也尝试了 IActionFilter 并在操作上使用 [TypeFilter(typeof(PerformanceLoggingFilter))],但没有运气。

谁能帮帮我?

【问题讨论】:

    标签: c# asp.net-core asp.net-core-mvc


    【解决方案1】:

    可能会建议您通过使用一个操作过滤器和其他自定义属性来尝试实现一些不同的实现:

    • 创建一个新的简单属性(我们将其命名为ExpectedMaxAttribute),它只包含ExpectedMax 值。将此属性应用于具有不同值的控制器操作。

    • PerformanceLogging 操作过滤器保持为全局,但修改实现。在OnActionExecuted 方法上检查控制器的操作是否有ExpectedMaxAttribute。如果是,则从属性中读取ExpectedMax 值,否则使用动作过滤器中的默认值。


    另外,我建议您根据约定命名操作过滤器,例如PerformanceLoggingActionFilter

    【讨论】:

    • 您的回答让我走上了正确的道路。我已经发布了我的解决方案作为答案。谢谢!
    【解决方案2】:

    感谢@Set 上面的答案和这个答案,我得到了它的工作: https://stackoverflow.com/a/36932793/5762645

    我最终得到了一个应用于所有操作的全局操作,然后有一个简单的 ExpectedMaxAttribute 用于阈值应该不同的操作。在我的全局操作过滤器的 OnActionExecuted 中,我检查有问题的操作是否附加了 ExpectedMaxAttribute,然后从中读取 ExpectedMax。以下是我的属性:

    public class PerformanceLoggingExpectedMaxAttribute : ActionFilterAttribute
    {
        public int ExpectedMax = -1;
    }
    

    还有我添加到 ActionFilter 的 OnActionExecuted 部分:

     public override void OnActionExecuted(ActionExecutedContext context)
     {
         sw.Stop();
         foreach (var filterDescriptor in context.ActionDescriptor.FilterDescriptors)
         {
             if (filterDescriptor.Filter is PerformanceLoggingExpectedMaxAttribute)
             {
                 var expectedMaxAttribute = filterDescriptor.Filter as PerformanceLoggingExpectedMaxAttribute;
                 if (expectedMaxAttribute != null) ExpectedMax = expectedMaxAttribute.ExpectedMax;
                 break;
             }
         }
         if (sw.ElapsedMilliseconds >= ExpectedMax)
         {
             _logger.LogInformation("Test log from PerformanceLoggingActionFilter");
         }
     }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-11-04
      • 1970-01-01
      • 1970-01-01
      • 2019-12-24
      • 2017-12-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多