Está en la página 1de 53

When a request reaches IIS

For example user might type some thing like this in the browser:
http://YourHostName/DirectoryName/FileName.aspx

The task of the web server is to accept the http request and to serve the requested
page as HTTP Response. Now IIS is going to decide how it is going to handle the
request. The IIS decision is based upon the file extension. If the extension is asp i.e.
Classic ASP then it will route the request to asp.dll. But if it is an ASP.NET request
then IIS will route it to ASP.NET Engine (if you go to IIS, right click on default
website, go to home directory and then to configurations, you can see the extensions
and there executable paths).

Now we will examine how ASP.NET Engine will process the request. ASP.NET engine
is often called as asp.net http pipeline. Incoming request will pass through number of
Http Modules before reaching Http Handler. Http Modules are nothing but classes
which can inspect the incoming request and make decisions which may affect the
internal flow of the request...

After passing through the Http modules it has now reached the Http Handler which
will produce the output. I will explain only one Http Handler here.

When a request comes for an asp.net page with .aspx extension the request is
handed off to the ASP.NET engine. The request then moves through the modules.
The request is then routed to the PageHandlerFactory, since in the machine.config's
< httpHandler > section we have the mapping:

< httpHandlers >


< add verb="*" path="*.aspx" type="System.Web.UI.PageHandlerFactory" />
< /httpHandlers >

Now PageHandlerFactory will provide an instance of Http Handler and it tries to


find the compiled class that represents the ASP.NET Web page that is being
requested. When the ASP.NET Web page is first visited, the ASP.NET engine
creates a class that derives from the System.Web.UI.Page class. This
dynamically created class is then compiled. The Page class implements
IHttphandler interface which indicates that it uses an http handler.

PageHandlerFactory sees whether the compiled version for the requested class
(page) exists. If not it will create the class and compiles it.
Some method of this class is invoked (I am not sure which one) and it will create a
completer html code for that particular page. It is sent back through the Http
Modules as response and it is rendered in the page. That's it. You are viewing
your requested page...

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.

What is Web Server ?

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

1. Worker Process
2. Application Pool

Worker Process: Worker Process (w3wp.exe) runs the ASP.Net application in IIS.
This process is responsible to manage all the request and response that are coming
from client system. All the ASP.Net functionality runs under the scope of worker
process. When a request comes to the server from a client worker process is
responsible to generate the request and response. In a single word we can say
worker process is the heart of ASP.NET Web Application which runs on IIS.

Application Pool: Application pool is the container of worker process. Application


pools is used to separate sets of IIS worker processes that share the same
configuration. Application pools enables a better security, reliability, and availability
for any web application. The worker process serves as the process boundary that
separates each application pool so that when one worker process or application is
having an issue or recycles, other applications or worker processes are not affected.
This makes sure that a particular web application doesn't not impact other web
application as they they are configured into different application pools.
Application Pool with multiple worker process is called “Web Garden”.

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.
Now, HTTP.SYS is Responsible for pass the request to particular Application pool.
Now here is one question, How HTTP.SYS comes to know where to send the
request? This is not a random pickup. Whenever we creates a new Application Pool,
the ID of the Application Pool is being generated and it’s registered with the
HTTP.SYS. So whenever HTTP.SYS Received the request from any web application, it
checks for the Application Pool and based on the application pool it send the request.

So, this was the first steps of IIS Request Processing.

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.

Note : Sometimes if we install IIS after installing asp.net, we need to register the
extension with IIS using aspnet_regiis command.

When Worker process loads the aspnet_isapi.dll, it start an HTTPRuntime, which is


the entry point of an application. HTTPRuntime is a class which calls the
ProcessRequest method to start Processing.
When this methods called, a new instance of HTTPContext is been created. Which
is accessible using HTTPContext.Current

+ Properties. This object still remains alive during life time of object request. Using
HttpContext.Current we can access some other objects like Request, Response,
Session etc.

After that HttpRuntime load an HttpApplication object with the help of


HttpApplicationFactory class.. Each and every request should pass through the
corresponding HTTPModule to reach to HTTPHandler, this list of module are
configured by the HTTPApplication.

Now, the concept comes called “HTTPPipeline”. It is called a pipeline because it


contains a set of HttpModules ( For Both Web.config and Machine.config level) that
intercept the request on its way to the HttpHandler. HTTPModules are classes that
have access to the incoming request. We can also create our own HTTPModule if we
need to handle anything during upcoming request and response.
HTTP Handlers are the endpoints in the HTTP pipeline. All request that are passing
through the HTTPModule should reached to HTTPHandler. Then HTTP Handler
generates the output for the requested resource. So, when we requesting for any
aspx web pages, it returns the corresponding HTML output.

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.

One of the very common question in any dot net interview is aboult explaining ASP.NET page life
cycle.

ASP.NET page life cycle is not very tough to know but in many books , I have seen it is written in
such a manner that it seems to be very complicated.

In this article, I will try to explain the page life cycle as simple as possible:

How it all begins

A user sits at her browser and types in a URL. A web page appears with text, images,buttons,
and so forth. She fills in a text box and clicks a button. New data appears in response. How does
this work?

When an ASP.NET page is requested from the server, the server loads the page into server
memory, processes the page, sends the page to the user, and then unloads it from memory.
From the beginning of the life cycle to the end, the goal is to render appropriate HTML to the
requesting browser. At each step, methods and events are available that allow you to override the
default behavior or add your own programmatic enhancements.

There are two slightly different sequences in the life cycle: one for the first time a page is loaded,
and a second when the page reloads itself in a postback.

During the first page load, the life cycle consists of the following steps:

1. A request for the page is made from a browser to the web server. The ASP.NET Framework
first determines whether the page already exists in a cache (a section of memory specifically
reserved for recently used items). If so, the page is retrieved and returned to the browser and we
are done. If not, then the actual page life cycle starts at this point.

2. During the Start phase, the postback mode is determined. If the page was requested by a
different page, then it was not a postback. If the page was returned to the server for processing
and redisplay, then it is a postback.
The IsPostBack and PreviousPage properties are set accordingly. The Request and
Response properties of the page along with a number of other properties are also
set.

3. The Page Initialization phase contains two events often handled by your code:
PreInit and Init.
If you do not handle these explicitly yourself, ASP.NET will perform the default behavior on your
behalf.

During the PreInit event, the target device is determined before the page is initialized, the master
page is set, the control tree is built, and the controls are assigned unique IDs, which are made
available to your code. Personalization and themes are loaded and applied to the page in this
step.
PreInit is the first event in the life cycle that can be trapped and handled. That is, this is the first
event that you can write your own code for, to change the default behavior of initializing the page.

4. During the Init event, control properties are read or initialized. If this is a postback, it is
important to realize that the controls won’t reflect any changes to the page made before the
postback—that happens in the PreRender phase. They will contain values specified in the
markup file.

5. During the Load event, all the control properties are set. View state information is available,
and controls in the page’s control hierarchy can be accessed. The load phase is routinely
modified in a Page_Load method.

6. During the Validation phase, the Validate method is called on all the validation controls on the
page. The IsValid property is set for all those controls and for the page as a whole.

7. During the Rendering phase, personalization, control, and view state is saved. Each control on
the page is called in succession to render itself to the browser, that is, to compose itself into
HTML that is included in the page’s Response property.

It is very common to handle the PreRender event with a Page_PreRender method, typically
when you must take some action based on the final value of some other control on the page.
During the Render event, the HTML is actuallygenerated and sent to the requesting page,
although this event is rarely handled unless you are developing custom controls.

8. Unload is the last event of the life cycle. It gives you an opportunity to do any final cleanup
(i.e., closing open files and releasing references to expensive resources, such as database
connections).

During postback, the life cycle is the same as during the first load, except for the following:

1. During the Load phase, after initialization is complete, the view state and the control state are
loaded and applied as necessary.

2. After the Validation phase completes, postback data is processed. Control event handlers are
now executed.

This is important: control event handlers, such as a Button Click, are not called until after the
Page Initialization and Load events are handled.

The following are the various stages a page goes through:

Page Request

The request page is either parsed or compiled, or fetched from the cache.

Start

Page properties like the Request and Response are set. The type of request is determined,
specifically whether it is a new Request or it is a PostBack. Culturing properties are also
determined via the pages ICulture property.
Page Initialization

All the controls on the given page are initialized with a UniqueID (please don’t confused
this with the ID property as the UnqiueID is a unique, hierarchicial identifier which
includes the server

control’s naming container). Theming is also applied at this stage.

Load

If the current request is a PostBack, the data from the viewstate and control state is
loaded to the appropriate properties of the controls.

Validation

The Validate method of all the validator controls are fired, which in turn sets the Boolean
property IsValid of the controls.

Postback Event Handling

If the current request is a PostBack, all event handlers are called.

Rendering

ViewState data is saved for all the controls that have enabled viewstate. The Render
method for all the controls is fired which writes its output to the OutputStream via a text
writer.

Unload

Once the page has been rendered and sent, the Page’s properties are unloaded (cleanup
time).

So know you have a better understanding of the various stages of a ASP.NET pages life
cycle, you should be aware that within each of the above stages there are events that you
can hook into so that your code is fired at the exact time that you want it to.

Event Wire-up is another important concept to understand. So Event wire-up is where


