Überblick:
Dieser Artikel basiert auf dem Quellcode von ASP.NET 2.0 und führt eine kurze Analyse der ASP.NET 2.0-Laufzeit durch. Ich hoffe, er kann Ihnen helfen, den Anforderungsverarbeitungsprozess und das Seitenkompilierungsmodell in ASP.NET 2.0 zu verstehen.
Schlüsselwörter:
ASP.NET 2.0-Laufzeit, Prinzipien, Anforderungsverarbeitung, Seitenkompilierung, ASP.NET 2.0 HTTP-Laufzeit-
Hauptklassen:
System.Web.HttpRuntime
System.Web.HttpApplicationFactory
System.Web.HttpApplication
System.Web.Compilation.BuildManager
System.Web.Compilation.ApplicationBuildProvider
System.Web.Compilation.BuildProvidersCompiler
System.Web.UI.PageHandlerFactory
Kurzes Flussdiagramm der Anfragebearbeitung:
Lesevorschläge:
Verwenden Sie das Reflector-Tool, um den Quellcode von ASP.NET 2.0 beim Lesen anzuzeigen.
analysieren:
Wenn wir über den Browser eine Anfrage an eine asp.net-Seite auf der ASP.NET 2.0-Website initiieren, empfängt IIS die Anfrage zuerst auf der Serverseite. Wenn IIS erkennt, dass es sich um eine asp.net-Seite handelt, bin ich darüber sehr glücklich Die Anfrage muss nicht von ihr verarbeitet werden, überlassen Sie sie einfach ASP.NET ISAPI. Die Arbeit von ASP.NET ISAPI ist auch relativ einfach. Seine Hauptaufgabe besteht darin, die Verarbeitung von Anforderungen durch aspnet_wp.exe zu veranlassen und die Ausführung des aspnet_wp.exe-Prozesses zu überwachen Nun, ASP.NET ISAPI wird ihn entlassen und durch eine neue aspnet_wp.exe ersetzen, um die Arbeit zu erledigen.
Die Hauptaufgabe von aspnet_wp.exe besteht darin, Anforderungen an eine Reihe verwalteter Objekte, sogenannte HTTP-Pipelines, zu übergeben. Wenn ASP.NET ISAPI mit einem Vertriebsmanager verglichen wird, ist aspnet_wp.exe der Produktionsmanager und die HTTP-Pipeline die Produktionspipeline. Das für die Montagelinie verantwortliche Team ist HttpRuntime. Der Produktionsmanager wird den Auftrag (HTTP-Anfrage) an das HttpRuntime-Teammitglied ProcessRequest (HttpWorkerRequest wr) übergeben, das schließlich von ProcessRequestInternal (HttpWorkerRequest wr) produziert wird ) entsprechend der internen Arbeitsteilung, daher steht ProcessRequestInternal(HttpWorkerRequest wr) im Mittelpunkt unserer Analyse.
Die Hauptarbeit von ProcessRequestInternal ist:
1. Erstellen Sie eine HttpContext-Instanz.
2. Initialisieren Sie die erste Anfrage (EnsureFirstRequestInit).
a) Führen Sie einige Initialisierungsarbeiten in ConsiderFirstRequestInit durch, indem Sie System.Web.HttpRuntime.FirstRequestInit aufrufen, z. B. das Einlesen der Web.Config-Konfiguration in RuntimeConfig und das Laden aller DLL-Dateien aus dem bin-Verzeichnis.
3. Erstellen Sie eine HttpWriter-Instanz.
4. Erstellen Sie eine HttpApplication-Instanz, indem Sie HttpApplicationFactory.GetApplicationInstance aufrufen.
Es gibt drei Schlüsselmethoden in HttpApplicationFactory.GetApplicationInstance:
HttpApplicationFactory._theApplicationFactory.EnsureInited();
HttpApplicationFactory._theApplicationFactory.EnsureAppStartCalled(context);
HttpApplicationFactory._theApplicationFactory.GetNormalApplicationInstance(context);
analysieren wir diese drei Methoden nacheinander:
1) HttpApplicationFactory._theApplicationFactory.EnsureInited();
Diese Methode prüft, ob HttpApplicationFactory initialisiert wurde. Wenn nicht, wird sie über HttpApplicationFactory.Init() initialisiert.
Rufen Sie in Init() zunächst den vollständigen Pfad der Datei global.asax ab und rufen Sie dann CompileApplication() auf, um global.asax zu kompilieren.
Wie erfolgt die Kompilierung?
Die Kompilierungsarbeit wird von BuildManager abgeschlossen. BuildManager ruft zuerst den GlobalAsaxType (also HttpApplication) ab und ruft dann BuildManager.GetGlobalAsaxBuildResult() =》GetGlobalAsaxBuildResultInternal() =》EnsureTopLevelFilesCompiled() zur Kompilierung auf.
In IndeedTopLevelFilesCompiled wird zuerst CompilationStage.TopLevelFiles kompiliert und die Dateien in den folgenden drei Verzeichnissen werden kompiliert:
a. CompileResourcesDirectory();
Kompilieren Sie das Verzeichnis App_GlobalResources.
b. CompileWebRefDirectory();
Kompilieren Sie das Verzeichnis App_WebReferences.
c. CompileCodeDirectories();
Kompilieren Sie das App_Code-Verzeichnis.
Dann kompilieren Sie CompilationStage.GlobalAsax, kompilieren Sie global.asax und rufen Sie die Methode auf: CompileGlobalAsax()=》ApplicationBuildProvider.GetGlobalAsaxBuildResult(BuildManager.IsPrecompiledApp).
Die spezifische Kompilierung in GetGlobalAsaxBuildResult wird durch ApplicationBuildProvider und BuildProvidersCompiler abgeschlossen.
BuildProvidersCompiler.PerformBuild(); führt Kompilierungsarbeiten durch.
ApplicationBuildProvider.GetBuildResult ruft das kompilierte Ergebnis ab.
Nach erfolgreicher Kompilierung wird eine DLL-Datei ähnlich App_global.asax.mlgx7n2v.dll im entsprechenden Verzeichnis von C:WINDOWSMicrosoft.NETFrameworkv2.0.50727Temporary ASP.NET Files generiert.
Die kompilierte Klasse heißt ASP.global_asax und erbt von HttpApplication.
Hinweis: Wenn im Webverzeichnis keine Global.asax-Datei vorhanden ist, werden Dateien wie App_global.asax.mlgx7n2v.dll nicht kompiliert und generiert.
2) HttpApplicationFactory._theApplicationFactory.EnsureAppStartCalled(context);
Erstellen Sie eine bestimmte HttpApplication-Instanz, lösen Sie das ApplicationOnStart-Ereignis aus und führen Sie die Methode Application_Start(object sender, EventArgs e) in ASP.global_asax aus. Die hier erstellte HttpApplication-Instanz wird nach der Verarbeitung des Ereignisses recycelt.
3) HttpApplicationFactory._theApplicationFactory.GetNormalApplicationInstance(context);
Diese Methode erstellt eine HttpApplication-Instanz und initialisiert sie (Aufruf der System.Web.HttpApplication.InitInternal()-Methode).
Das Erstellen einer HttpApplication-Instanz basiert auf dem tatsächlichen _theApplicationType. Wenn im Webverzeichnis keine Datei global.asa vorhanden ist, dh keine dynamische Kompilierung zum Generieren des Typs ASP.global_asax vorhanden ist, wird HttpApplication direkt instanziiert. Wenn der Typ ASP.global_asax erstellt wird, instanziieren Sie ASP.global_asa.
Rufen Sie nach dem Erstellen der HttpApplication-Instanz die InitInternal-Methode der Instanz auf.
Die InitInternal-Methode ist auch die Methode, auf die wir uns konzentrieren. Die Hauptfunktionen dieser Methode sind wie folgt:
1. InitModules(): Erstellen Sie entsprechende HttpModules gemäß den Einstellungen von Web.Config.
2. HookupEventHandlersForAppplicationAndModules: Rufen Sie basierend auf dem auftretenden Ereignis die entsprechende Ereignisverarbeitungsfunktion in der HttpApplication-Instanz auf.
3. Erstellen Sie viele Instanzen von Klassen, die die IExecutionStep-Schnittstelle implementieren, fügen Sie sie zu _execSteps der aktuellen HttpApplication-Instanz hinzu und warten Sie auf die Rückrufausführung. Von hier aus können wir sehen, dass HttpApplication Anforderungen asynchron verarbeitet und viele Verarbeitungsaufgaben für Anforderungen in _execStep abgelegt werden, um auf die Ausführung des Rückrufs zu warten.
Die Hauptverarbeitungsarbeit in _execStep ist wie folgt:
1) Führen Sie eine Sicherheitsüberprüfung des angeforderten Pfads durch und verhindern Sie den Zugriff auf illegale Pfade (ValidatePathExecutionStep).
2) Wenn UrlMappings festgelegt ist, führen Sie RewritePath(UrlMappingsExecutionStep) aus.
3) Führen Sie Ereignisverarbeitungsfunktionen aus, z. B. BeginRequest, AuthenticateRequest usw.
4) Rufen Sie den HttpHandler ab, der die aktuelle Anforderung verarbeitet. Hier wird auch die Laufzeitkompilierung der ASP.NET-Seite durchgeführt. (MapHandlerExecutionStep)
Diese Verarbeitung erfolgt durch Aufrufen der System.Web.HttpApplication.MapHttpHandler-Methode.
Rufen Sie in MapHttpHandler zunächst den entsprechenden Typ ab, der IHttpHandlerFactory entsprechend der Zugriffsadresse aus web.config implementiert. Für asp.net-Seiten ist der Standardwert PageHanlderFactory. Erstellen Sie dann eine PageHanlderFactory-Instanz, rufen Sie GetHandlerHelper auf, rufen Sie BuildManager.CreateInstanceFromVirtualPath in GetHandlerHelper auf, um eine Instanz der aktuell angeforderten ASP.NET-Seite zu kompilieren und zu erstellen (wenn sie kompiliert wurde, laden Sie sie direkt aus dem Cache).
CreateInstanceFromVirtualPath übergibt die Kompilierungsaufgabe nach mehreren Methodenaufrufen an BuildManager. CompileWebFile ruft den entsprechenden BuildProvider aus web.config ab. Für ASPX-Dateien ist der entsprechende BuildProvider PageBuildProvider. Wie PageBuildProvider Seiten kompiliert, wird hier nicht weiter analysiert. Wenn Sie interessiert sind, können Sie den Quellcode von ASP.NET 2.0 weiter studieren.
5) Rufen Sie die .ProcessRequest-Methode des entsprechenden HttpHandlers auf, um die Anforderung zu verarbeiten (wenn sie asynchron ist, rufen Sie BeginProcessReques auf). (CallHandlerExecutionStep)
6) Schreiben Sie den Antwortinhalt in Filter. (CallFilterExecutionStep)
5. Rufen Sie BeginProcessRequest der HttpApplication-Instanz auf, um die Anforderung asynchron zu verarbeiten.
Viele der oben erwähnten Dinge, die in _execSteps passieren, werden ausgeführt, nachdem HttpRuntime HttpApplication BeginProcessRequest aufruft und dann ResumeSteps in BeginProcessRequest aufruft.
Die ASP.NET 2.0-Laufzeit ist ein sehr komplexer, schwer verständlicher und wichtiger Teil von ASP.NET 2.0. Das Studium des ASP.NET 2.0-Laufzeit-Quellcodes wird uns helfen, unser Verständnis der Prinzipien von ASP.NET 2.0 zu vertiefen Die Entwicklung von ASP.NET 2.0-Anwendungen bringt uns viel Hilfe. In diesem Artikel lerne ich zum ersten Mal die ASP.NET 2.0-Laufzeit. Er soll mir helfen, die ASP.NET 2.0-Laufzeit besser zu verstehen. Sie können gerne Kritik zum Inhalt des Artikels äußern.
Ich bin der Meinung, dass das Schreiben von Artikeln nicht nur die Schreibfähigkeiten verbessern und die Kommunikation erleichtern kann, sondern dass man durch das Schreiben von Artikeln auch seine eigenen Ideen klären, tiefgreifendes Denken fördern und sein Verständnis für Technologie vertiefen kann. Entwickler können sich eine Auszeit vom Programmieren nehmen . Das Schreiben einiger technischer Artikel ist immer noch sehr hilfreich, um sich zu verbessern.