ASP.NET MVC 4 przechwytuje wszystkie przychodzące żądania

Czy jest dla mnie sposób, aby złapać wszystkie przychodzące wnioski do mojego ASP.NET aplikacja MVC 4 i uruchomić jakiś kod przed kontynuacją żądania dalej do określonego kontrolera / akcji?

Muszę uruchomić jakiś niestandardowy kod auth z istniejącymi usługami i aby zrobić to poprawnie, muszę być w stanie przechwycić wszystkie przychodzące żądania od wszystkich klientów, aby dokładnie sprawdzić niektóre rzeczy z inną usługą.

Author: Jesse, 2012-07-30

4 answers

Najbardziej poprawnym sposobem byłoby utworzenie klasy, która dziedziczy actionfilterattribute i nadpisuje metodę OnActionExecuting. Można to następnie zarejestrować w GlobalFilters w Global.asax.cs

Oczywiście przechwyci to tylko żądania, które faktycznie mają trasę.

 74
Author: Yngve B-Nilsen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-07-30 17:57:09

Możesz użyć HttpModule, aby to osiągnąć. Oto przykład, którego używam do obliczenia czasu procesu dla wszystkich żądań:

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 */ }
    }

}

I tak się rejestruje moduł w sieci.Config:

<system.webServer>
    <modules runAllManagedModulesForAllRequests="true">
        <add name="PerformanceMonitorModule" type="Sample.HttpModules.PerformanceMonitorModule" />
    </modules>
<//system.webServer>
 37
Author: M. Mennan Kara,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-07-30 17:57:54

Myślę, że to, czego szukasz, to:

Application_BeginRequest()

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

Wkładasz to Global.asax.cs.

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

Używam tego do celów debugowania, ale nie jestem pewien, czy jest to dobre rozwiązanie dla Twojego przypadku.

 22
Author: user2173353,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-12-10 08:51:08

Nie jestem pewien co do MVC4, ale myślę, że jest on dość podobny do MVC5. Jeśli utworzyłeś nowy projekt WWW - > poszukaj w Global.asax i powinieneś zobaczyć następujący wiersz FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); w metodzie Application_Start().

RegisterGlobalFilters jest metodą w pliku FilterConfig.cs znajdującym się w folderze App_Start.

Jak powiedział @ YngveB-Nilsen ActionFilterAttribute jest to moim zdaniem droga do zrobienia. Dodaj nową klasę, która pochodzi z System.Web.Mvc.ActionFilterAttribute. Jest to ważne, ponieważ System.Web.Http.Filters.ActionFilterAttribute nie powiedzie się na przykład z następującym wyjątkiem.

The dana instancja filtra musi zaimplementować co najmniej jedną z następujących interfejsy filtrów: System.Www.Mvc.IAuthorizationFilter, System.Www.Mvc.IActionFilter, System.Www.Mvc.IResultFilter, System.Www.Mvc.IExceptionFilter, System.Www.Mvc.Filtry.IAuthenticationFilter.

Przykład zapisujący żądanie do okna debugowania:

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

W FilterConfig -> RegisterGlobalFilters -> Dodaj następujący wiersz: filters.Add(new DebugActionFilter());.

Możesz teraz przechwytywać wszystkie przychodzące żądania i modyfikować je.

 1
Author: Ogglas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-25 13:07:00