c# - 在 ASP.NET Core MVC 1.0.1 (ASP.NET Core 1.1) 中覆盖 Controller / Action 中的全局 Action 过滤器

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

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

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

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

在我的 Controller 中,我正在应用属性:

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

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

谁能帮帮我?

最佳答案

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

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

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


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

关于c# - 在 ASP.NET Core MVC 1.0.1 (ASP.NET Core 1.1) 中覆盖 Controller / Action 中的全局 Action 过滤器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42697333/

相关文章:

c# - OnCertificateValidated 未运行 - 自签名证书客户端身份验证 - ASP.NET Core 和 Kestrel

c# - 如何转义名称为 SQL 保留关键字的表?

c# mashal const std::list<object> 来自 c++ dll

c# - 使用 Json.NET/NEST/Elasticsearch 在 ASP.NET Core 应用程序中找不到方法错误

asp.net - 无法将索引 35 处的字节 [FC] 从指定的代码页转换为 Unicode

c# - ASP.NET Core 2.0 防止重复条目

c# - 如何配置 log4net 以在 Debug模式下打印到控制台

c# - Azure Function 2.x 支持路由 url 的版本号和类名称

c# - services.AddControllersWithViews() 与 services.AddMvc()

c# - .Net Core 依赖注入(inject)从构造函数中注入(inject)