Per capire a fondo come utilizzare al meglio ASP.NET risulta necessario conoscere il funzionamento base del web: come avviene una richiesta dal browser verso il server, quali sono le tecnologie utilizzate e come un server web elabora una richiesta.

Capire perché una pagina web non viene interpretata nel modo giusto da un browser, perché una richiesta non viene eseguita come ci si aspetta, generare il giusto codice HTML da un controllo personalizzato, sono questioni che non dipendono solo dalla conoscenza di ASP.NET (o qualsiasi altra tecnologia utilizzata), ma anche dalla conoscenza del funzionamento di un’applicazione web.

HTTP Request e Response

Il protocollo HTTP (HyperText Transfer Protocol) nasce come meccanismo per trasferire i documenti definiti come HyperText. Gli HyperText sono documenti messi in relazione tra loro tramite parole chiave cliccabili, ovvero collegamenti ipertestuali (hyperlink).

Attualmente però, un hypertext è diventato ben più complesso, ed i collegamenti non sono più solo testuali, ma posso essere anche immagini; i documenti hypertext si sono trasformati in documenti multimediali ed anche il protocollo si è aggiornato, anche per sopperire ad alcuni limiti della prima versione, tra cui la mancanza di meccanismi di sicurezza.

Il suo funzionamento rimane sempre il medesimo: una risposta a fronte di una richiesta (client/server);
il client (un browser) effettua una richiesta per una risorsa aprendo una connessione al server (web server) che risponde inviando la risorsa e la connessione viene chiusa.
Una richiesta HTTP avviene tramite comandi stabiliti dal protocollo, tra cui GET, POST, HEAD. Vediamo un esempio:
richiamiamo dal browser una pagina: http://localhost:80/Hello.html

Ecco la richiesta HTTP che il browser invia al server “localhost”:

GET /Hello.html HTTP/1.1
Host: localhost:80
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:6.0.2) Gecko/20100101 Firefox/6.0.2
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: it-it,it;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Connection: keep-alive

Ciò che ci interessa maggiormente è rappresentato dalla prima riga che specifica il comando GET utilizzato, la risorsa richiesta, il protocollo/versione utilizzato, e dalla seconda riga che specifica il server verso il quale viene eseguita la richiesta. Tutto il resto è superfluo per il nostro scopo.

Il server riceve la richiesta e la elabora: in questo caso il server cercherà la risorsa indicata e la invierà nella Response verso il client. Ecco come è fatta la Response:

HTTP/1.1 200 OK
Content-Type: text/html
Last-Modified: Wed, 06 Jul 2011 15:53:21 GMT
Accept-Ranges: bytes
Etag: "9259e2d4f43bcc1:0"
Server: Microsoft-IIS/7.5
X-Powered-By: ASP.NET
Date: Sat, 15 Oct 2011 16:28:52 GMT
Content-Length: 130
<html>
    <body>
        <h1> Hello World </h1>
    </body>
</html>

Il browser riceve la Response e mostra la risorsa. In questo caso è una semplicissima pagina HTML, quindi il browser farà il render del codice HTML per renderlo visibile.

Il funzionamento è molto elementare, quindi inutile dilungarsi oltre.

Biglietti per Vasco Rossi

Chi risponde a questa richiesta?

Il server.

Beh, ora si che c’è bisogno di spiegare… Occhiolino
Nei tempi antichi, esistevano le applicazioni CGI … …
no, forse sono partito da troppo lontano!!

Parliamo dei giorni d’oggi, e soprattutto della piattaforma Microsoft. La soluzione è un servizio (deamon process) che sta in ascolto sulla porta 80 (default) e processa le richieste. Stiamo parlando di IIS (Internet Information Services).

Come si comporta IIS per rispondere alle richieste?
Tramite configurazione viene fatta una mappatura tra le estensioni dei file ed estensioni di IIS, che sono tipicamente DLL esterne chiamate ISAPI DLLs (Internet Services Application Programming Interface). Quando arriva una richiesta al server, viene dunque esaminata l’estensione del file, quindi la richiesta può essere gestita direttamente da IIS (esempio un file JPG o HTML o qualsiasi altro file statico, viene letto e spedito direttamente sulla Response) o indirizzata ad una particolare estensione ISAPI. Questo è il caso dei file .aspx.

Mapping moduli ISAPI

Mapping moduli ISAPI

Le richieste che riguardano file .aspx vengono processate dunque dall’extension aspnet_isapi.dll, che a sua volta rimanda l’esecuzione dal motore ASP.NET del framework alla pipeline HTTP di APS.NET. In maniera simile alla configurazione di IIS, il motore ASP.NET mappa le richieste con specifici HTTP Handlers. Questi gestori non sono altro che “pezzi di codice” che si preoccupano di generare il codice HTML da rimandare nel Response.

La configurazione per questi meccanismi la si può trovare nel file web.config presente nella cartella del framework in uso: $WINDOWS$\Microsoft.NET\Framework\$VERSION$\CONFIG

Qui di seguito e mostrata la configurazione di default per gli handler:

...
<httpHandlers>
      ...
      ...
      <add path="*.svc" verb="*" type="System.ServiceModel.Activation.HttpHandler, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" validate="false"/>
      <add path="trace.axd" verb="*" type="System.Web.Handlers.TraceHandler" validate="True"/>
      <add path="WebResource.axd" verb="GET" type="System.Web.Handlers.AssemblyResourceLoader" validate="True"/>
      <add path="*.axd" verb="*" type="System.Web.HttpNotFoundHandler" validate="True"/>
      <add path="*.aspx" verb="*" type="System.Web.UI.PageHandlerFactory" validate="True"/>
      <add path="*.ashx" verb="*" type="System.Web.UI.SimpleHandlerFactory" validate="True"/>
      <add path="*.asmx" verb="*" type="System.Web.Services.Protocols.WebServiceHandlerFactory, System.Web.Services, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" validate="False"/>
      ...
      ...
 </httpHandlers>
...
Pipeline ASP.NET

Pipeline ASP.NET

Come si può notare nella figura sottostante, per le pagine .aspx è richiamato il gestore PageHandlerFactory, che si occupa di cercare la classe compilata della pagina richiesta (se non esiste compila al volo la pagina ed il suo codice) ed invocarla. La pagina invocata (ovvero il codice che abbiamo scritto noi nella pagina aspx unito al code behind) si occupa quindi di generare il codice HTML (metodo render) ed inviarlo come output nel buffer della response.

Riferimenti

http://www.4guysfromrolla.com/articles/011404-1.aspx
http://www.15seconds.com/issue/020417.htm
http://msdn.microsoft.com/en-us/library/aa479328.aspx

<br>