Et kig på ASP.NETs Page klasse

Tags:    asp.net
Skrevet af Bruger #4522 @ 11.03.2009

Introduktion


Når en forespørgsel på en ASP.NET side - dvs. en side med endelsen .aspx sendes fra browseren til serveren er der i begyndelsen blot tale om en simpel HTTP pakke, men når serveren får fat i denne pakke, starter en proces hvis mål er at transformere pakken til et komplekst ASP.NET objekt.

En ASP.NET side kompileres dynamisk første gang den efterspørges. Det foregår ved at en hel række såkaldte køretidsmoduler sørger for at den indkomne HTTP pakke udvikles til et rendyrket .NET objekt: et ASP.NET objekt der nedarver fra Page klassen.

Næste trin er nu at ASP.NETs køretidssytem anvender dette objekt til at generere den 'markup' som skal sendes tilbage til browseren. I løbet af denne proces er der en række hændelser ASP.NET stiller til rådighed, og som programmøren kan håndtere såfremt nødvendigt. Dette er den såkaldte Page-livscyklus.

Alt dette skal vi kigge nærmere på i denne artikel.

Forudsætninger
Denne artikel henvender sig til ASP.NET programmører med en smule erfaring. Du behøver dog ikke være en ASP.NET ekspert for at kunne læse, forstår og drage nytte af denne tekst.

Webforms
I denne artikel beskæftiger vi os kun med hvad der nu kan kaldes "den gode gamle Webformsmodel", hvis nyeste version er ASP.NET 3.5. Webformsmodellen stiler mod at lade webudvikling minde om .NET desktopudvikling som i Winforms. For at få det til at lykkedes har man abstraheret en stor del af HTTP-modellen væk fra udvikleren. Målet var at simplificere webudviklingen, men virkeligheden viste sig hurtig at være en anden. Jo, Webformsmodellen er meget simpel - på overfladen. Alle end de mest simple ASP.NET webapplikationer kræver en stor viden om ASP.NET og dets Webforms model, og især om hele Page-klassen og dens livscyklus (som forklaret i denne artikel tilfældigvis). Så selvom ASP.NET er nem at lære, er det faktisk ganske kompliceret at mestre. For det andet er det meget svært med Webforms at benytte nogle af de mere populære udviklingsmetoder såsom test-dreven udvikling og unit-testing. For det tredje: "All non-trivial abstractions, to some degree, are leaky.". Med andre ord, selvom ASP.NET Webforms prøver at gemme nogle at HTTPs og HTMLs særheder, og gøre webudvikling til noget der minder om desktopudvikling, så vil virkeligheden nogle gange stikke sit grimme ansigt frem - og så kan der blive ballade. Især hvis det ligger i hænderne på en mindre kompetent udvikler.

Alt dette er nogle af grundende til at Microsoft lancerede ASP.NET MVC (som i skrivende stund er i beta). ASP.NET MVC prøver ikke at gemme nettets virkelighed, og er struktureret efter det kendte MVC designmønster.

ASP.NET Webforms er dog på ingen måde død - det er stadig meget populært, og vil blive understøttet i meget lang tid fremover. ASP.NET MVC er stadig den nye dreng i klassen, og er langt fra at være ligeså komplet som ASP.NET Webforms. Og i mange scenarier er Webforms mere velegnet end ASP.NET MVC.

Denne artikel handler udelukkende om ASP.NET Webforms.

Generering af Page-objektet


Når ASP.NET første gang modtager en forespørgsel på en side (med endelsen .aspx ), sker følgende: 1. sidens kildekode læses og danner grundlag for en dynamisk genereret klasse der nedarver fra enten Page eller en klasse der så selv nedarver fra Page. 2. Klassen kompileres til en assembly. 3. Denne assembly gemmes i en bestemt ASP.NET mappe på serveren.

Fremover vil forespørgelser på denne side springe alt dette over, og i stedet sendes videre til det pågældende lokalt gemte assembly. Hvis der i mellemtiden er sket nogle ændringer af den tilknyttede .aspx -side, kasseres den gemte assembly, og der genereres en ny. Det samme sker såfremt hele webapplikationen genstarter (en webapplikation kan genstarte af mange grunde, men to hyppige årsager er hvis der ændres i web.config filen, eller der kopieres en ny assembly over i dens Bin -mappe.).

Maskinrummet i IIS 6
For helt at forstå denne proces blive vi nød til at kigge på serveren (da ASP.NET er en serverteknologi er det vel ikke overraskende).

Såfremt din ASP.NET applikation hostes på en Windows version tidligere end Windows Server 2003 er din eneste mulighed IIS 5.0 modellen. Jeg antager, at de fleste vil benytte Windows Server 2003 eller 2008, i hvilket tilfælde IIS 6.0 modellen benyttes. I denne artikel beskæftiger vi os derfor kun med IIS 6.0 modellen. For at benytte IIS 6.0 modellen skal du også benytte ASP.NET 1.1 eller senere (hvis du bruger ASP.NET 1.0 på IIS 6.0 eller senere benyttes IIS 5.0 modellen).