ASP.NET looks for methods that match a naming convention (e.g. Page_Load, Page_Init,
etc) , and these methods are automatically fired at the appropriate event. There is a page
level attribute AutoEventWireup that can be set to either true or false to enable this
behaviour.

Below are some of the more popular events that you should understand as you will most
likely be interested in them:
PreInit
You can use this event to:
 Create /recreate dynamic controls
 Set a master page or theme dynamically
 Access profile properties

Init

Used to read or initialize your control properties.

InitComplete

Used when you need to access your properties after they have been initialized.

PreLoad

Used when you need to process things before the Load event has been fired.

Load

The Page’s OnLoad method and all of its child control’s OnLoad method are fired
recursively. This event is used to set properties and make database connections

Control Events

Control specific events are handled at this stage. e.g. Click event’s for the button control.

LoadComplete

This stage is for when you need to access controls that have been properly loaded.

PreRender

Can be used to make any ‘last chance’ changes to the controls before they are rendered.

SaveStateComplete

This event is used for things that require view state to be saved, yet not making any
changes to the controls themselves.

Render

The page object calls this method on all of the controls, so all the controls are written and
sent to the browser.
Unload

All the controls UnLoad method are fired, followed by the pages UnLoad event (bottom-
up). This stage is used for closing database connections, closing open files, etc.

It is import to understand that each server control has its very own life cycle, but they are
fired recursively so things may not occur at the time you think they do (they occur in
reverse order!). What this means is that some events fire from the bottom up like the Init
event, while others load from the top-down like the Load event.

Purpose
State management is the process by which you maintain state and page information
over multiple requests for the same or different pages.

Types of State Management


There are 2 types State Management:

1. Client – Side State Management


This stores information on the client's computer by embedding the information into a
Web page, a uniform resource locator(url), or a cookie. The techniques available to
store the state information at the client end are listed down below:

a. View State – Asp.Net uses View State to track the values in the Controls. You can
add custom values to the view state. It is used by the Asp.net page framework to
automatically save the values of the page and of each control just prior to rendering
to the page. When the page is posted, one of the first tasks performed by page
processing is to restore view state.

b. Control State – If you create a custom control that requires view state to work
properly, you should use control state to ensure other developers don’t break your
control by disabling view state.

c. Hidden fields – Like view state, hidden fields store data in an HTML form without
displaying it in the user's browser. The data is available only when the form is
processed.

d. Cookies – Cookies store a value in the user's browser that the browser sends with
every page request to the same server. Cookies are the best way to store state data
that must be available for multiple Web pages on a web site.

e. Query Strings - Query strings store values in the URL that are visible to the user.
Use query strings when you want a user to be able to e-mail or instant message
state data with a URL.

2. Server – Side State Management


a. Application State - Application State information is available to all pages,
regardless of which user requests a page.
b. Session State – Session State information is available to all pages opened by a
user during a single visit.

Both application state and session state information is lost when the application
restarts. To persist user data between application restarts, you can store it using
profile properties.

Implementation Procedure

Client – Side State Management:

View State:
The ViewState property provides a dictionary object for retaining values between
multiple requests for the same page. When an ASP.NET page is processed, the
current state of the page and controls is hashed into a string and saved in the page
as a hidden field. If the data is too long for a single field, then ASP.NET performs
view state chunking (new in ASP.NET 2.0) to split it across multiple hidden fields.
The following code sample demonstrates how view state adds data as a hidden form
within a Web page’s HTML:

<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE”


value="/wEPDwUKMTIxNDIyOTM0Mg9kFgICAw9kFgICAQ8PFgIeBFRleHQFEzQvNS8yMDA2IDE6Mzc6
MTEgUE1kZGROWHn/rt75XF/pMGnqjqHlH66cdw==" />

Encrypting of the View State: You can enable view state encryption to make it more
difficult for attackers and malicious users to directly read view state information.
Though this adds processing overhead to the Web server, it supports in storing
confidential information in view state. To configure view state encryption for an
application does the following:

<Configuration>

<system.web>

<pages viewStateEncryptionMode="Always"/>

</system.web>

</configuration>

Alternatively, you can enable view state encryption for a specific page by setting the
value in the page directive, as the following sample demonstrates:

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs"


Inherits="_Default" ViewStateEncryptionMode="Always"%>

View State is enabled by default, but if you can disable it by setting the
EnableViewState property for each web control to false. This reduces the server
processing time and decreases page size.
Reading and Writing Custom View State Data:
If you have a value that you’d like to keep track of while the user is visiting a single
ASP.NET Web page, adding a custom value to ViewState is the most efficient and
secure way to do that. However, ViewState is lost if the user visits a different Web
page, so it is useful only for temporarily storing values.
Example: Determine the time of last visit to the page

// Check if View State object exists, and display it if it does

If (ViewState ["lastVisit"]!= null)

Label1.Text = (string)ViewState["lastVisit"]; else

Label1.Text = "lastVisit ViewState not defined.";

// Define the ViewState object for the next page view


ViewState.Add("lastVisit", DateTime.Now.ToString());

Control State: If you create a custom control that requires ViewState, you can use
the ControlState property to store state information for your control. ControlState
allows you to persist property information that is specific to a control and cannot be
turned off like the ViewState property. To use control state in a custom control, your
control must override the OnInit method and call the Register-RequiresControlState
method during initialization and then override the SaveControl-State and
LoadControlState methods.

Hidden fields: ViewState stores information in the Web page using hidden fields.
Hidden fields are sent back to the server when the user submits a form; however,
the information is never displayed by the Web browser (unless the user chooses to
view the page source). ASP.NET allows you to create your own custom hidden fields
and store values that are submitted with other form data. A HiddenField control
stores a single variable in its Value property and must be explicitly added to the
page. You can use hidden fields only to store information for a single page, so it is
not useful for storing session data. If you use hidden fields, you must submit your
pages to the server using Hypertext Transfer Protocol (HTTP) POST (which happens if
the user presses a button) rather than requesting the page using HTTP GET (which
happens if the user clicks a link). Unlike view state data, hidden fields have no built-
in compression, encryption, hashing, or chunking, so users can view or modify data
stored in hidden fields.

Cookies: Web applications can store small pieces of data in the client’s Web browser
by using cookies. A cookie is a small amount of data that is stored either in a text file
on the client file system (if the cookie is persistent) or in memory in the client
browser session (if the cookie is temporary). The most common use of cookies is to
identify a single user as he or she visits multiple Web pages.

Reading and Writing Cookies:


A Web application creates a cookie by sending it to the client as a header in an HTTP
response. The Web browser then submits the same cookie to the server with every
new request.
Create a cookie -> add a value to the Response.Cookies HttpCookieCollection.
Read a cookie -> read values in Request.Cookies.
Example:
// Check if cookie exists, and display it if it does

if (Request.Cookies["lastVisit"] != null) // Encode the cookie in case the


cookie contains client-side script Label1.Text =
Server.HtmlEncode(Request.Cookies["lastVisit"].Value);

else Label1.Text = "No value defined";

// Define the cookie for the next visit Response.Cookies["lastVisit"].Value =


DateTime.Now.ToString();Response.Cookies["lastVisit"].Expires =
DateTime.Now.AddDays(1);

If you do not define the Expires property, the browser stores it in memory and the
cookie is lost if the user closes his or her browser.

To delete a cookie, overwrite the cookie and set an expiration date in the past. You
can’t directly delete cookies because they are stored on the client’s computer.
Controlling the Cookie Scope: By default, browsers won’t send a cookie to a Web site
with a different hostname. You can control a cookie’s scope to either limit the scope
to a specific folder on the Web server or expand the scope to any server in a domain.
To limit the scope of a cookie to a folder, set the Path property, as the following
example demonstrates:

Example:
Response.Cookies["lastVisit"].Path = "/Application1";

Through this the scope is limited to the “/Application1” folder that is the browser
submits the cookie to any page with in this folder and not to pages in other folders
even if the folder is in the same server. We can expand the scope to a particular
domain using the following statement:
Example:
Response.Cookies[“lastVisit”].Domain = “Contoso”;

Storing Multiple Values in a Cookie:


Though it depends on the browser, you typically can’t store more than 20 cookies
per site, and each cookie can be a maximum of 4 KB in length. To work around the
20-cookie limit, you can store multiple values in a cookie, as the following code
demonstrates:
Example:

Response.Cookies["info"]["visit"].Value = DateTime.Now.ToString();

Response.Cookies["info"]["firstName"].Value = "Tony";
Response.Cookies["info"]["border"].Value = "blue";

Response.Cookies["info"].Expires = DateTime.Now.AddDays(1);

Running the code in this example sends a cookie with the following value to the Web
browser:
(visit=4/5/2006 2:35:18 PM) (firstName=Tony) (border=blue)

Query Strings: Query strings are commonly used to store variables that identify
specific pages, such as search terms or page numbers. A query string is information
that is appended to the end of a page URL. A typical query string might look like the
following real-world example:
http://support.microsoft.com/Default.aspx?kbid=315233
In this example, the URL identifies the Default.aspx page. The query string (which
starts with a question mark [?]) contains a single parameter named “kbid,” and a
value for that parameter, “315233.” Query strings can also have multiple
parameters, such as the following real-world URL, which specifies a language and
query when searching the Microsoft.com Web site:
http://search.microsoft.com/results.aspx?mkt=en-US&setlang=en-
US&q=hello+world

