ASP.NET MVC 4 перехватывает все входящие запросы

Есть ли способ для меня перехватить все входящие запросы к моему приложению ASP.NET MVC 4 и выполнить некоторый код, прежде чем продолжить запрос на указанный контроллер / действие?

Мне нужно запустить какой-нибудь пользовательский код авторизации с существующими сервисами, и чтобы сделать это правильно, мне нужно будет иметь возможность перехватывать все входящие запросы от всех клиентов, чтобы дважды проверить некоторые вещи с другим сервисом.

4 ответа

Решение

Самый правильный способ - создать класс, который наследует ActionFilterAttribute и переопределяет OnActionExecuting метод. Это может быть зарегистрировано в GlobalFilters в Global.asax.cs

Конечно, это будет только перехватывать запросы, которые на самом деле имеют маршрут.

Вы можете использовать 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>

Я думаю, что вы ищете это:

Application_BeginRequest()

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

Вы положили это в Global.asax.cs,

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

Я использую это в целях отладки, но я не уверен, насколько это хорошее решение для вашего случая.

Я не уверен насчет MVC4, но думаю, что он довольно похож на MVC5. Если вы создали новый веб-проект -> посмотрите в Global.asax и вы должны увидеть следующую строку FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); в методе Application_Start(),

RegisterGlobalFilters метод в файле FilterConfig.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());,

Теперь вы можете перехватывать все входящие запросы и изменять их.

Другие вопросы по тегам