2012-07-30 122 views
67

有沒有辦法讓我趕上所有傳入的請求到我的ASP.NET MVC 4應用程序並運行一些代碼,然後繼續向指定的控制器/操作請求?ASP.NET MVC 4攔截所有傳入的請求

我需要運行與現有服務的一些自定義的授權碼,並正確地做到這一點,我需要能夠攔截來自所有客戶端的所有傳入的請求仔細檢查一些事情與其他服務。

+7

查看我的過濾文章http://msdn.microsoft.com/en-us/library/gg416513(VS.98).aspx – RickAndMSFT 2012-07-30 19:50:19

回答

70

最正確的方法是創建一個繼承ActionFilterAttribute並覆蓋OnActionExecuting方法的類。然後這個可以在GlobalFilters中註冊Global.asax.cs

當然,這隻會攔截實際有路由的請求。

+8

唯一的(難看的)otherway是'protected void Application_BeginRequest(object sender,EventArgs e )'。 – 2012-07-30 17:55:43

+1

好吧,我想你也可以創建一個HttpHandler的,並且註冊捕獲所有在web.config中,但這是真髒:) – 2012-07-30 17:56:35

+0

很好,謝謝!當足夠的時間過去後,將會標記爲答案。 – Jesse 2012-07-30 17:58:24

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 2012-07-30 19:51:33

+1

我不推薦這種方法,因爲它使用了'runAllManagedModulesForAllRequests'這是表現拖累。 'Application_BeginRequest'似乎是一種更簡單的方法來實現結果 – Quango 2015-12-23 13:52:54

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-Nilsen說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。

實施例,該請求寫入到調試窗口:

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

FilterConfig - >RegisterGlobalFilters - >添加下列行:filters.Add(new DebugActionFilter());

您現在可以捕獲所有傳入的請求,並對其進行修改。