Value Name | ASP.NET Object | Value


mkt | Request.QueryString[“mkt”] | en-US
setlang | Request.QueryString[“setlang”] | en-US
q | Request.QueryString[“q”] | hello world

Limitations for Query Strings:


1. Some Browsers and client devices impose a 2083 – character limit on the length
of the URL.
2. You must submit the page using an HTTP GET command in order for query string
values to be available during page processing. Therefore, you shouldn’t add query
strings to button targets in forms.
3. You must manually add query string values to every hyperlink that the user might
click.
Example:
Label1.Text = "User: " + Server.HtmlEncode(Request.QueryString["user"]) +

", Prefs: " + Server.HtmlEncode(Request.QueryString["prefs"]) +

", Page: " + Server.HtmlEncode(Request.QueryString["page"]);

Server - Side State Management:

Application State: ASP.NET allows you to save values using application state, a
global storage mechanism that is accessible from all pages in the Web application.
Application state is stored in the Application key/value dictionary. Once you add your
application-specific information to application state, the server manages it, and it is
never exposed to the client. Application state is a great place to store information
that is not user-specific. By storing it in the application state, all pages can access
data from a single location in memory, rather than keeping separate copies of the
data. Data stored in the Application object is not permanent and is lost any time the
application is restarted.

ASP.NET provides three events that enable you to initialize Application variables (free
resources when the application shuts down) and respond to Application errors:

a. Application_Start: Raised when the application starts. This is the perfect place to
initialize Application variables.

b. Application_End: Raised when an application shuts down. Use this to free


application resources and perform logging.

c. Application_Error: Raised when an unhandled error occurs. Use this to perform


error logging.

Session State: ASP.NET allows you to save values using session state, a storage
mechanism that is accessible from all pages requested by a single Web browser
session. Therefore, you can use session state to store user-specific information.
Session state is similar to application state, except that it is scoped to the current
browser session. If different users are using your application, each user session has
a different session state. In addition, if a user leaves your application and then
returns later after the session timeout period, session state information is lost and a
new session is created for the user. Session state is stored in the Session key/value
dictionary.

You can use session state to accomplish the following tasks:


i. Uniquely identify browser or client-device requests and map them to individual
session instances on the server. This allows you to track which pages a user saw on
your site during a specific visit.

ii. Store session-specific data on the server for use across multiple browser or client-
device requests during the same session. This is perfect for storing shopping cart
information.

iii. Raise appropriate session management events. In addition, you can write
application code leveraging these events.

ASP.NET session state supports several different storage options for session data:

a. InProc Stores session state in memory on the Web server. This is the default, and
it offers much better performance than using the ASP.NET state service or storing
state information in a database server. InProc is fine for simple applications, but
robust applications that use multiple Web servers or must persist session data
between application restarts should use State Server or SQLServer.

b. StateServer Stores session state in a service called the ASP.NET State Service.
This ensures that session state is preserved if the Web application is restarted and
also makes session state available to multiple Web servers in a Web farm. ASP.NET
State Service is included with any computer set up to run ASP.NET Web applications;
however, the service is set up to start manually by default. Therefore, when
configuring the ASP.NET State Service, you must set the startup type to Automatic.

c. SQLServer Stores session state in a SQL Server database. This ensures that
session state is preserved if the Web application is restarted and also makes session
state available to multiple Web servers in a Web farm. On the same hardware, the
ASP.NET State Service outperforms SQLServer. However, a SQL Server database
offers more robust data integrity and reporting capabilities.

d. Custom Enables you to specify a custom storage provider. You also need to
implement the custom storage provider.

e. Off Disables session state. You should disable session state if you are not using it
to improve performance.

Advantages

Advantages of Client – Side State Management:

1. Better Scalability: With server-side state management, each client that connects
to the Web server consumes memory on the Web server. If a Web site has hundreds
or thousands of simultaneous users, the memory consumed by storing state
management information can become a limiting factor. Pushing this burden to the
clients removes that potential bottleneck.

2. Supports multiple Web servers: With client-side state management, you can
distribute incoming requests across multiple Web servers with no changes to your
application because the client provides all the information the Web server needs to
process the request. With server-side state management, if a client switches servers
in the middle of the session, the new server does not necessarily have access to the
client’s state information. You can use multiple servers with server-side state
management, but you need either intelligent load-balancing (to always forward
requests from a client to the same server) or centralized state management (where
state is stored in a central database that all Web servers access).

Advantages of Server – Side State Management:

1. Better security: Client-side state management information can be captured (either


in transit or while it is stored on the client) or maliciously modified. Therefore, you
should never use client-side state management to store confidential information,
such as a password, authorization level, or authentication status.

2. Reduced bandwidth: If you store large amounts of state management information,


sending that information back and forth to the client can increase bandwidth
utilization and page load times, potentially increasing your costs and reducing
scalability. The increased bandwidth usage affects mobile clients most of all, because
they often have very slow connections. Instead, you should store large amounts of
state management data (say, more than 1 KB) on the server.

Caching in ASP.NET
Category: ASP.NET
Comments (5)

This tutorial explains about The Importance of Caching, Declarative Page Output
Caching, Programmatic Page Caching, Caching Page Fragments, Caching Data and
Monitoring Performance.

Introduction:

Sponsored Links
Caching is one of the coolest features in Asp.net. Caching enables you to store the expensive
data into Cache object and later retrieve it without doing expensive operations. A very
common example where you want to use caching is datagrid paging. I am sure you all are
familiar with datagrid paging which enables you to view the records in multiple pages. Each
time you visit a different page all the records are fetched from the database. This becomes
very expensive operation. Caching can save a lot of expensive operations since you can store
all the records in the cache object and use the cache object as the data source. In this article
we will see some important features that caching provides.

Output Caching:

Output caching is used for pages and is also known as Page-level caching. All you need
to do to enable output caching is to add a directive in your html view of the aspx page.
The output directive can be written like this:

@ OutputCache Duration="60" VaryByParam="none"

The page will be cached for 60 seconds the VaryByParam attribute is set to "none" which
means that there is no sort of caching implemented. Hence if the first user requested page
which contains item1 than the second user will also see item1 even if he is requesting
item2.

That's why we always specify what the caching depends on.

@ OutputCache Duration="60" VaryByParam="Category"

In the above OutputCache directive you can notice that I changed the VaryByParam
attribute to "Category" which means that now the result of caching depends upon
Category. Here Category represents the name of the column in the database.
Programmatic Page Caching

You can also use caching programmatically, meaning that you can change the value of
cache depending upon the tasks performed by the user. The Response.Cache class let's
you access the functionality to work with the cache object.

You can change the expiration time on the Cache using the SetExpires method of the
Response.Cache class.

Response.Cache.SetExpires(System.DateTime.Now.AddMinutes(10));

In the same way you can also use Response.Cache.VaryByParams to set the Params
programmatically.

Accessing Caching in the Class Libraries

Sometimes you will need to access the caching object in the class library. You cannot use
Response class anymore since its only limited to the asp.net code behind page. For
accessing cache in class library you will have to use HttpContext.Current.Cache. Also
don't forget to include System.web namespace.

Data Caching

Caching is one of the coolest features in Asp.net. Caching enables you to store the
expensive data into Cache object and later retrieve it without doing expensive operations.
Data Caching can tremendously increase performance since each time the data is
requested you can turn to the Cache object rather than going to the database and fetching
the result.

Sponsored Links
You all must be familiar with datagrid paging where you can display certain number of records
in the datagrid control and use the numeric or next-previous buttons to view the other
records. All the records are fetched for each and every page in the datagrid. Meaning that if
you have 40000 records in the database and you are using paging. Each time you click to go
to the next page you retrieve 40000 records. This is way too much performance kill. That's
why for this task we can use Data Caching, let's see how we can use data caching to make our
application more efficient.

private void Button3_Click(object sender, System.EventArgs e)

{
if(Cache["MyArticles"] == null)

// Go to the database and fetch the result in the DataSet

// Assign the dataset to the Cache object

// Cache["MyArticles"] = ds

else

// This means that Cache is not empty and there is data in the cache

// Extract the value of Cache object to the DataSet

// DataSet ds = (DataSet) Cache["MyArticles"]

The above example is pretty much simple and as you have also noticed that the syntax for
using Data Caching is very similar to the ViewState object. By using this technique you
will only get the data from the database if the Cache is empty. And if you see the page
source you will not find any hidden fields since Cache is stored in memory rather than in
page source.

Caching Page Fragments

Fragment Caching refers to caching the sections of the page. These sections are most
commonly UserControls. Page fragment caching allows you to cache the small portion of
the page instead of caching the whole page.
Let's see some examples of fragment caching and how it can be used.

@ OutputCache Duration="120" VaryByParam="CategoryID;SelectedID"

In the Page directive above we have cached CategoryID and SelectedID for 120 seconds.
Both of these are the query string parameters.

This means that if the first user request CategoryID = 2 and the second user request the
same CategoryID than the second user will recieve the contents from the cache object
instead of going to the database and pulling records.

@ OutputCache Duration="120" VaryByParam="none" VaryByControl="Category"

The VaryByControl attribute can only be used in fragment caching. You can use this to
cache the value of the controls. These controls can be any server controls like
dropdownlist or datagrid.
When using fragment caching you only need to put the cache directive in the user control
and not on the page.

You can use different type of tools to monitor your performance before and after caching
is used. Some of the good tools are NProf and ACT

In this article, you will learn about concepts, advantages, types of caching and about
implementation of caching in ASP.NET applications. The code also serves as an
example of using inline coding, creating user controls, trace mechanism, etc.

What is Caching?

Caching is a technique of persisting the data in memory for immediate access to


requesting program calls. Many in the developer community consider caching as one
of the features available to improve performance of Web applications.

Why Caching?

Consider a page that has list of Employee name, contact numbers and mail-Ids of
existing employees of a company on an intranet accessible by all employees. This is
very useful information that is available throughout the company and could also be
one of the most accessed pages. The functionality of adding, updating or deleting is
usually less intensive compared to more transaction-based systems like Purchase
ordering, Voucher creation etc. Now in a normal scenario the process of querying
database for each request is not cost-effective in terms of server resources, hence is
lot better to cache or persist the data to avoid this costly loss of resources.

The .NET Advantage

ASP.NET provides the flexibility in terms of caching at different levels.

1. Page Level Output Caching

This is at the page level and one of the easiest means for caching pages. This
requires one to specify Duration of cache and Attribute of caching.

Syntax: <%@ OutputCache Duration="60" VaryByParam="none" %>

The above syntax specifies that the page be cached for duration of 60 seconds and
the value "none" for VaryByParam* attribute makes sure that there is a single
cached page available for this duration specified.

* VaryByParam can take various "key" parameter names in query string. Also there
are other attributes like VaryByHeader, VaryByCustom etc. Please refer to MSDN for
more on this.

2. Fragment Caching

Even though this definition refers to caching portion/s of page, it is actually caching a
user control that can be used in a base web form page. In theory, if you have used
include files in the traditional ASP model then this caching model is like caching these
include files separately. In ASP.NET more often this is done through User Controls.
Initially even though one feels a bit misleading, this is a significant technique that
can be used especially when implementing "n" instances of the controls in various
*.aspx pages. We can use the same syntax that we declared for the page level
caching as shown above, but the power of fragment caching comes from the
attribute "VaryByControl". Using this attribute one can cache a user control based on
the properties exposed.

Syntax: <%@ OutputCache Duration="60" VaryByControl="DepartmentId" %>

The above syntax when declared within an *.ascx file ensures that the control is
cached for 60 seconds and the number of representations of cached control is
dependant on the property "DepartmentId" declared in the control.

Add the following into an *.ascx file. Please note the use of tag "Control" and the
cache declaration.

<%@ Control Language="C#"%>


<%@ outputcache duration="60" varybycontrol="DepartMentId" %>
<script runat="server">
private int _Departmentid=0;
public int DepartMentId
{
get{return _Departmentid;}
set{_Departmentid =value;}
}
//Load event of control
void Page_Load(Object sender, EventArgs e)
{
lblText.Text = "Time is " + DateTime.Now.ToString() + " for Department id = "
+ _Departmentid + "\n";
}
</script>
<asp:Label id="lblText" runat="server"></asp:Label>

Add the following to an *.aspx file. Please note the way "Register" tag is used; the
declaration of control using syntax <[TagPrefix]:[TagName]>; Usage of property "
DepartMentId". Open the page in two browsers and closely watch the Base form
timing and the User control timing. Also note that the following page results in two
copies or representation of user control in the cache.

<%@ Page Language="C#" Trace="true" %>


<%@ Register TagPrefix="CacheSample" TagName="Text"
Src="CachingControl.ascx" %>
<script runat=server>
void Page_Load(Object sender, EventArgs e)
{
this.lbltime.Text ="Base form time is " + DateTime.Now.ToString() + "\n";
}
</script>
<html>
<head>
</head>
<body>
<form runat="server" ID="Form2">
<table>
<tbody>
<tr>
<td>
<asp:Label id="lbltime" runat="server"></asp:Label>
</td>
</tr>
<tr>
<td>
<CACHESAMPLE:TEXT id="instance1" runat="Server" DepartMentId="0">
</CACHESAMPLE:TEXT>
</td>
</tr>
<tr>
<td>
<CACHESAMPLE:TEXT id="instance2" runat="Server" DepartMentId="1">
</CACHESAMPLE:TEXT>
</td>
</tr>
</tbody>
</table>
</form>
</body>
</html>

3. Application Level Caching

With Page level Output caching one cannot cache objects between pages within an
application. Fragment caching is great in that sense but has limitations by using user
controls as means to do. We can use the Cache object programmatically to take
advantage of caching objects and share the same between pages. Further the
availability of different overloaded methods gives a greater flexibility for our Cache
policy like Timespan, Absolute expiration etc. But one of the biggest takes is the
CacheDependancy. This means that one can create a cache and associate with it a
dependency that is either another cache key or a file.

In almost all Web applications there could be numerous master tables that act as
lookups to application specific tables. For e.g. if you take up adding a Employee,
usually one has master tables like "tblQualification" to get list of qualifications,
"tblLocations" to get list of locations etc. These tables* are usually set during the
initial application configuration phase and could be modified once a month or even
less than that. Hence it makes sense for us to use them in our Cache rather than
making calls to database on each request. But then what Cache Policy do we adopt?

We cannot hold these objects in Cache for entire application instance, because if
anybody changes data in these tables one has to also refresh the cache. It is here
that CacheDependancy can be used.

* Even though these tables are less frequently used for updates, they are extensively
used in our select statements through out the applications.

Find below the snippet that uses CacheDependancy. Here what I have done is to
provide a list view of existing employees. You need to create a Database in Sql
Server, setup some data before you can continue. The schema scripts are enclosed
in the article.

Add database connection value in Web.Config and change the value as per your
setup.

<appSettings>
<add key="conn" value="Data Source=vishnu;trusted_connection=yes;Initial
Catalog=Users"/>
</appSettings>

First I get the dataset into which I fill the user list. But before this I check for the
cache initially if it exists I directly cast it to a dataset, if not create a cache again.
daUsers.Fill(dsUsers,"tblUsers");

I create the cache with "Users" as key using Cache.Insert* and link this with a file
"Master.xml". This "Master.xml" is a XML file that contains Master data of
"tblQualifications" and "tbllocations". I have used "Server.MapPath" to get the
physical path of the file on the server. The CacheDependancy instance will make sure
that any change in this dependency file means that you need to recreate your cache
key definition. This is a great feature to use since I can recreate my cache only when
required instead of caching the data at the page level.

Cache.Insert("Users",dsUsers,new
System.Web.Caching.CacheDependency(Server.MapPath("Master.xml")) ,
DateTime.Now.AddSeconds(45),TimeSpan.Zero);

* For other overloaded parameters refer MSDN.

Also note how we could use trace within to add my own statements.

HttpContext.Current.Trace.Write("from Database..");

<%@ Page Language="c#" Trace="true" %>


<%@ import Namespace="System" %>
<%@ import Namespace="System.Data" %>
<%@ import Namespace="System.Data.SqlClient" %>
<%@ import Namespace="System.Configuration" %>
<%@ import Namespace="System.Web" %>
<%@ import Namespace="System.Collections" %>
<%@ import Namespace="System.IO" %>
<script runat="server">
void Page_Load(Object sender, EventArgs e)
{
DataSet dsUsers;
try
{
if(Cache["Users"]==null)
{
SqlConnection cn;
dsUsers = new DataSet("new");
cn = new SqlConnection(ConfigurationSettings.AppSettings.Get("conn"));
SqlDataAdapter daUsers;
daUsers = new SqlDataAdapter("Select * from tblUsers",cn);
cn.Open();
daUsers.Fill(dsUsers,"tblUsers");
//Update the cache object
Cache.Insert("Users",dsUsers, new System.Web.Caching.CacheDependency(
Server.MapPath("Master.xml")), DateTime.Now.AddSeconds(45),TimeSpan.Zero);
HttpContext.Current.Trace.Write(DateTime.Now.AddSeconds(45).ToString() + "
is expiry time..");
cn.Close();
cn.Dispose();
HttpContext.Current.Trace.Write("from Database..");
lblChange.Text ="From the database....";
}
else
{
HttpContext.Current.Trace.Write("From cache..");
lblChange.Text ="From the cache....";
dsUsers= (DataSet) Cache["Users"];
}
dlUsers.DataSource =dsUsers;
dlUsers.DataMember = dsUsers.Tables[0].TableName ;
//lblChange.Text += Server.MapPath("Master.xml");
this.DataBind();
}
catch(Exception ex)
{
lblChange.Text = ex.Message;
}
}
</script>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<html>
<head>
<title>Cache Dependency Tester</title>
<meta content="Microsoft Visual Studio 7.0" name="GENERATOR" />
<meta content="C#" name="CODE_LANGUAGE" />
<meta content="JavaScript" name="vs_defaultClientScript" />
<meta content="http://schemas.microsoft.com/intellisense/ie5"
name="vs_targetSchema" />
</head>
<body ms_positioning="GridLayout">
<form id="Form1" method="post" runat="server">
<asp:DataList id="dlUsers" style="Z-INDEX: 101; LEFT: 44px; POSITION: absolute;
TOP: 104px" runat="server" Height="148px" Width="343px" BorderWidth="1px"
GridLines="Horizontal" CellPadding="4" BackColor="White" ForeColor="Black"
BorderStyle="None" BorderColor="#CCCCCC">
<SelectedItemStyle font-bold="True" forecolor="White"
backcolor="#CC3333"></SelectedItemStyle>
<FooterStyle forecolor="Black" backcolor="#CCCC99"></FooterStyle>
<HeaderStyle font-bold="True" forecolor="White"
backcolor="#333333"></HeaderStyle>
<ItemTemplate>
<table>
<tr>
<td>
<%#DataBinder.Eval(Container.DataItem,"UserId")%></td>
<td>
<%#DataBinder.Eval(Container.DataItem,"FirstName")%></td>
<td>
<%#DataBinder.Eval(Container.DataItem,"LastName")%></td>
</tr>
</table>
</ItemTemplate>
</asp:DataList>
<asp:Label id="lblChange" style="Z-INDEX: 102; LEFT: 46px; POSITION: absolute;
TOP: 63px" runat="server" Height="28px" Width="295px"></asp:Label>
<asp:Button id="btnMaster" style="Z-INDEX: 103; LEFT: 50px; POSITION:
absolute; TOP: 293px" onclick="btnMaster_Click" runat="server" Text="Refresh
Master"></asp:Button>
</form>
</body>
</html>

We created the page that initiates and uses the Cache. For testing purpose we need
another page that will overwrite this "Master.xml" on click of a button for which the
code snippet is as follows. This ideally should be our master maintenance page that
adds/updates Master records in database and overwrites the XML. But to make it
easy I have just written an overwriting sample.

<%@ Page Language="C#" Trace="true"%>


<%@ import Namespace="System" %>
<%@ import Namespace="System.Data" %>
<%@ import Namespace="System.Data.SqlClient" %>
<script runat="server">
void btnMaster_Click(Object sender, EventArgs e)
{
//Call save function
this.Save();
}
void Save()
{
try
{
SqlConnection cn;
DataSet dsUsers = new DataSet("Users");
//I have used this to get the Connectionstring from the
//Configuration file.
cn = new SqlConnection(ConfigurationSettings.AppSettings.Get("conn"));
SqlDataAdapter daQualification;
SqlDataAdapter daLocations;
daQualification = new SqlDataAdapter("Select * from tblqualifications",cn);
daLocations = new SqlDataAdapter("Select * from tblLocations",cn);
cn.Open();
daQualification.Fill(dsUsers,"tblqualifications");
daLocations.Fill(dsUsers,"tblLocations");
HttpContext.Current.Trace.Write("Masters data up..");
//Overwrite the XML file. Also please read MSDN on the overloaded parameters for
WriteXml
dsUsers.WriteXml(HttpContext.Current.Server.MapPath
"Master.xml"),XmlWriteMode.WriteSchema);
cn.Close();
cn.Dispose();
}
catch(Exception ex)
{
throw new Exception(ex.Message);
}
}
</script>
<html>
<head>
</head>
<body>
<form runat="server" ID="Form1">
<span>
<table>
<tbody>
<tr>
<td>
<label id="lblRefresh" runat="server">
Rewrite the XML File by clicking the buttonbelow.</label>
</td>
</tr>
<tr align="middle">
<td>
<asp:Button id="btnMaster" onclick="btnMaster_Click" runat="server"
Text="Write XML"></asp:Button>
</td>
</tr>
</tbody>
</table>
</span>
</form>
</body>
</html>

Now once you have created the above pages i.e. one that implements caching and
other that overwrites the dependency file, create two instance of browser and open
the cache implementation page and note for trace, label text; open the other
instance of browser with the page which overwrites the XML. Note the former, the
first time it fetches data from the database and the subsequent request will be from
cache till your expiration time of 45 seconds is reached or anyone overwrites or
changes the "Master.xml" file. Also give a look on Timespan parameter since you
have a concept of Sliding expiration that can also be implemented. Keep refreshing
the first page and you will see that trace indicates the cached page retrieval. Click
the overwrite XML button on the latter page that would overwrite the XML and again
refresh the former page to note that the data is retrieved from database. Though in
this example I have not shown any direct relation between the cached data and the
dependency file (like get values from dependency file and merge with cached object
etc) in terms of integrated usage, this could very easily be designed and
implemented. Dependency caching is a powerful technique that .NET supports and
should be utilized wherever applicable.

Conclusion

Caching is a technique that definitely improves the performance of web applications


if one is careful to have a balance in terms of which data needs to be cached and
parameter values for expiration policy.

User Control can access only within the current application,if u want to access the
user control to other application,u want to copy that user control to that application.

Custom control can access from any application becs it is stored in GAC(Global
Assembly Cache).

We can add the custom control to Visual studio IDE toolbox,but user control can't.

User control is good for static layout


Custom control is good for dynamic layout
User Control will appear in the Solution Explorer where as custom control will appear
in the toolbox,
the significant of both controls is re-usability.User control will use with in the
application where as custom control will use in any application because it is in the
tool box.
Extending the functionality of the existing control is Custom Control and grouping up
of existing controls for desired out put is user control.

Difference between user controls and custom controls in .net (vb, c# net with asp.net)
User controls:

It is newly concept in .net it same like as inheritance concept in oops


In asp.net the base class is system.web.ui.page object
When ever creating user control that will be converting as a class, and this class become
Subclasses of System.web.ui.page class at compile time
User control extension with .ascx
Let us see program how build (at end I will mention difference between user control and
Custom control)

Let us consider with help of IDE

<%@ Control Language =”vb”%>


<form>
<Asp: Label id=”l1” text “enter yr name” runat =”server”/>
<Asp: Textbox id=”t1” runat=”server”/>
</form>

Now this save as labeltextbox.ascx (user control)


Now this user control can be used for any page in your web application
This can be done by
As fallow (just u write in code behind page)
<%@ Register tagprefix=”raghu” tagname=”chinni” src=” labeltextbox.ascx”%>

Now create instance for user control in html file of aspx page

<Raghu: chinni id=”lt” runat =”server”/>

Custom control:
Creating user controls, which are essentially reusable small web pages,
You can also create your own compiled custom controls.
There are three ways to create custom controls:
1) Create a derived custom control by deriving from an existing control.
2) Create a composite control by grouping existing controls together into a new compiled
control.
3) Create a full custom control by deriving from System.Web.UI.WebControls.WebControl
Composite controls are most similar to user controls. The key difference is that composite
Controls are compiled into a DLL and used as you would any server control.
Let us programmatically that will help how to build:

Iam explaining on simple example:

Take notepad example:

Imports System.ComponentModel
Imports System.Web.UI
("<{0}: WebCustomControl1 runat=server>")>
Public Class WebCustomControl1
Inherits System.Web.UI.WebControls.WebControl

Dim text As String

Property [Text]() As String


Get
Return text
End Get

Set(ByVal Value As String)


text = Value
End Set
End Property

Protected Overrides Sub Render(ByVal output As System.Web.UI.HtmlTextWriter)


output.Write([Text])
End Sub

End Class

Now compile then it generate one dll

Now open IDE language is vb.net with asp.net


Just write in html of .vb page

<% @ Register Tag prefix=”raghu” namespace=”chinni” assembly= “WebControlLibrary1” %>

Now create instance


Under

<form>
<raghu:chinni ID=”tatcis” Text=”this is placid man”/><form>

Now press F5

U gets output as
this is placid man

Let us see differences


User control
1) Reusability web page
2) We can’t add to toolbox
3) Just drag and drop from solution explorer to page (aspx)
4) U can register user control to. Aspx page by Register tag
5) A separate copy of the control is required in each application
6) Good for static layout
7) Easier to create
8)Not complied into DLL
9) Here page (user page) can be converted as control then
We can use as control in aspx
Custom controls
1) Reusability of control (or extend functionalities of existing control)
2) We can add toolbox
3) Just drag and drop from toolbox
4) U can register user control to. Aspx page by Register tag
5) A single copy of the control is required in each application
6) Good for dynamics layout
7) Hard to create
8) Compiled in to dll

ASP.NET Page Class Overview


.

When an ASP.NET page is requested and renders markup to a browser, ASP.NET creates
an instance of a class that represents your page. That class is composed not only of the
code that you wrote for the page, but also code that is generated by ASP.NET. This topic
provides an overview of the code that is generated by ASP.NET.

Generating and Running the Page Class Code


An ASP.NET page runs as a unit, combining the server-side elements in a page, such as
controls, with the event-handling code you have written. If you use a Web site project,
you do not have to precompile pages into assemblies. ASP.NET dynamically compiles
pages and runs them the first time they are requested by a user. If there are any changes
to the page or resources the page depends on, the page is automatically recompiled.

Web site projects also support precompilation of a Web project to enhance performance
(for the first time a page request is received) and perform error checking as well as to
support site deployment. For more information, see ASP.NET Web Site Precompilation
Overview

ASP.NET Web application projects must be explicitly compiled before they are deployed.
For more information about differences in compilation between Web site projects and
Web application projects, see Web Application Projects versus Web Site Projects.

The class or classes that the compiler creates depends on whether the page uses the
single-file model or the code-behind model.

Single-File Pages
In a Web site project, you can create single-file pages. In a single-file page, the markup,
server-side elements, and event-handling code are all in a single .aspx file. When the
page is compiled, the ASP.NET generates and compiles a new class that derives from the
base Page class or from a custom base class defined with the Inherits attribute of the
@ Page directive. For example, if you create a new ASP.NET Web page named
SamplePage1 in your application's root directory, a class named ASP.SamplePage1_aspx
is generated that derives from the Page class. For pages in application subfolders, the
subfolder name is used as part of the generated class. The generated class contains
declarations for the controls in the .aspx page and contains your event handlers and other
custom code.

The generated class is compiled into an assembly, and when the page is requested, the
assembly is loaded into the application domain, and then the page class is instantiated
and executed to render output to the browser.
For a Web site project, if you make changes to the page that would affect the generated
class—whether by adding controls or modifying your code—the compiled class code is
invalidated and a new class is generated. For more information on compilation in Web site
projects and in Web application projects, see ASP.NET Compilation Overview and Web
Application Projects versus Web Site Projects.

The following illustration shows the inheritance model for the page class in a single-file
ASP.NET Web page:

Code-Behind Pages
Code-behind pages are the default in Web application projects and are optional in Web
site projects. In the code-behind model, the page's markup and server-side elements,
including control declarations, are in an .aspx file, while your page code is in a separate
code file. The code file contains a partial class—that is, a class declaration with the
keyword partial (Partial in Visual Basic) indicating that it contains only some of the total
code that makes up the full class for the page. In the partial class, you add the code that
your application requires for the page. This typically consists of event handlers, but can
include any methods or properties that you need.

The inheritance model for code-behind pages is slightly more complex than that for
single-file pages. The model is this:

1. The code-behind file contains a partial class that inherits from a base page class.
The base page class can be the Page class, or it can be another class that derives
from Page.
2. The .aspx file contains an Inherits attribute in the @ Page directive that points to
the code-behind partial class.
3. When the page is compiled, ASP.NET generates a partial class based on the .aspx
file; this class is a partial class of the code-behind class file. The generated partial
class file contains declarations for the page's controls. This partial class enables
your code-behind file to be used as part of a complete class without requiring you
to declare the controls explicitly.
4. Finally, ASP.NET generates another class that inherits from the class generated in
Step 3. This second generated class contains the code required to build the page.
The second generated class and the code-behind class are compiled into an
assembly that runs to render output to the browser.

The following illustration shows the inheritance model for the page class in a code-behind
ASP.NET Web page:

When you work with master pages and content pages, both can use the same events
(such as Page_Load).Be sure you know which events come before others. You are
bringing two classes together to create a singlepage class, and a specific order is
required. When an end user requests a content page in the browser, the event
ordering is as follows:

Master page child controls initialization: All server controls contained within the
master page are first initialized.
Content page child controls initialization: All server controls contained in the
content page are initialized.
Master page initialization: The master page itself is initialized.
Content page initialization: The content page is initialized.
Content page load: The content page is loaded (this is the Page_Load event
followed by the Page_LoadComplete event).
Master page load: The master page is loaded (this is also the Page_Load event).
Master page child controls load: The server controls on the master page are
loaded onto the page.
Content page child controls load: The server controls on the content page are
loaded onto the page.

How to access master page controls from content pages

Consider the following scenario

Master Page

<%@ master language="C#" %>


<html>
<head id="Head1" runat="server">
<title>Master Page</title>
</head>
<body>
<form id="Form1" runat="server">
<table id="header" style="WIDTH: 100%; HEIGHT:80px" cellspacing="1"
cellpadding="1" border="1">
<tr>
<td width="100%" style="TEXT-ALIGN: center">
<asp:label runat="server" id="Header">
This is the default header in the MasterPage</asp:label>
</td>
</tr>
</table>
-------------------------------------------------------------------------------------

Content Page

<%@ page language="C#" master="~/ExposeHeader.master" %>


<script runat="server">
void Page_Load(object sender, System.EventArgs e)
{
Label headerLabel = (Label)
Master.FindControl("Header"); // Header is my master page label id.
headerLabel.Text = "This label content is set through the Page_Load event of the
child page";
}
</script>

Here I am using Master.FindControl with the master page control's id (The identifier
for the control to be found). Find control will search the current naming container for
a server control with the specified id parameter. It returns the specified control or
null if the specified control does not exist.

Calling JavaScript from ASP.NET Master


Page and Content Pages - Part I
Calling JavaScript from Master and Content Pages confuses a lot of developers. In
this article, we will see some common problems and their solutions of calling
JavaScript from a Master/Content page. This article is Part I of the two part series
and will cover JavaScript in Master Pages. The next article will cover JavaScript in
Content pages.
Update: Part II of this article can be read over here Calling JavaScript from ASP.NET
Master Page and Content Pages - Part II
Call JavaScript From Master Page
You can call an existing JavaScript function from a Master Page or can create one on
the fly. Here are some common scenarios:
1. Create a JavaScript function on the fly and call the JavaScript function in
the MasterPage Page_Load() event
C#
protected void Page_Load(object sender, EventArgs e)
{
string someScript = "";
someScript = "<script language='javascript'>alert('Called from
CodeBehind');</script>";
Page.ClientScript.RegisterStartupScript(this.GetType(),
"onload", someScript);
}
VB.NET
Protected Sub Page_Load(ByVal sender As Object, ByVal e As
System.EventArgs) Handles Me.Load
Dim someScript As String = ""
someScript = "<script language='javascript'>alert('Called from
CodeBehind');</script>"
Page.ClientScript.RegisterStartupScript(Me.GetType(), "onload",
someScript)
End Sub

The Page.ClientScript.RegisterStartupScript() allows you to emit client-side script


blocks from code behind. More info can be found over here
http://msdn.microsoft.com/en-
us/library/system.web.ui.clientscriptmanager.registerstartupscript.aspx
2. Call an existing JavaScript function on MasterPage Page_Load() event
Let us assume you have an existing JavaScript function declared in between the
<head> tags, then here’s how to call that function from Page_Load()
<head runat="server">
<title></title>
<script type="text/javascript">
function invokeMeMaster() {
alert('I was invoked from Master');
}
</script>
<asp:ContentPlaceHolder id="head" runat="server">
</asp:ContentPlaceHolder>
</head>
C#
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.ClientScript.IsStartupScriptRegistered("alert"))
{
Page.ClientScript.RegisterStartupScript
(this.GetType(), "alert", "invokeMeMaster();", true);
}

}
VB.NET
Protected Sub Page_Load(ByVal sender As Object, ByVal e As
System.EventArgs) Handles Me.Load
If (Not Page.ClientScript.IsStartupScriptRegistered("alert"))
Then
Page.ClientScript.RegisterStartupScript(Me.GetType(),
"alert", "invokeMeMaster();", True)
End If
End Sub
3. Call JavaScript function from MasterPage on Button click
If you want to call a JavaScript function on a Button click, then here’s how to do so:
<head runat="server">
<title></title>
<script type="text/javascript">
function invokeMeMaster() {
alert('I was invoked from Masterdotnetcurry');
}
</script>
<asp:ContentPlaceHolder id="head" runat="server">
</asp:ContentPlaceHolder>
</head>
In the <body> tag, add a Button and use the OnClientClick to call this function
<asp:Button ID="btnMaster" runat="server" Text="Button"
OnClientClick="return invokeMeMaster();"/>

The OnClientClick() is called before the postback occurs. This gives us a place to
check for some condition and cancel the submit if the condition is not satisfied. We
will see an example in Tip 6.
4. Access a control on the MasterPage using JavaScript
If you have a control on the MasterPage and need to access it using JavaScript, then
here’s how to do so. In this sample, we will test the length of the TextBox to see if
there are 5 or more letters. If the number of letters is less than 5, the form submit
will be cancelled.
Add a TextBox and a Button control in the MasterPage (outside the
ContentPlaceHolder) as shown below
<body>
<form id="form1" runat="server">
<div>
<asp:Panel ID="panelMaster" GroupingText="MasterPage controls"
runat="server">
<asp:TextBox ID="txtMaster" runat="server"></asp:TextBox>
<asp:Button ID="btnMaster" runat="server" Text="Button"
OnClientClick="return accessMasterControl();" />
<br />
</asp:Panel>
<asp:ContentPlaceHolder id="ContentPlaceHolder1" runat="server">

