簡體   English   中英

覆蓋ASP.NET Core MVC 1.0.1(ASP.NET Core 1.1)中的控制器/操作中的全局操作過濾器

[英]Override global action filter in controller/action in ASP.NET Core MVC 1.0.1 (ASP.NET Core 1.1)

我正在構建一個ASP.NET Core MVC應用程序,並試圖創建一個全局操作篩選器,該篩選器記錄執行一次操作花費了多少時間(僅當花費的時間超過某個閾值時才應記錄)。 我已經成功完成了此操作,但是現在我想說一個動作或一個控制器應該具有不同的閾值。 當我嘗試此操作時,我的動作過濾器被應用了兩次(這不是我想要的),但是具有正確的兩個不同閾值。

我嘗試了很多事情並四處搜尋。 在MVC 3和MVC 4項目中,我已經使用Global.asax中的RegisterGlobalFilters()成功完成了此操作,當我在控制器/動作上使用屬性時,它會自動覆蓋全局變量。 我也嘗試過這篇文章中列出的方法,但是沒有運氣:

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

從上面的代碼片段可以看出,我嘗試了OnActionExecutionAsync方法,還嘗試了IActionFilter,並在操作上使用了[TypeFilter(typeof(PerformanceLoggingFilter))),但是沒有運氣。

誰能幫我嗎?

可能會建議您通過使用一個動作過濾器和其他自定義屬性來嘗試實現的目標不同的實現:

  • 創建一個新的簡單屬性(將其命名為ExpectedMaxAttribute ),該屬性僅保存ExpectedMax值。 將此屬性應用於具有不同值的控制器動作。

  • 保持PerformanceLogging操作過濾器為全局過濾器,但修改實現。 OnActionExecuted方法上,檢查控制器的動作是否具有ExpectedMaxAttribute 如果是,則從屬性讀取ExpectedMax值,否則使用動作過濾器的默認值。


另外,我建議您根據約定為PerformanceLoggingActionFilter類的約定重命名操作過濾器。

由於上面的@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");
     }
 }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM