ASP.NET MVC 4 fängt alle eingehenden Anforderungen ab

78

Gibt es eine Möglichkeit für mich, alle eingehenden Anforderungen an meine ASP.NET MVC 4-App abzufangen und Code auszuführen, bevor die Anforderung an den angegebenen Controller / die angegebene Aktion weitergeleitet wird?

Ich muss einen benutzerdefinierten Authentifizierungscode mit vorhandenen Diensten ausführen. Um dies ordnungsgemäß ausführen zu können, muss ich in der Lage sein, alle eingehenden Anforderungen aller Clients abzufangen, um einige Dinge mit dem anderen Dienst zu überprüfen.

Jesse
quelle

Antworten:

80

Am korrektesten wäre es, eine Klasse zu erstellen, die die ActionFilterAttribute- und Override- OnActionExecutingMethode erbt . Dies kann dann in der registriert wird GlobalFiltersinGlobal.asax.cs

Dies fängt natürlich nur Anforderungen ab, die tatsächlich eine Route haben.

Yngve B-Nilsen
quelle
10
Der einzige (hässliche) andere Weg ist der protected void Application_BeginRequest(object sender, EventArgs e).
Erik Philips
1
Nun, ich denke, Sie könnten auch einen HttpHandler erstellen und diesen registrieren, um alles in web.config zu fangen, aber das ist wirklich schmutzig :)
Yngve B-Nilsen
1
Gibt es eine Möglichkeit, eine Umleitung innerhalb der OnActionExecutingÜberschreibung zu erzwingen ?
Jesse
2
Ja, Sie können das filterContext.Result auf ein RedirectResult setzen
Yngve B-Nilsen
1
Sie können das Ergebnis in eine beliebige Art von ActionResult ändern, die Sie für richtig halten
Yngve B-Nilsen
38

Sie können ein HttpModule verwenden, um dies zu erreichen. Hier ist ein Beispiel, mit dem ich die Prozesszeit für alle Anfragen berechne:

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

}

Und so registrieren Sie das Modul in Web.Config:

<system.webServer>
    <modules runAllManagedModulesForAllRequests="true">
        <add name="PerformanceMonitorModule" type="Sample.HttpModules.PerformanceMonitorModule" />
    </modules>
<//system.webServer>
M. Mennan Kara
quelle
3
Wenn das Ziel darin besteht, MVC-App-Anforderungen zu erfassen, bevor sie an den Controller gesendet werden, ist das Filtern ein viel besserer Ansatz. Siehe meinen Artikel msdn.microsoft.com/en-us/library/gg416513(VS.98).aspx - mein Beispiel hat einen schönen Timing-Filter
RickAndMSFT
1
Ich würde gegen diesen Ansatz empfehlen, da er runAllManagedModulesForAllRequestseinen Leistungsverlust verwendet. Application_BeginRequestscheint ein viel einfacherer Weg zu sein, um das Ergebnis zu erzielen
Quango
25

Ich denke, was Sie suchen, ist Folgendes:

Application_BeginRequest()

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

Du hast es reingelegt Global.asax.cs.

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

Ich verwende dies zum Debuggen, bin mir aber nicht sicher, wie gut es für Ihren Fall ist.

user2173353
quelle
2

Ich bin mir bei MVC4 nicht sicher, aber ich denke, es ist MVC5 ziemlich ähnlich. Wenn Sie ein neues Webprojekt erstellt haben -> schauen Global.asaxSie hinein und Sie sollten die folgende Zeile FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);in der Methode sehen Application_Start().

RegisterGlobalFiltersist eine Methode in der Datei FilterConfig.csim Ordner App_Start.

Wie @ YngveB-Nilsen sagte, ActionFilterAttributeist meiner Meinung nach der richtige Weg. Fügen Sie eine neue Klasse hinzu, die von abgeleitet ist System.Web.Mvc.ActionFilterAttribute. Dies ist wichtig, da dies System.Web.Http.Filters.ActionFilterAttributebeispielsweise mit der folgenden Ausnahme fehlschlägt.

Die angegebene Filterinstanz muss eine oder mehrere der folgenden Filterschnittstellen implementieren: System.Web.Mvc.IAuthorizationFilter, System.Web.Mvc.IActionFilter, System.Web.Mvc.IResultFilter, System.Web.Mvc.IExceptionFilter, System.Web .Mvc.Filters.IAuthenticationFilter.

Beispiel, das die Anforderung in das Debug-Fenster schreibt:

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

Fügen Sie in FilterConfig-> RegisterGlobalFilters-> die folgende Zeile hinzu : filters.Add(new DebugActionFilter());.

Sie können jetzt alle eingehenden Anforderungen abfangen und ändern.

Ogglas
quelle