ASP CGI JSP ASP: Applications
ASP CGI JSP ASP: Applications
Microsoft Active Server Pages, also known as ASP, since its first release in late 1996 provided
web developers with a rich and complex framework for building web applications. As years
passed its infrastructure evolved and improved so much that what is now known as ASP.NET is
no longer something which resembles its predecessor. ASP.NET is a framework for building web
applications, that is, applications that run over the web, where the client-server paradigm is
represented mostly by a browser forwarding requests for resources of different kinds to a web
server. Before the advent of dynamic server-side resource generation techniques like CGI, PHP,
JSP and ASP, all web servers had to do was accept client’s requests for static resources and
forward them to the requestor. When dynamic technologies started to grow up web servers
became invested of greater responsibility, since they had to find a way to generate those
dynamic resources on their side and return the result to the client, a task they were not formerly
built for.
From a bird’s eye view, the interaction between client and server is very simple. Communications
over the web occur via HTTP (Hyper Text Transfer Protocol), an application level protocol which
relies on TCP and IP to transmit data between two nodes connected to the heterogeneous
network known as World Wide Web.
Different servers chose different ways to generate and serve dynamic resources and what we’re
going to examine is how IIS does that, together with the path a request follows once on the
server and back to the client.
As mentioned, static resources needn’t to be processed by the server; once a request for such a
resource arrives, the server just retrieves its contents from the file system and sends it back to
the client as a stream of byte flowing on the HTTP protocol. Static resources can be images,
Javascript files, css style sheets or plain old html pages. It’s clear that the server needs to know
how to distinguish between static and dynamic resource, whereas the second need to be
processed somehow and not just sent back to the client. That’s where ISAPI extensions appear,
where ISAPI stands for Internet Server Application Programming Interface. ISAPI extensions
are modules implemented as plain old Win32 .dll, on which IIS relies to process specific
resources. Mappings between ISAPI extensions and files are configured via the IIS snap-in
and stored in the IIS metabase, where each file extension can be associated with a particular
ISAPI extension, that is, when a request for such a file arrives, IIS handles it to the
corresponding ISAPI extension, confident that it will be able to handle it.
As Figure 1 illustrates, the .asp extension is mapped to the asp.dll ISAPI extension; at the
time of ASP this component was in charge of performing all the tasks required to generate a
response, that is, collecting information about the request, made available into the ASP page via
the Request, Response and other common ASP intrinsic objects, parsing and executing the ASP
page and returning the resulting HTML.
Actually, that was a big improvement compared to a technology like CGI, but ASP.NET takes
this approach much further and introduces abstractions which totally shield the developers from
having to care about what happens at this stage.
When installed, ASP.NET configures IIS to redirect requests for ASP.NET specific files to a
new ISAPI extension called aspnet_isapi.dll. What this extension does is somewhat
different then the former asp.dll extension, which was essentially responsible just for parsing
and executing the requested ASP page. The steps taken by a generic ISAPI module to process
a request are totally hidden from IIS, therefore ISAPI extension may follow different
paradigms in order to process requests.
As well as the file extensions listed in Table 1, the ASP.NET ISAPI extension manages other
file extensions which are usually not served to web browsers, like Visual Studio project files,
source code files and config files, for example.
So far we’ve seen that when a request for an ASP.NET file is picked up by IIS, it is passed to
the aspnet_isapi.dll, which is the main entry point for ASP.NET related processing.
Actually, what the ISAPI extension does depends sensibly on the version of IIS available on
the system, and thus the process model, which is the sequence of operations performed by the
ASP.NET runtime to process the request and generate a response, may vary quite a bit.
When running under IIS 5.X, all ASP.NET-related requests are dispatched by the ISAPI
extension to an external worker process called aspnet_wp.exe. The ASP.NET ISAPI
extension, hosted in the IIS process inetinfo.exe, passes the control to
aspnet_wp.exe, along with all the information concerning the incoming request. The
communication between the two is performed via named pipes, a well known mechanism for IPC
(Inter Process Communication). The ASP.NET worker process performs a considerable number
of tasks, together with the ISAPI extension. They are the main authors of all the stuff that
happens under the hoods of an ASP.NET request. To introduce a topic which will be discussed
later, take note of the fact that each web application, corresponding to a different virtual
directory hosted on IIS, is executed in the context of the same process, the ASP.NET worker
process. To provide isolation and abstraction from the execution context the ASP.NET model
introduces the concept of Application Domains, in brief AppDomains. They can be considered as
lightweight processes. More on this later.
If running under IIS 6, on the other side, the aspnet_wp.exe process is not used, in favour
of another process called w3wp.exe. Furthermore, inetinfo.exe is no longer used to
forward HTTP requests to ISAPI extensions, although it keeps running for serving other
protocols requests. A lot of other details change compared to the process model used by
previous versions of IIS, although IIS 6 is capable of running in compatibility mode and
emulate the behavior of its predecessor. A big step forward, compared to the process model
used when running on top of IIS 5, is that incoming requests are in the former handled at a
lower – Kernel – level and then forwarded to the correct ISAPI extension, thereby avoiding
inter process communication techniques which may represent an expensive operation under a
performance and resource consumption point of view. We’ll delve deeper into this topic in the
following paragraphs.
This is the default process model available on Windows 2000 and XP machines. As mentioned it
consists in the IIS inetinfo.exe process listening by default on the TCP port 80 for
incoming HTTP requests and queuing them into a single queue, waiting to be processed. If the
request is specific to ASP.NET, the processing is delegated to the ASP.NET ISAPI extension,
aspnet_isapi.dll. This, in turn, communicates with the ASP.NET worker process,
aspnet_wp.exe via named pipes and finally is the worker process which takes care of
delivering the request to the ASP.NET HTTP runtime environment. This process is graphically
represented in Figure 2.
In Figure 2 is represented an additional element we didn’t mention yet, the ASP.NET HTTP
Runtime Environment. It’s not topic of this article and will eventually be explained in a follow up
article, but for the sake of this discussion the HTTP Runtime Environment can be considered as a
black box where all the ASP.NET specific processing takes place, all the managed code lives and
developers can actually put their hands on, from the HttpRuntime straight to the HttpHandler
who will finally process the request and generate the response. This is even referred to as the
ASP.NET Pipeline or HTTP Runtime pipeline.
One of the interesting points of this process model is that all the requests, once handled by the
ISAPI extension, are passed to the ASP.NET worker process. Only one instance of this process
is active at a time, with one exception, discussed later. Therefore all ASP.NET web applications
hosted on IIS are actually hosted inside the worker process, too. However, this doesn’t mean
that all the applications are run under the same context and share all their data. As mentioned,
ASP.NET introduces the concept of AppDomain, which is essentially a sort of managed
lightweight process which provides isolation and security boundaries. Each IIS virtual directory
is executed in a single AppDomain, which is loaded automatically into the worker process
whenever a resource belonging to that application is requested for the first time. Once the
AppDomain is loaded – that is, all the assemblies required to satisfy that request are loaded into
the AppDomain – the control is actually passed to the ASP.NET pipeline for the actual
processing. Multiple AppDomains can thus run under the same process, while requests for the
same AppDomain can be served by multiple threads. However, a thread doesn’t belong to an
AppDomain and can serve requests for different AppDomains, but at a given time a thread
belongs to a single AppDomain.
For performance purposes the worker process can be recycled according to some criteria which
can be specified declaratively in the machine.config file placed in the directory
C:\windows\microsoft.net\Framework\[framework version]\CONFIG. These criteria are the age
of the process, number of requests served and queued, time spent idle and consumed memory.
Once one of the threshold value of these parameters is reached, the ISAPI extension creates a
new instance of the worker process, which will we used from then on to serve the requests. This
is the only time when multiple copies of the process can be running concurrently. In fact, the old
instance of the process isn’t killed, but it is allowed to terminate serving the pending requests.
The IIS 6 process model is the default model on machines running Windows 2003 Server
operating system. It introduces several changes and improvements over the IIS 5 process
model. One of the biggest changes is the concept of application pools. On IIS 5.X all web
applications, that is, all AppDomains, were hosted by the ASP.NET worker process. To achieve a
finer granularity over security boundaries and personalization, the IIS 6 process model allows
applications to run inside different copies of a new worker process, w3wp.exe. Each application
pool can contain multiple AppDomains and is hosted in a single copy of the worker process. In
other words, the shift is from a single process hosting all applications to multiple processes
hosting each an application pool. This model is also called the worker process isolation mode.
Another big change from the previous model is the way IIS listens for incoming requests. With
the IIS 5 model, it was the IIS process, inetinfo.exe, who was listening on a specific TCP
port for HTTP requests. In the IIS 6 architecture, incoming requests are handled and queued at
kernel level instead of user mode via a kernel driver called http.sys; this approach has several
advantages over the old model and is called kernel-level request queuing.
It’s the worker process who is in charge of loading the ASP.NET ISAPI extension, which, in
turn, loads the CRL and delegates all the work to the HTTP Runtime.
The w3wp.exe worker process, differently from the aspnet_wp.exe process used in IIS 5
model, isn’t ASP.NET specific, and is used to handle any kind of requests. The specific worker
process then decides which ISAPI modules to load according to the type of resources it needs
to serve.
A detail not underlined in Figure 3 for simplicity reasons is that incoming requests are forwarded
from the application pool queue to the right worker process via a module loaded in IIS 6 called
Web Administration Service (WAS). This module is responsible for reading worker process – web
application bindings from the IIS metabase and forwarding the request to the right worker
process.
References
Simone Busoli - ASP.NET Internals - The bridge between ISAPI and Application Domains
BrainBell.com – ASP.NET Application Fundamentals
Dino Esposito – Programming Microsoft ASP.NET 2.0 Core Reference
Dino Esposito – Programming Microsoft ASP.NET 2.0 Applications Advanced Topics
George Shepherd – IIS 6.0: New Features Improve Your Web Server's Performance,
Reliability, and Scalability
Fritz Onion – ASP.NET Pipeline: Use Threads and Build Asynchronous Handlers in Your
Server-Side Web Code
Tim Ewald and Keith Brown – HTTP Pipelines: Securely Implement Request Processing,
Filtering, and Content Redirection with HTTP Pipelines in ASP.NET
This author has published 9 articles on DotNetSlackers. View other articles or the
complete profile here.
Home
Articles
Software
Table of Contents
Introduction
HTTP
HTTP Clients
The Web Server - IIS
The ASP.NET Framework
Conclusion
Introduction
The purpose of this document is to provide a very thorough explanation of what
happens during an HTTP request to an ASP.NET page being served up through
IIS. It starts out with the basics but then dives in to the gory details, more
detail than is probably needed for basic web page development. However a
thorough knowledge of this process is invaluable when debugging strange
problems, developing ASP.NET custom web controls or developing any sort of
web framework.
HTTP
It is important to understand that HTTP is the only method that a client (e.g.
browser) uses to communicate with a web server. The client runs on one
computer and the server on another. The client connects a socket to the server
and sends an HTTP request. The server does some processing and returns an
HTTP response. That's it. IIS Applications, ASP.NET, .NET HTTP Modules, AJAX,
Web Services, etc. are all just abstractions on this concept. A deep
understanding any web technology requires a good working knowledge of HTTP.
HTTP Request
The good news is that HTTP is quite simple. At heart HTTP has two concepts - a
request and a response. Let's look at a sample HTTP request that would be sent
from a browser to a web server:
The most important line is the first one. It says that we're doing a GET request
for the Default.aspx page in the web root. The URL for this request was
"http://localhost/Default.aspx". The only other option besides GET is POST.
There is some confusion about the difference between GET and POST. Some
say that GET is used to get information from the server and POST is used to
send information to the server. Although this describes typical usage it is not
strictly true. GET often sends information to the server through the "query
string". The query string is a list of name-value pairs that are appended to the
URL. For example:
Conversely POST need not send any information to the server and a POST
results in a response being sent from the web server just like GET does. This
POST is equivalent to the GET example above:
So the only real difference (as far as HTTP is concerned) is the location in the
request of the name-value parameters. Most web servers set a max size on the
query string though so if large amounts of data need to be sent a POST is
usually used. Also note that POST can still specify a query string after the page.
The apparent differences (in usage) of GET and POST exist because of the way
a browser initiates them. GET is used when the user types in an URL, clicks a
link, or client-side script navigates the browser. In all these cases the query
string is explicity and manually created. A POST occurs when an HTML FORM
element is "submitted". In this case the browser automatically creates the HTTP
header parameters from the INPUT, SELECT and TEXTAREA elements on the
page.
HTTP Response
The response the web server sends to the client is similar, in format, to the
request.
HTTP/1.1 200 OK
Server: Microsoft-IIS/5.0
Date: Thu, 08 Dec 2005 16:39:39 GMT
X-AspNet-Version: 1.1.4322
Set-Cookie: ASP.NET_SessionId=xshitibm0r1nlpawjvwfzn55; path=/
Cache-Control: private
Content-Type: text/html; charset=utf-8
Content-Length: 3579
<html>
<head>
<title>Home Page</title>
</head>
<body>
...
The first line let's us know that the request was good, the page was found and
no errors occurred. If anything had gone wrong (or a redirection occurred, etc)
we would have seen something else other than "200 OK".
The Content-Type parameter lets us know what kind of data is being returned.
In this case we are told to expect plain old HTML. If we had requested an image
file we would have seen "image/jpeg", for example.
Content-Length tells the client exactly how much data to expect to be returned.
Two CRLFs in a row designate the end of the header and the start of the
response data (in this case HTML).
Web Session
So if HTTP only sends these simple requests and responses how does a web
server maintain a session for the user? This is not done by keeping a socket
connected to the server. Rather a cookie is used to set and send a session ID
number. This is the ASP.NET_SessionId cookie in the GET and response
examples. The cookie is set the first time the client makes an HTTP request to
the web server. The client then passes the cookie back to the web server on
each subsequent HTTP request. If the server doesn't receive an HTTP request
from a client in a set amount of time (session time-out) the memory reserved
for the session is released and the client will receive a new session ID on the
next request. This usually logs the user out of whatever web application s/he
was signed into.
HTTP Clients
The Web Browser
The web browser (IE, Firefox, etc.) is by far the most common HTTP client, and
one that everyone is familiar with. Every time the user clicks a link, types in an
URL, or hits refresh an HTTP request occurs. In fact many HTTP requests
usually occur. This is because the browser usually requests an page that returns
HTML. The HTML is then parsed to discover links to images, script files,
stylesheet files, frame or iframe sources, etc. Each time that one of these links
is discovered an entirely separate HTTP request is made to retrieve the item.
So, browsing to a page can result in many HTTP requests.
Client-Side Scripting
For an HTTP request to a page that returns HTML it is possible to return code
that will be executed in the browser. This is usually Javascript and is contained
between <script> tags. Since this code runs inside the browser it is not
possible to access any of the code or memory that exists on the web server (i.e.
Session variables). Of course, data that exists on the server side can be sent to
the client browser in the HTML response. The copy of the data can then be
accessed by the client-side javascript. It is very important to remember that
client-side javascript can only have anything happen on the server-side via
HTTP GET or POST.
AJAX
As stated in the Client-Side scripting section an HTTP GET or POST must occur
in order for the browser to get data from or cause anything to happen on the
server. When the browser does either of these (they're the same remember)
the current page is unload and a new page is created from the HTTP HTML
response. This results in "browser flash". To avoid this flash and provide what
seems like a more seemless client experience the concept of AJAX was
developed. AJAX stands for Asynchronous Javascript and XML. It allows the
javascript coder to invoke special javascript methods that send an HTTP
request, read the response and provide the data (typically XML) back to the
method callee.
AJAX is often used to invokes a web service method. This involves sending an
HTTP POST to the web server that invokes the web service method with the
desired parameter values. The data from the response, typically XML (i.e. the
web service return type is string and is formatted as XML), is then read from
the response. The XML is then loaded into the browser's XML parser.
AJAX is great for some things but there are number of things to think about.
Don't do normal navigation through AJAX because the user loses the ability to
bookmark, use the "back" button, etc. You should also deal with the possibility
that the web server doesn't respond or responds with an HTTP error when
invoking a web service method with AJAX.
The first concept that requires a good understanding is the concept of an IIS
application. The best way to understand an IIS application is to think of it like a
process ("EXE") that is running on the server. This running EXE is then bound to
a particular directory on the server. When a page request comes in to the web
server the first thing IIS does is determine what application it needs to pass the
request off to. This is done by looking at the URL that was specified in the first
line of the HTTP request (see above) and determining the local (e.g. "C:\...")
directory the page will be found in. The request is then forwarded to the
application that is bound to that directory. The process that is the actual web
server is really nothing more than an application broker for HTTP requests. The
only thing of significance the web server does is pass a stream to the
application that can be used to write the response back to the client.
To illustrate this let's imagine IIS is configured with an application on a
directory - "D:\MyStoreWeb". Since this directory is not under
"/Inetpub/wwwroot" it would also be configured as a Virtual Directory. We'll say
that the alias for this directory is configured as "store". Given this the web
server will map the URL "http://serverdnsname/store" to the directory
"D:\MyStoreWeb". Note that you can effectively think of an IIS Application and
an IIS Virtual Directory as the exact same thing except that a Virtual Directory
is (usually) located outside of the "/Inetpub/wwwroot" directory.
The very first time an HTTP request comes in for any file below
"http://serverdnsname/store" (e.g. "http://serverdnsname/store/default.aspx")
IIS will start the "store" application. This is equivalent to launching an "EXE" on
the server. This is why the first hit to an application after the server has been
rebooted or "iisreset" has been run is slow. This is also when the
System.Web.HttpApplication's Application_Start method is
invoked. Usually this is done in the Global.asax file that VS generates. It is
important to note that static class members properties are global to the entire
application just like they would be in a full-blown windows process. This means
that static class members are available to all web request sessions.
Hopefully this all makes sense because now it gets more complicated. What I've
stated so far is a simplification of what an IIS application is for the case that
you only have pages that are from a single technology base (like .NET). One of
the things that can be configured (individually) for an IIS application is what
happens for each type of page that is requested. This is done by configuring a
file extension to be handled by what is called an ISAPI extension. This is done
by clicking the "Configuration" button on the application's "[Virtual] Directory"
tab on its "Properties" window. The "App Mappings" tab shows each file
extension and what ISAPI dll will handle it. IIS streams the contents of files not
listed here (typically .html, .gif, .jpg, etc.) directly back to the client. A file
request for any of the files listed here is passed to the specified ISAPI DLL. This
DLL then becomes responsible for reading the file (if there even is one, the file
doesn't really have to exist at all!), interpretting the contents and writing the
response. The complication here is that each DLL maintains it's own application
and session objects. So really, a single IIS application can have many
application objects and multiple sessions for a client that accesses pages of
differing technologies. Each ISAPI dll can independently override the IIS
application's session time-out value.
Like a normal windows process an IIS application runs under a windows user
account. By default this is a low privilege account like the built-in
<computername>_IUSR account. In IIS this is configured for the application by
clicking the top "Edit" button in "Directory Security" tab in the appplicatio's
"Properties" window. "Windows Authentication" can be used to have web
requests run under a window account that is specified by the client browser.
Otherwise the request is considered anonymous and runs under whatever user
is configured as the "Account used for anonymous access". A complication here
is .NET. Unless the web request is set to run under "Window Authentication"
.NET will use a special, low-privilege account called ASPNET. It will ignore
whatever you set as the "Account used for anonymous access" in IIS. To get it
to use the account specified here, you need to add the following to your
application's "Web.config" file:
<identity
impersonate="true"
/>
Enough about IIS applications already! Let's start looking at what happens
when a request for a .NET page (.aspx, .asmx) comes into the web server.
ASP.NET
Loading the Page
So far we have:
What happens next is that "aspnet_isapi.dll" contacts (or starts if this is the first
.NET request) a process called "aspnet_wp.exe". The request is then forwarded
to this process. Now the hot-potato shuffling of the web request is finally done.
"aspnet_wp.exe", referred to as "ASP.NET" from now on, is actually going to do
something!
The first thing that ASP.NET does is look at the location of the requested file
and find the "nearest" Web.config file for it. "Nearest" being the the first
Web.config it finds as it looks in the directories from the file's directory up to
the IIS application's web root. If the Web.config file has been loaded and a .NET
application has been created for it, ASP.NET uses this one, otherwise a new one
is created. In .NET this application object is of type
System.Web.HttpApplication and is generally accessed via a Page's
Application property.
Next it finds or creates the session object for the web request. This object is of
type HttpSessionState and is usually accessed by the Page's Session
property.
The next step is important to understand when debugging. ASP.NET looks in the
application folder's "bin" directory and loads all the DLLs into memory. As it
loads each DLL it finds all the namespaces in them and (I'm assuming) stores
them in an easily referenced list. Note that this loading of DLLs only occurs
when the application is starting up (on the first page request).
The next thing ASP.NET checks (OK, I'm sure it's doing a LOT more, but none of
it is relevant here) is if any "HTTP Modules" have been added to the application.
An HTTP module is a way of intercepting the request at this stage, before
ASP.NET goes nuts and starts actually parsing the file, running the code behind,
etc. An HTTP module can take over the response stream and preempt "normal"
ASP.NET processing. HTTP modules are added to the application in the
Web.config file, for example:
<httpmodules>
<add name="WebChartImageStream"
type="Company.Product.Web.Module.HttpModules.ClassName,
Company.Product.Web.Module.HttpModules" />
</httpmodules>
Anyway, let's ignore HTTP modules or at least pretend that one is not
intercepting our web request. The next thing that happens is that ASP.NET
actually reads the contents of the requested file. It's going to categorize the file
into one of two types:
It does this by looking for a line with an @Page directive. If no such line is
found ASP.NET assumes the page has nothing but boring static content and
immediately renders the page contents to the response stream. Otherwise it
starts processing the server side directives. An (ASP.NET 1.1) @Page directive
might look like:
So, "could not load type" means "could not find the DLL, the namespace, or the
class". When you get this error first check that the DLL for the page is in the
web app's "bin" directory. Next check that the class name specified in the
"Inherits" attribute is correct. If that seems good check the namespace
carefully. Use ILDASM to make sure the DLL in the "bin" really does contain the
class. If all this seems correct then it is probably a dependency issue. A "could
not load type" type error may also occur when the .NET framework cannot find
a DLL/namespace/class that the DLL is complaining about references. In this
case use ILDASM to identify the dependencies and perform the same
file/namespace/class analysis for each dependency. If all else fails make sure
the "bin" directory you are looking at is indeed correct for the application -
perhaps another IIS application or Web.config file is causing another "bin"
directory to be used.
Before going on to parsing the page there is one more thing the framework
does that should be mentioned. This is the creation of the HttpRequest and
HttpResponse objects that are commonly accessed via the Page's Request
and Response properties respectively. The creation of the HttpRequest
includes the populating of the Form (if POST) and QueryString (if "?..." in
URL) collections.
This Control class has a method called Render that writes HTML back to the
response stream. So when it comes time (we'll get there!) to send the page's
HTML back to the client ASP.NET iterates through the Control instances and
calls the Render method on each one. Essentially the page doesn't contain any
HTML of it's own - all the HTML is contained in it's sub-controls.
Since plain old HTML can be rendered directly to the output stream ASP.NET will
parse HTML text blocks into a string that is assigned to an instance of
System.Web.UI.LiteralControl. This LiteralControl instance is
then added to the Page's Controls collection. When the parser comes across
an element that has an attribute called "runat" that is set to "server" (referred
to as a server-side control) it does not use a LiteralControl. Instead it
looks at the element name to determine what control type to instantiate. In the
case of our example the parser will find the asp:textbox element. Element
names prepended with "asp:" are known by the ASP.NET framework as controls
to be found in the System.Web.UI.WebControls namespace. So ASP.NET
will instantiate an instance of the
System.Web.UI.WebControls.TextBox class (notice that ASP.NET is
case-insenstive here). The attributes of a server-side control element are
assigned to properties of the class instance.
When ASP.NET is finished parsing our example page the Page's Controls will
contain the following items:
Remember that each Control in the collection has a method called Render.
This method renders the control to the response stream (i.e. renders HTML back
to the browser). A LiteralControl simply renders its Text. A TextBox
control obviously does a bit more since it will need to examine its ID, Width,
etc. properties to determine what it should write to the response stream - e.g.
"<input type=text id=loginIdTextBox
style=width:50px; ... >".
This is done by creating a protected class variable of the type implied by the
HTML element ("asp:textbox" =
System.Web.UI.WebControls.TextBox). The name of the class variable
must match the ID of the HTML element. After the Controls collection has
been populated ASP.NET iterates through it and sets the protected
appropriate class variable for each Control. LiteralControl instances are
ignored since they don't have an ID. So for our example our "codebehind" class
will have the following line:
If, for example, we want to set the text of the loginID input box in the Page's
Load event handler we could do the following:
Note that ASP.NET does not require a server-side control with an ID to have a
corresponding class variable.
Page Lifecycle
Now that we're done the parsing stage we're going to enter the stages that the
developer gets to intercept and insert custom code into. First let's recap the
stages so far:
6. PreInit
7. Init
8. Load ViewState
9. Load
10. PreRender
11. PreRenderComplete
12. Render
13. Unload
PreInit
Init
The Init stage begins with the execution of the Page's OnInit method. This
method is virtual so it can be overridden in our Page class derivative.
Load ViewState
Suppose for example a page contains a server-side data list control with a
SortBy property. When the user clicks a column header a POST occurs to set
the SortBy property and thereby render the data list sorted by that column.
Now let's say that the user has clicked on the "Name" column. A POST occurs,
the SortBy property is set to "Name" and the response that is written back
contains the data, sorted by name. All is good. Then the user makes some
changes to the filtering criteria for the list, which causes the page to be POSTed
back to the server. The Page object is rebuilt from scratch, including the
controls. This means that the SortBy property will be set to whatever its
default value is. The "Name" sorting has been lost.
In pre-ViewState days (ASP) we would have solved this problem by storing the
sort clause in a POST-able HTML element like INPUT (type="hidden"). We
would then have set the value of this element before POSTing, read the value
out of the Request.Form object and manually set the (equivalent of the)
SortBy property. Saving the state of all these properties was time-consuming
and laborious.
When using the ViewState property of the page values are stored across
HTTP POSTs. An important point to stress is that ASP.NET loads information
from ViewState and sets the appropriate controls' properties between the Init
and Load stages. So if you set a control property in the Init stage it may get
overwritten by a ViewState value and therefore be different in the Load stage.
If you're curious to know how ASP.NET does the magic behind ViewState read
on. Otherwise skip to the next section.
In order to save the ViewState information that has been set ASP.NET writes it
to the response stream. It does this by adding an HTML INPUT element
(type="hidden") to the page. This element is given the name "__VIEWSTATE".
The Page's ViewState object is then serialized as a string of
"control.property= value" pairs
(e.g."datalist1.sortby=name&datalist1.userid=123"). This string is then base
64-encrypted and given as the value for the "__VIEWSTATE" element. When the
page is POSTed back this "__VIEWSTATE" is POSTed with it. ASP.NET can then
retreive its value, decrypt it and set the appropriate control properties.
Load
The Init stage begins with the execution of the Page's OnLoad method. This
method is virtual so it can be overridden in our Page class derivative. However
it is more common, and better practice, to set the Page's Load event handler
in the OnInit method. When creating a new page Visual Studio does this for
you and names the event handler method "Page_Load". This method is the
recommended place for doing normal page/control initialization.
PreRender
PreRenderComplete
This method was introduced in ASP.NET 2.0. It's purpose is to provide an event
handler that can be used to do work immediately after asynchronous events
have finished. See Asynchronous Calls in a Web Page for more information.
Render
This is the stage where the page and all its sub-controls are rendered to the
response stream. For a page this method is implemented by the ASP.NET
framework and does all the work for you. For a custom control you will need to
override and implement the Render method to have your control render the
appropriate HTML.
Unload
Now everything about the HTTP request is released starting with the ASP.NET
page and controls and going all the up the stack to the ISAPI extension and
possibly even the socket. Nothing about the request remains except a line in
the web server's log file.
Conclusion
At this point your brain is recoiling from knowing WAY too much about an
ASP.NET page request. If you actually managed to read the whole document
through at once you will probably be suffering from information overload. That's
OK, just refer to the document as needed. However, if you're going to be doing
custom web control or web framework development I encourage you to know as
much about this stuff as possible. Reread as necessary until you understand it
all.
This article describes how the IIS process clients requests and
responses.
Introduction
When request come from client to the server a lot of operation is performed
before sending response to the client. This is all about how IIS Process the
request. Here I am not going to describe the Page Life Cycle and there events,
this article is all about the operation of IIS Level. Before we start with the
actual details, let’s start from the beginning so that each and everyone
understand it's details easily. Please provide your valuable feedback and
suggestion to improve this article.
When we run our ASP.NET Web Application from visual studio IDE, VS
Integrated ASP.NET Engine is responsible to execute all kind of asp.net requests
and responses. The process name is "WebDev.WebServer.Exe" which
actually takw care of all request and response of an web application which is
running from Visual Studio IDE.
Now, the name “Web Server” come into picture when we want to host the
application on a centralized location and wanted to access from many locations.
Web server is responsible for handle all the requests that are coming from
clients, process them and provide the responses.
What is IIS ?
IIS (Internet Information Server) is one of the most powerful web servers from
Microsoft that is used to host your ASP.NET Web application. IIS has it's own
ASP.NET Process Engine to handle the ASP.NET request. So, when a request
comes from client to server, IIS takes that request and process it and send
response back to clients.
Request Processing :
Hope, till now it’s clear to you that what is Web server and IIS is and what is
the use of them. Now let’s have a look how they do things internally. Before we
move ahead, you have to know about two main concepts
Now, I have covered all the basic stuff like Web server, Application Pool, Worker
process. Now let’s have look how IIS process the request when a new request
comes up from client.
If we look into the IIS 6.0 Architecture, we can divided them into Two Layer
1. Kernel Mode
2. User Mode
Now, Kernel mode is introduced with IIS 6.0, which contains the HTTP.SYS.
So whenever a request comes from Client to Server, it will hit HTTP.SYS First.
Till now, Client Requested for some information and request came to the Kernel
level of IIS means at HTTP.SYS. HTTP.SYS has been identified the name of the
application pool where to send. Now, let’s see how this request moves from
HTTP.SYS to Application Pool.
In User Level of IIS, we have Web Admin Services (WAS) which takes the
request from HTTP.SYS and pass it to the respective application pool.
When Application pool receive the request, it simply pass the request to worker
process (w3wp.exe) . The worker process “w3wp.exe” looks up the URL of the
request in order to load the correct ISAPI extension. ISAPI extensions are the
IIS way to handle requests for different resources. Once ASP.NET is installed, it
installs its own ISAPI extension (aspnet_isapi.dll) and adds the mapping into
IIS.
All the request now passes from httpModule to respective HTTPHandler then
method and the ASP.NET Page life cycle starts. This ends the IIS Request
processing and start the ASP.NET Page Lifecycle.
Conclusion
When client request for some information from a web server, request first
reaches to HTTP.SYS of IIS. HTTP.SYS then send the request to respective
Application Pool. Application Pool then forward the request to worker process to
load the ISAPI Extension which will create an HTTPRuntime Object to Process
the request via HTTPModule and HTTPHanlder. After that the ASP.NET Page
LifeCycle events starts.
This was just overview of IIS Request Processing to let Beginner’s know how the
request get processed in backend. If you want to learn in details please check
the link for Reference and further Study section.