De resurser som IIS stiller til rådighed er grupperet efter filtype. IIS videresender forespørgelser på en resurse til det modul som kender til en bestemt filtype. Disse moduler er såkaldte "ISAPI extensions".

ISAPI er en forkortelse for Internet Server Application Programming Interface, og er et API til IIS. Hvis man har rigtig meget tid (og kan lide kompleksitet), kan man lave web-sites ved brug af ISAPI (Microsoft udviklede før i tiden MSDN sitet i ISAPI, men er siden skiftet over til ASP.NET). ISAPI er ikke kun implementeret i IIS, men også i Apache (via mod_isapi ), så server webapplikationer udviklet til IIS kan også afvikles på Apache. En ISAPI extension er en applikation som kører på IIS. De er implementeret som DLLer, der så indlæses i en IIS-kontrolleret proces. ASP.NET er en sådanne IIS applikation, dvs. en ISAPI extension.

Når IIS modtager en forespørgsel på en .aspx -side indlæses ASP.NET modullet (som altså er en ISAPI extension implementeret i en DLL), og den tager over herfra. ASP.NET modullet hedder aspnet_isapi.dll.

Faktisk håndterer aspnet_isapi.dll flere filtyper end .aspx. Følgende liste opremser nogle af de filtyper som IIS lader aspnet_isapi.dll håndtere:

  • .asax : ASP.NET applikationsfiler, typisk global.asax.

  • .ascx : ASP.NET brugerkontrolfiler (dvs. de såkaldte user controls).

  • .ashx : HTTP handler.

  • .asmx : ASP.NET web services.

  • .aspx : De enkelte ASP.NET sider.

  • .axd : En anden type HTTP handler.



IIS 6.0 har et modul på kerneniveau som tager sig af at lytte efter HTTP forespørgelser. Denne driver hedder http.sys og den kommer aldrig i kontakt med noget tredjeparts kode, så dets (og IISs) stabilitet vil derfor ikke blive påvirket af program-crashes. http.sys sørger for at placere de enkelte forespørgelser i en kø i den korrekte applikationspulje (se mere om applikationspuljer nedenfor). Et andet modul, kaldet Web Administatiom Service (WAS) tager sig af at læse IIS metabase og informere http.sys om at oprette så mange køer som der er applikationspuljer.

IIS 6.0 modellen er centreret omkring w3wp.exe -processen, som er serverens arbejdshest. Denne proces deles af alle applikationer i samme applikationspulje (så hvis du har flere applikationspuljer har du flere instanser af w3wp.exe kørende). Ideen med applikationspuljer blev introduceret i IIS 6.0 for at indkapsle de enkelte virtuelle servere så kørslen af programmer i én pulje ikke kan berøre kørslen af programmer i en anden pulje. Så hvis et program får en proces til at "crashe" vil det kun påvirke dens egen applikatiohspulje, men ikke andre puljer eller selve serveren.

Det er denne proces, altså w3wp.exe, der indlæser aspnet_isapi.dll (den ISAPI extension vi har snakket en del om ovenfor), som efterfølgende indlæser .NET CLR og starter hele ASP.NET pipelinen som herefter tager sig af selve forespørgelsen.

WAS står for styringen af de forskellige w3wp.exe-processer. w3wp.exe sørger så for at hente de enkelte forespørgelser fra deres egen kø.

Lad os opsummere dette på listeform:

  1. WAS læser IIS metabase og initialiserer http.sys.

  2. WAS står for at oprette og genbruge w3wp.exe -processerne. Der oprettes ligeså mange som der er applikationspuljer.

  3. http.sys lytter efter HTTP forespørgelser.

  4. Når der kommer en HTTP forespørgsel, putter http.sys den i den korrekte applikationspuljes kø.

  5. De enkelte w3wp.exe-processer henter de forespørgelser der venter i deres kø.

  6. w3wp.exe sørger for at indlæse de nødvendige ISAPI moduler, f.eks. indlæses aspnet_isapi.dll hvis forespørgelsen er efter en ASP.NET side, og asp.dll hvis det er en gammeldags ASP side.

  7. ISAPI extension modullerne kan indlæse forskellige eksterne moduler såfremt det er nødvendigt. F.eks. indlæser aspnet_isapi.dll .NET CLR.




Hvad synes du om denne artikel? Giv din mening til kende ved at stemme via pilene til venstre og/eller lægge en kommentar herunder.

Del også gerne artiklen med dine Facebook venner:  

Kommentarer (1)

User
Bruger #16651 @ 09.10.11 21:11
Virkelig en yderst gennemarbejdet og flot artikel der gennemgår så mange detaljer! BRAVO!!
Du skal være logget ind for at skrive en kommentar.
t