ASP.NET MVC 4拦截所有传入的请求


78

在继续将请求继续发送到指定的控制器/操作之前,我是否有办法捕获到ASP.NET MVC 4应用程序的所有传入请求并运行一些代码?

我需要使用现有服务运行一些自定义身份验证代码,并且要正确执行此操作,我将需要能够拦截来自所有客户端的所有传入请求,以仔细检查其他服务中的某些内容。


Answers:


80

最正确的方法是创建一个继承ActionFilterAttribute和重写OnActionExecuting方法的类。然后可以在GlobalFilters中注册Global.asax.cs

当然,这只会拦截实际具有路由的请求。


9
唯一的(丑陋的)方式是protected void Application_BeginRequest(object sender, EventArgs e)
埃里克·飞利浦

1
好吧,我想您也可以创建一个HttpHandler并将其注册以捕获所有web.config文件,但这确实很肮脏:)
Yngve B-Nilsen 2012年

1
有没有一种方法可以从OnActionExecuting覆盖内强制重定向?
杰西

2
是的,您可以将filterContext.Result设置为RedirectResult
Yngve B-Nilsen

1
您可以将结果更改为您认为合适的任何类型的ActionResult
Yngve B-Nilsen 2012年

38

您可以使用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应用程序请求进入控制器之前捕获它们,则过滤是一种更好的方法。请参阅我的文章msdn.microsoft.com/en-us/library/gg416513(VS.98).aspx-我的示例具有不错的定时筛选器
RickAndMSFT

1
我建议不要使用这种方法,因为它使用runAllManagedModulesForAllRequests了性能下降。Application_BeginRequest似乎是获得结果的简单得多的方法
Quango 2015年

25

我认为您要搜索的是:

Application_BeginRequest()

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

你把它放进去了Global.asax.cs

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

我将其用于调试目的,但不确定如何为您的情况解决。


2

我不确定MVC4,但我认为它与MVC5非常相似。如果您已经创建了一个新的Web项目->查找Global.asax,您应该FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);在方法中 看到以下行Application_Start()

RegisterGlobalFiltersFilterConfig.cs位于文件夹中文件中的方法App_Start

正如@ YngveB-Nilsen所说,这ActionFilterAttribute是我认为的方法。添加一个从派生的新类System.Web.Mvc.ActionFilterAttribute。这很重要,因为System.Web.Http.Filters.ActionFilterAttribute它将失败,例如以下异常。

给定的筛选器实例必须实现以下筛选器接口中的一个或多个:System.Web.Mvc.IAuthorizationFilter,System.Web.Mvc.IActionFilter,System.Web.Mvc.IResultFilter,System.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());

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.