2017-03-09 21 views
0

ASP.NET Core MVCアプリケーションを構築していて、どのくらいの量のグローバルアクションフィルタを作成しようとしていますかアクションの実行に時間が費やされます(使用済みの時間があるしきい値を超えた場合にのみ記録する必要があります)。私はこれを成功させましたが、今は単一のアクションまたは単一のコントローラーが異なるしきい値を持つ必要があると言いたいと思います。これを試してみると、私のアクションフィルタは2回適用されます(これは私が望むものではありません)が、正しい2つの異なるしきい値で適用されます。ASP.NETのコントローラ/アクションでグローバルアクションフィルタをオーバーライドするコアMVC 1.0.1(ASP.NET Core 1.1)

私はかなりのことを試して、検索しました。 MVC 3とMVC 4プロジェクトでは、Global.asaxでRegisterGlobalFilters()を使用してこれを正常に実行しました。コントローラ/アクションでその属性を使用すると、自動的にグローバルグローバルをオーバーライドします。

Override global authorize filter in ASP.NET Core MVC 1.0

私ActionFilterAttributeのための私のコード:私は私のStartup.csにこのグローバルフィルタを適用しています

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

私も運なしで、この記事に記載されているアプローチを試してみました
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アプローチを試していますが、代わりに[TypeFilter(typeof(PerformanceLoggingFilter))]を使用してIActionFilterを試してみました。

誰でもお手伝いできますか?

答えて

0

私はそれがこの答えとの組み合わせで上記@セットの答えのおかげで作業しました: 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"); 
    } 
} 
1

はあなたがワンアクションフィルタと追加のカスタム属性を使用することによって達成しようとするものの少し異なる実装を提案することができる:

  • だけ保持し、新たなシンプルな属性(のはそれExpectedMaxAttribute名前を付けましょう)を作成しますExpectedMax値。この属性をコントローラのアクションに異なる値で適用します。

  • PerformanceLoggingアクションフィルタをグローバルにしておきますが、実装を変更してください。 OnActionExecutedでは、コントローラのアクションがExpectedMaxAttributeであるかどうかをチェックします。はいの場合は、属性からExpectedMax値を読み取ります。そうでない場合は、アクションフィルタのデフォルト値を使用します。


また、私はPerformanceLoggingActionFilterのようなものを命名規則に応じてアクションフィルタの名前を変更することをお勧めいたします。

+0

あなたの答えは正しい道に私を導きました。私は答えとして私の解決策を掲載しました。ありがとう! – nicklas669

関連する問題