2012-07-30 118 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());

您现在可以捕获所有传入的请求,并对其进行修改。