</asp:ContentPlaceHolder>
</div>
</form>
</body>
In the <head> element of the MasterPage, add the following code:
<head runat="server">
<title></title>
<script type="text/javascript">
function accessMasterControl() {
if (document.getElementById('<%=txtMaster.ClientID
%>').value.length <= 5) {
alert('Minimum 5 characters required')
return false;
}
else { return true;}
}
</script>
<asp:ContentPlaceHolder id="head" runat="server">
</asp:ContentPlaceHolder>
</head>
5. Access a control on the Content Page from a MasterPage using JavaScript
If you have a control on the Content Page which has to be accessed in the
MasterPage using JavaScript, then here’s how to do so:
On the Content Page, create a TextBox as shown below :
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1"
Runat="Server">
<asp:Panel ID="panelContent" GroupingText="ContentPage Controls"
runat="server">
<asp:TextBox ID="txtContent" runat="server"></asp:TextBox>
</asp:Panel>
</asp:Content>

Now access and populate the TextBox ‘txtContent’ from the MasterPage
<head runat="server">
<title></title>
<script type="text/javascript">
function accessControlContentPage() {
var txtCont = document.getElementById('<%=
Page.Master.FindControl("ContentPlaceHolder1").FindControl("txtContent"
).ClientID %>');
txtCont.value = "I got populated using Master
Page";
}
</script>
<asp:ContentPlaceHolder id="head" runat="server">
</asp:ContentPlaceHolder>
</head>
6. Ask user before submitting the form on a MasterPage
In order to ask the user for a confirmation before submitting the form, you can either
use code behind or can use simple mark up as shown below:
Declare a Button control that causes postback and write the following code in
MasterPage.master.cs or .vb
C#
protected void Page_Load(object sender, EventArgs e)
{
string myScript = @"<script type='text/javascript'>
function askBeforeSubmit() {
var msg = 'Are you sure?';
return confirm(msg);
}
</script>";
Page.ClientScript.RegisterClientScriptBlock(this.GetType(),
"MakeSure", myScript);
form1.Attributes.Add("onsubmit", "return askBeforeSubmit();");
}
VB.NET
Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs)
Dim myScript As String = "<script type='text/javascript'>" &
ControlChars.CrLf & " function askBeforeSubmit() {" &
ControlChars.CrLf & " var msg = 'Are you sure?';" &
ControlChars.CrLf & " return confirm(msg);" & ControlChars.CrLf &
" }" & ControlChars.CrLf & " </script>"
Page.ClientScript.RegisterClientScriptBlock(Me.GetType(),
"MakeSure", myScript)
form1.Attributes.Add("onsubmit", "return askBeforeSubmit();")
End Sub
If you want to avoid a code-behind approach, you can ask the user for a confirmation
by using the OnClientClick() on the Submit button
<asp:Button ID="btnMaster" runat="server" Text="Button"
OnClientClick="return confirm('Are you sure?');"/>
Calling JavaScript from ASP.NET Master
Page and Content Pages - Part II
In this article, we will see some common problems and their solutions of calling
JavaScript from a Master/Content page. This article is Part II of the series ‘Calling
JavaScript from ASP.NET Master Page and Content Pages’ and in this article; we will
cover JavaScript in Content Pages. Part I of this article can be read over here Calling
JavaScript from ASP.NET Master Page and Content Pages - Part I
Call JavaScript from Content Page
Here are some common scenarios of executing JavaScript from a Content Page.
1. Create a JavaScript function on the fly and call the JavaScript function in
the Content Page Page_Load() event
C#
protected void Page_Load(object sender, EventArgs e)
{
const string someScript = "alertMe";
if (!ClientScript.IsStartupScriptRegistered(this.GetType(),
someScript))
{
ClientScript.RegisterStartupScript(this.GetType(),
someScript, "alert('I was called from Content page!')",
true);
}
}
VB.NET
Protected Sub Page_Load(ByVal sender As Object, ByVal e As
System.EventArgs) Handles Me.Load
Dim someScript As String = "alertMe"
If (Not ClientScript.IsStartupScriptRegistered(Me.GetType(),
someScript)) Then
ClientScript.RegisterStartupScript(Me.GetType(),
someScript, "alert('I was called from Content page!')", True)
End If
End Sub
2. Call a JavaScript function declared in a .js file from the Content Page
If you have a .js file and want to call the function from your Content Page, then
here’s how to do so.
Let’s create a .js file called TestScript.js and add the following function in the .js file.
function insideJS() {
alert('Inside .js');
}
Assuming that your .js file is kept in a Script folder, reference the file in your
MasterPage in the following manner.
<head runat="server">
<title></title>
<script src="Scripts/TestScript.js" type="text/javascript"></script>
...
Now in your Content Page(in our case Default.aspx.cs or .vb), call the JavaScript
function on the Page_Load:
C#

protected void Page_Load(object sender, EventArgs e)


{
if (!
Master.Page.ClientScript.IsStartupScriptRegistered("alert"))
{
Master.Page.ClientScript.RegisterStartupScript
(this.GetType(), "alert", "insideJS();", true);
}
}

VB.NET
Protected Sub Page_Load(ByVal sender As Object, ByVal e As
EventArgs)
If (Not
Master.Page.ClientScript.IsStartupScriptRegistered("alert")) Then
Master.Page.ClientScript.RegisterStartupScript
(Me.GetType(), "alert", "insideJS();", True)
End If
End Sub
3. Referencing the .js file from a Content Page instead of the Master page
The approach shown above in Tip 2 works well, however this approach would add a
reference to the .js file for every page in the application (since we are adding the .js
in the Master Page). If you want to avoid this approach, then remove the reference
added to the .js file in Tip 2 in the Master Page. Now add a reference to the .js file
from the Content Page using the ‘RegisterClientScriptInclude’ as shown below:
C#
protected void Page_Load(object sender, EventArgs e)
{
Page.ClientScript.RegisterClientScriptInclude("selective",
ResolveUrl(@"Scripts\TestScript.js"));
if (!
Master.Page.ClientScript.IsStartupScriptRegistered("alert"))
{
Master.Page.ClientScript.RegisterStartupScript
(this.GetType(), "alert", "insideJS();", true);
}
}
VB.NET
Protected Sub Page_Load(ByVal sender As Object, ByVal e As
EventArgs)
Page.ClientScript.RegisterClientScriptInclude("selective",
ResolveUrl("Scripts\TestScript.js"))
If (Not
Master.Page.ClientScript.IsStartupScriptRegistered("alert")) Then

Master.Page.ClientScript.RegisterStartupScript(Me.GetType(), "alert",
"insideJS();", True)
End If
End Sub
Using this approach, we can avoid referencing the .js file for every content page.
Note: This approach adds the JavaScript reference inside the <body>tag of the
page.
4. Declare JavaScript inside the Content page and execute it
If you are looking out to declare JavaScript inside the Content Page, then here’s how
to do so. Add the following markup inside the Content page (in our case
Default.aspx)
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1"
Runat="Server">
<asp:Panel ID="panelContent" GroupingText="ContentPage Controls"
runat="server">
<asp:TextBox ID="txtContent" runat="server"></asp:TextBox>
<asp:Button ID="btnContent" runat="server" Text="Button"
OnClientClick="Populate();" />
</asp:Panel>
<script type="text/javascript" language="javascript">
function Populate() {
{
document.getElementById('<%=txtContent.ClientID
%>').value = "Hi";
}
}
</script>
</asp:Content>
The markup shown above populates the textbox with some text on a button click.
5. Accessing a Control on the Master Page From a ContentPage using
JavaScript
In our previous article, we saw how in Tip 5 To access a control on the ContentPage
From a Master Page using JavaScript. In this tip, we will see how to access a control
kept on the MasterPage from a ContentPage. Do the following:
We have added a textbox control to the <body> of the MasterPage as shown below:
<body>
<form id="form1" runat="server">
<div>
<asp:Panel ID="panelMaster" GroupingText="MasterPage controls"
runat="server">
<asp:TextBox ID="txtMaster" runat="server"></asp:TextBox>
<br />
</asp:Panel>
<asp:ContentPlaceHolder id="ContentPlaceHolder1" runat="server">

</asp:ContentPlaceHolder>
</div>
</form>
</body>
We will now access this TextBox ‘txtMaster’ in the ContentPage using JavaScript
To do so, go to the Content page (Default.aspx) and add the following line below the
<Page> directive to register the MasterPage
<%@ Page Title="" Language="C#" MasterPageFile="~/MasterPage.master"
AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
...
<%@ MasterType VirtualPath="~/MasterPage.master" %>
...
Now in the code behind of Default.aspx.cs or .vb, access the MasterPage control in
the following manner
C#
protected void Page_Load(object sender, EventArgs e)
{
TextBox tb = (TextBox)Master.FindControl("txtMaster");
string val = tb.ClientID;
string script = @"<script>
function PopulateMaster() {
document.getElementById('" + val + @"').value = 'Via
Content Page. Love dotnetcurry';
}
PopulateMaster();
</script>";
if (!Page.ClientScript.IsStartupScriptRegistered("Mast"))
{
Page.ClientScript.RegisterStartupScript(this.GetType(),
"Mast", script);
}

}
ASP.NET Master Pages
http://msdn.microsoft.com/en-us/library/wtxbf3hh.aspx

.NET Framework 4
Other Versions
ASP.NET master pages allow you to create a consistent layout for the pages in your
application. A single master page defines the look and feel and standard behavior that
you want for all of the pages (or a group of pages) in your application. You can then
create individual content pages that contain the content you want to display. When users
request the content pages, they merge with the master page to produce output that
combines the layout of the master page with the content from the content page.

This overview contains the following sections:

• How Master Pages Work


• Advantages of Master Pages
• Run-time Behavior of Master Pages
• Master Page and Content Page Paths
• Master Pages and Themes
• Scoping Master Pages
• Related Topics
• Reference
How Master Pages Work
Master pages actually consist of two pieces, the master page itself and one or more
content pages.

Note
You can also nest master pages. For details, see Nested ASP.NET Master Pages.

Master Pages

A master page is an ASP.NET file with the extension .master (for example, MySite.master)
with a predefined layout that can include static text, HTML elements, and server controls.
The master page is identified by a special @ Master directive that replaces the @ Page
directive that is used for ordinary .aspx pages. The directive looks like the following.

VB
C#
C++
F#
JScript

Copy
<%@ Master Language="C#" %>
The @ Master directive can contain most of the same directives that a @ Control directive
can contain. For example, the following master-page directive includes the name of a
code-behind file, and assigns a class name to the master page.

VB
C#
C++
F#
JScript

Copy
<%@ Master Language="C#" CodeFile="MasterPage.master.cs"
Inherits="MasterPage" %>

In addition to the @ Master directive, the master page also contains all of the top-level
HTML elements for a page, such as html, head, and form. For example, on a master page
you might use an HTML table for the layout, an img element for your company logo, static
text for the copyright notice, and server controls to create standard navigation for your
site. You can use any HTML and any ASP.NET elements as part of your master page.

Replaceable Content Placeholders

In addition to static text and controls that will appear on all pages, the master page also
includes one or more ContentPlaceHolder controls. These placeholder controls define
regions where replaceable content will appear. In turn, the replaceable content is defined
in content pages. After you have defined the ContentPlaceHolder controls, a master page
might look like the following.

VB
C#
C++
F#
JScript
Copy
<%@ Master Language="C#" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML


1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >


<head runat="server" >
<title>Master page title</title>
</head>
<body>
<form id="form1" runat="server">
<table>
<tr>
<td><asp:contentplaceholder id="Main" runat="server" /></td>
<td><asp:contentplaceholder id="Footer" runat="server" /></td>
</tr>
</table>
</form>
</body>
</html>

Content Pages

You define the content for the master page's placeholder controls by creating individual
content pages, which are ASP.NET pages (.aspx files and, optionally, code-behind files)
that are bound to a specific master page. The binding is established in the content page's
@ Page directive by including a MasterPageFile attribute that points to the master page to
be used. For example, a content page might have the following @ Page directive, which
binds it to the Master1.master page.

VB
C#
C++
F#
JScript

Copy
<%@ Page Language="C#" MasterPageFile="~/MasterPages/Master1.master"
Title="Content Page"%>

In the content page, you create the content by adding Content controls and mapping
them to ContentPlaceHolder controls on the master page. For example, the master page
might have content placeholders called Main and Footer. In the content page, you can
create two Content controls, one that is mapped to the ContentPlaceHolder control Main
and the other mapped to the ContentPlaceHolder control Footer, as shown in the following
figure.

Replacing placeholder content

After creating Content controls, you add text and controls to them. In a content page,
anything that is not inside the Content controls (except script blocks for server code)
results in an error. You can perform any tasks in a content page that you do in an
ASP.NET page. For example, you can generate content for a Content control using server
controls and database queries or other dynamic mechanisms.

A content page might look like the following.

VB
C#
C++
F#
JScript
Copy
This language is not supported or no code example is available.

[C#]

Copy
<% @ Page Language="C#" MasterPageFile="~/Master.master" Title="Content Page
1" %>
<asp:Content ID="Content1" ContentPlaceHolderID="Main" Runat="Server">
Main content.
</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="Footer" Runat="Server" >


Footer content.
</asp:content>

The @ Page directive binds the content page to a specific master page, and it defines a
title for the page that will be merged into the master page. Note that the content page
contains no other markup outside of the Content controls. (The master page must contain
a head element with the attribute runat="server" so that the title setting can be merged
at run time.)

You can create multiple master pages to define different layouts for different parts of your
site, and a different set of content pages for each master page.

Back to top

Advantages of Master Pages


Master pages provide functionality that developers have traditionally created by copying
existing code, text, and control elements repeatedly; using framesets; using include files
for common elements; using ASP.NET user controls; and so on. Advantages of master
pages include the following:

• They allow you to centralize the common functionality of your pages so that you
can make updates in just one place.
• They make it easy to create one set of controls and code and apply the results to
a set of pages. For example, you can use controls on the master page to create a
menu that applies to all pages.
• They give you fine-grained control over the layout of the final page by allowing
you to control how the placeholder controls are rendered.
• They provide an object model that allows you to customize the master page from
individual content pages.

Back to top
Run-time Behavior of Master Pages
At run time, master pages are handled in the following sequence:

1. Users request a page by typing the URL of the content page.


2. When the page is fetched, the @ Page directive is read. If the directive references
a master page, the master page is read as well. If this is the first time the pages
have been requested, both pages are compiled.
3. The master page with the updated content is merged into the control tree of the
content page.
4. The content of individual Content controls is merged into the corresponding
ContentPlaceHolder control in the master page.
5. The resulting merged page is rendered to the browser.

The process is illustrated in the following diagram.

Master pages at run time

From the user's perspective, the combined master and content pages are a single,
discrete page. The URL of the page is that of the content page.

From a programming perspective, the two pages act as separate containers for their
respective controls. The content page acts as a container for the master page. However,
you can reference public master-page members from code in the content page, as
described in the next section.

Note that the master page becomes a part of the content page. In effect, the master page
acts in much the same way a user control acts — as a child of the content page and as a
container within that page. In this case, however, the master page is the container for all
of the server controls that are rendered to the browser. The control tree for a merged
master and content page looks something like this:

Copy
Page
Master Page
(Master page markup and controls)
ContentPlaceHolder
Content page markup and server controls
(Master page markup and controls)
ContentPlaceHolder
Content page markup and server controls
(Master page markup and controls)

This diagram is simplified; if the content page does not have corresponding Content
controls, the master page might also have markup and controls in the ContentPlaceHolder
controls.

In general, this structure has no effect on how you construct your pages or program them.
However, in some cases, if you set a page-wide property on the master page, it can affect
the behavior of the content page, because the master page is the closest parent for the
controls on the page. For example, if you set the EnableViewState property on the
content page to true but set the same property to false in the master page, view state will
effectively be disabled because the setting on the master page will take priority.

Back to top

Master Page and Content Page Paths


When a content page is requested, its content is merged with the master page, and the
page runs in the context of the content page. For example, if you get the
CurrentExecutionFilePath property of the HttpRequest object, whether in content page
code or in master page code, the path represents the location of the content page.

The master page and content page do not have to be in the same folder. As long as the
MasterPageFile attribute in the content page's @ Page directive resolves to a .master
page, ASP.NET can merge the content and master pages into a single rendered page.

Referencing External Resources

Both the content page and master page can contain controls and elements that reference
external resources. For example, both might contain image controls that reference image
files, or they might contain anchors that reference other pages.

The context for the merged content and master pages is that of the content page. This
can affect how you specify URLs for resources, such as image files and target pages, in
anchors.

Server Controls

In server controls on master pages, ASP.NET dynamically modifies the URLs of properties
that reference external resources. For example, you might put an Image control on a
master page and set its ImageUrl property to be relative to the master page. At run time,
ASP.NET will modify the URL so that it resolves correctly in the context of the content
page.

ASP.NET can modify URLs in the following cases:


• The URL is a property of an ASP.NET server control.
• The property is marked internally in the control as being a URL. (The property is
marked with the attribute UrlPropertyAttribute.) In practical terms, ASP.NET server
control properties that are commonly used to reference external resources are
marked in this way.

Other Elements

ASP.NET cannot modify URLs on elements that are not server controls. For example, if you
use an img element on a master page and set its src attribute to a URL, ASP.NET will not
modify the URL. In that case, the URL will be resolved in the context of the content page
and create the URL accordingly.

In general, when working with elements on master pages, it is recommended that you use
a server control, even for elements that do not require server code. For example, instead
of using an img element, use an Image server control. That way, ASP.NET can resolve
URLs correctly and you can avoid maintenance issues that might arise if you move the
master or content page.

For more information about specifying paths for ASP.NET server controls, see ASP.NET
Web Project Paths.

Back to top

Master Pages and Themes


You cannot directly apply an ASP.NET theme to a master page. If you add a theme
attribute to the @ Master directive, the page will raise an error when it runs.

However, themes are applied to master pages under these circumstances:

• If a theme is defined in the content page. Master pages are resolved in the
context of content pages, so the content page's theme is applied to the master
page as well.
• If the site as a whole is configured to use a theme by including a theme definition
in the pages Element (ASP.NET Settings Schema) element.

For more information, see ASP.NET Themes and Skins.

Back to top

Scoping Master Pages


You can attach content pages to a master page at three levels:

• At the page level You can use a page directive in each content page to bind it
to a master page, as in the following code example.
VB

C#

C++

F#

JScript

Copy

This language is not supported or no code example is available.

VB

C#

C++

F#

JScript
Copy

<%@ Page Language="C#" MasterPageFile="MySite.Master" %>


• At the application level By making a setting in the pages element of the
application's configuration file (Web.config), you can specify that all ASP.NET
pages (.aspx files) in the application automatically bind to a master page. The
element might look like the following.

Copy

<pages masterPageFile="MySite.Master" />


If you use this strategy, all ASP.NET pages in the application that have Content controls
are merged with the specified master page. (If an ASP.NET page does not contain Content
controls, the master page is not applied.)
• At the folder level This strategy is like binding at the application level, except
that you make the setting in a Web.config file in one folder only. The master-page
bindings then apply to the ASP.NET pages in that folder.

When a request reaches IIS, http modules, http handler, task of web server,