2012-07-30 16 views
67

すべて私のASP.NET MVC 4アプリケーションへの着信要求はであり、指定されたコントローラ/アクションへの要求を継続する前にコードを実行する方法はありますか?ASP.NET MVC 4はすべての着信要求を傍受します

は、私は、すべてのクライアントからのすべての着信要求は他のサービスである事を再確認することがインターセプトする必要があります、既存のサービスといくつかのカスタム認証コードを実行すると、これを適切に行う必要があります。

+7

私のフィルタリング記事を参照http://msdn.microsoft.com/en-us/library/gg416513(VS.98).aspx – RickAndMSFT

答えて

70

ActionFilterAttributeを継承し、OnActionExecutingメソッドを継承するクラスを作成するのが最も正しい方法です。これはGlobalFiltersGlobal.asax.csに登録することができます。

もちろん、実際には経路を持っているリクエストを傍受するだけです。

+8

唯一の(醜い)もう一つの方法は、 'protected void Application_BeginRequest(Object sender、EventArgs e ) '。 –

+1

まあ、私はあなたもHttpHandlerを作成し、web.configのすべてをキャッチするために登録することができると思うが、それは本当に汚いです:) –

+0

素晴らしい、ありがとう!十分な時間が経過すると答えとしてマークします。 – Jesse

35

あなたはこれを実現するためにHttpModuleを使用することができます。ここで私はすべての要求のための処理時間を計算するために使用するサンプルは次のとおりです。

using System; 
using System.Diagnostics; 
using System.Web; 

namespace Sample.HttpModules 
{ 
    public class PerformanceMonitorModule : IHttpModule 
    { 

     public void Init(HttpApplication httpApp) 
     { 
      httpApp.BeginRequest += OnBeginRequest; 
      httpApp.EndRequest += OnEndRequest; 
      httpApp.PreSendRequestHeaders += OnHeaderSent; 
     } 

     public void OnHeaderSent(object sender, EventArgs e) 
     { 
      var httpApp = (HttpApplication)sender; 
      httpApp.Context.Items["HeadersSent"] = true; 
     } 

     // Record the time of the begin request event. 
     public void OnBeginRequest(Object sender, EventArgs e) 
     { 
      var httpApp = (HttpApplication)sender; 
      if (httpApp.Request.Path.StartsWith("/media/")) return; 
      var timer = new Stopwatch(); 
      httpApp.Context.Items["Timer"] = timer; 
      httpApp.Context.Items["HeadersSent"] = false; 
      timer.Start(); 
     } 

     public void OnEndRequest(Object sender, EventArgs e) 
     { 
      var httpApp = (HttpApplication)sender; 
      if (httpApp.Request.Path.StartsWith("/media/")) return; 
      var timer = (Stopwatch)httpApp.Context.Items["Timer"]; 

      if (timer != null) 
      { 
       timer.Stop(); 
       if (!(bool)httpApp.Context.Items["HeadersSent"]) 
       { 
        httpApp.Context.Response.AppendHeader("ProcessTime", 
                  ((double)timer.ElapsedTicks/Stopwatch.Frequency) * 1000 + 
                  " ms."); 
       } 
      } 

      httpApp.Context.Items.Remove("Timer"); 
      httpApp.Context.Items.Remove("HeadersSent"); 

     } 

     public void Dispose() { /* Not needed */ } 
    } 

} 

そして、これはあなたがのWeb.Configでモジュールを登録する方法である:

<system.webServer> 
    <modules runAllManagedModulesForAllRequests="true"> 
     <add name="PerformanceMonitorModule" type="Sample.HttpModules.PerformanceMonitorModule" /> 
    </modules> 
<//system.webServer> 
+3

コントローラに行く前にMVCアプリケーションの要求をキャプチャすることが目的ならば、フィルタリングははるかに良いアプローチです。私の記事を参照してくださいhttp://msdn.microsoft.com/en-us/library/gg416513(VS.98).aspx - 私のサンプルは素晴らしいタイミングフィルタを持っています – RickAndMSFT

+1

私は 'runAllManagedModulesForAllRequests'を使用しているので、パフォーマンスの牽引力。 'Application_BeginRequest'は、結果を達成するもっと簡単な方法のようです – Quango

21

私は何を検索することはあると思いますこの:

Application_BeginRequest() 

http://www.dotnetcurry.com/showarticle.aspx?ID=126

あなたはGlobal.asax.csに入れます。

protected void Application_BeginRequest(object sender, EventArgs e) 
    { 
     HttpContext.Current.Request.....; 
    } 

私はこれをデバッグの目的で使用しますが、私はあなたの場合にどのように良い解決策があるのか​​よく分かりません。

1

私はMVC4についてはよく分からないが、私はそれがMVC5にかなり似ていると思います。新しいWebプロジェクトを作成した場合 - >Global.asaxに見て、あなたは方法Application_Start()に次の行FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);が表示されるはずです。

RegisterGlobalFiltersは、フォルダApp_StartにあるファイルFilterConfig.csのメソッドです。 @ YngveB-ニルセンとして

ActionFilterAttributeが私の意見で移動するための方法であると述べました。 System.Web.Mvc.ActionFilterAttributeから派生した新しいクラスを追加します。 System.Web.Http.Filters.ActionFilterAttributeは次の例外を除いて失敗するため、これは重要です。 System.Web.Mvc.IAuthorizationFilter、 System.Web.Mvc.IActionFilter、System.Web.Mvc.IResultFilter、 システム:

所与のフィルタ・インスタンスは、以下 フィルタインターフェースの一つ以上を実装しなければなりません。 Web.Mvc.IExceptionFilter、 System.Web.Mvc.Filters.IAuthenticationFilter。デバッグウィンドウにリクエストを書き込み

例:FilterConfig

public class DebugActionFilter : System.Web.Mvc.ActionFilterAttribute 
{ 
    public override void OnActionExecuting(ActionExecutingContext actionContext) 
    { 
    Debug.WriteLine(actionContext.RequestContext.HttpContext.Request); 
    } 
} 

- >RegisterGlobalFilters - >次の行を追加しますfilters.Add(new DebugActionFilter());を。

すべての着信要求をキャッチして変更できるようになりました。

関連する問題