What ASP.NET Programmers Should Know About Application Domains
When we launch the Notepad program in Windows, the program executes inside of a container known as a process. We can launch multiple instances of Notepad, and each instance will run in a dedicated process. Using the Task Manager application, we can see a list of all processes currently executing in the system.
A process contains the executable code and data of a program inside memory it has reserved from the operating system. There will be at least one thread executing instructions inside of the process, and in most cases there are multiple threads. If the program opens any files or other resources, those resources will belong to the process.
A process is also boundary. Erroneous code inside of a process cannot corrupt areas outside of the current process. It is easy to communicate inside of a process, but special techniques are required to communicate from one process to another. Each process also runs under a specific security context which can dictate what the process can do on the machine and network.
A process is the smallest unit of isolation available on the Windows operating system. This could pose a problem for an ISP who wants to host hundreds of ASP.NET applications on a single server. The ISP will want to isolate each ASP.NET application to prevent one application from interfering with another company’s application on the same server, but the relative cost of launching and executing a process for hundreds of applications may be prohibitive.
I opened 2 notepad, In task manger window I can see Two application and when I click on one application and go to Process there are two process running for the Notepad.
I try to end one application by End application because say it is not responding than other application was there. this shows in windows one process does not affect other process boundary Same as we have concept of APPDOMAIN in ASP .net.
Introducing the Application Domain
.NET introduces the concept of an application domain, or AppDomain. Like a process, the AppDomain is both a container and a boundary. The .NET runtime uses an AppDomain as a container for code and data, just like the operating system uses a process as a container for code and data. As the operating system uses a process to isolate misbehaving code, the .NET runtime uses an AppDomain to isolate code inside of a secure boundary.
Note, however, that the application domain is not a secure boundary when the application runs with full trust. Applications running with full trust can execute native code and circumvent all security checks by the .NET runtime. ASP.NET applications run with full trust by default.
An AppDomain belongs to only a single process, but single process can hold multiple AppDomains. An AppDomain is relatively cheap to create (compared to a process), and has relatively less overhead to maintain than a process. For these reasons, an AppDomain is a great solution for the ISP who is hosting hundreds of applications. Each application can exist inside an isolated AppDomain, and many of these AppDomains can exist inside of a single process – a cost savings.
AppDomains And You
You’ve created two ASP.NET applications on the same server, and have not done any special configuration. What is happening?
A single ASP.NET worker process will host both of the ASP.NET applications. On Windows XP and Windows 2000 this process is named aspnet_wp.exe, and the process runs under the security context of the local ASPNET account. On Windows 2003 the worker process has the name w3wp.exe and runs under the NETWORK SERVICE account by default.
An object lives in one AppDomain. Each ASP.NET application will have it’s own set of global variables: Cache, Application, and Session objects are not shared. Even though the code for both of the applications resides inside the same process, the unit of isolation is the .NET AppDomain. If there are classes with shared or static members, and those classes exist in both applications, each AppDomain will have it’s own copy of the static fields – the data is not shared. The code and data for each application is safely isolated and inside of a boundary provided by the AppDomain
In order to communicate or pass objects between AppDomains, you’ll need to look at techniques in .NET for communication across boundaries, such as .NET remoting or web services.
Note again: the one caveat to the idea of an AppDomain as a boundary is that ASP.NET applications will run with full trust by default. Fully trusted code can execute native code, and native code can essentially have access to anything inside the process. You’ll need to run applications with partial trust to restrict access to unmanged code and verify all managed code to secure AppDomains.
Shadow Copies and Restarts
Once an assembly is loaded into an AppDomain, there is no way to remove the assembly from the AppDomain. It is possible, however, to remove an AppDomain from a process.
If you copy an updated dll into an application’s bin subdirectory, the ASP.NET runtime recognizes there is new code to execute. Since ASP.NET cannot swap the dll into the existing AppDomain , it starts a new AppDomain. The old application domain is “drain stopped”, that is, existing requests are allowed to finish executing, and once they are all finished the AppDomain can unload. The new AppDomain starts with the new code and begins taking all new requests.
Typically, when a dll loads into a process, the process locks the dll and you cannot overwrite the file on disk. However, AppDomains have a feature known as Shadow Copy that allows assemblies to remain unlocked and replaceable on disk.
The runtime initializes ASP.NET with Shadow Copy enabled for the bin directory. The AppDomain will copy any dll it needs from the bin directory to a temporary location before locking and loading the dll into memory. Shadow Copy allows us to overwrite any dll in the bin directory during an update without taking the web application offline.
**************************************************************************************************************
By default Only One Worker Process per application Pool
**************************************************************************************************************
By default Only One Worker Process per application Pool
References Beginner’s Guide: How IIS Process ASP.NET Request
What is the difference between Web Farm and Web Garden?
I have 7 application Pool in my IIs PIC, and One app pool is set as defautapppool ,So When we create virtual directory for hosting our application in IIS that time we can set the APP pool for our web application.
Then App pool is container of worker process than We can set number of worker process to be run inside app pool, If there are multiple worker process inside app domain if one app domain ailed to handel specific request than other worker process will do.
WEB GARDEN:
Web garden is a scenario in which a single machine has multiple asp.net worker processes running simultaneously. A web garden is utilized on a multi-core web server. To achieve more robust execution and processing of the C# ASP .NET web application threads, each worker process within the application pool would execute on an individual processor. It is created within Internet Information Services (IIS) by creating an application pool, selecting the Performance tab, and under the "Web Garden" section, setting the maximum number of worker processes to a value greater than 1.
USE: Rather than using the typical hosting environments, the web gardens use more resources, and may also be slower in performance due to which there is unnecessary complexity. It has useful scenarios which may include when a non-CPU bound application needs to execute a long running request, such as an intensive computational request, long database transaction, or other long process. In both cases, a web garden could offer a solution by offloading the single worker process and distributing incoming requests amongst the workers in the application pool.
The larger gain for web gardens is not speed, but rather robustness. Due to their robustness, enabling web gardens can often be a good way to see if a C# ASP .NET web application will function correctly in a multi-server web farm environment. Often, if a web application performs well in a garden scenario, it will typically be easier to migrate to a web farm.
Advantages of Web Garden
Application pool and App-domain , both of them can provide isolation's, but use different approaches. Application pool use the process to isolate the applications which works without .NET. But App-domain is another isolation methods provided by .NET. If your server host thousands of web sites, you wont use thousands of the application pool to isolate the web sites, just because, too many processes running will kill the OS. However, sometime you need application pool. One of the advantages for application pool is that you can config the identity for application pool. Also you have more flexible options to recycle the application pool. At least right now, IIS didn't provide explicit options to recycle the app-domain.
If you only have a single site in your app pool, then an app pool and an App-domain recycle will be quite similar. The app pool recycle will recycle the entire w3wp.exe process while the App-domain will recycle the .NET App-domain only, but since most of what that needs to be recycled lives in the App-domain, they will achieve the same thing. It's just a matter of which is easier for you to do. But, if the App-domain recycle doesn't do the trick, then try a full app pool recycle. This will depend on your situation.
If you have multiple sites in the app pool, then an App-domain is preferred because it won't touch any of the other sites or applications in the app pool and is isolated to just the single application/App-domain in the app pool.
Mulitple Appdomains can exist in Win32 process.
What is the difference between Web Farm and Web Garden?
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” comes 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
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: 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.
I have 7 application Pool in my IIs PIC, and One app pool is set as defautapppool ,So When we create virtual directory for hosting our application in IIS that time we can set the APP pool for our web application.
Then App pool is container of worker process than We can set number of worker process to be run inside app pool, If there are multiple worker process inside app domain if one app domain ailed to handel specific request than other worker process will do.
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
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.
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.
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 HttpApplicationFactoryclass.. 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.
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.
When client request for some information from a web server, request first reaches to HTTP.SYS of IIS. HTTP.SYS then send the request to respective Application Pool. Application Pool then forward the request to worker process to load the ISAPI Extension which will create an HTTPRuntime Object to Process the request via HTTPModule and HTTPHanlder. After that the ASP.NET Page LifeCycle events starts.
This was just overview of IIS Request Processing to let Beginner’s know how the request get processed in backend. If you want to learn in details please check the link for Reference and further Study section.
I have been asked this question many times by different readers of my blog. They wanted to know about the fundamentals of Web Farms and Web Garden. In this blog post, I am going to explain the exact difference between web farm and web garden, and the advantages and disadvantages of using them. I have also described how to create web garden in different version of IIS.
Overview
Visual Studio has its own integrated ASP.NET engine which is used to run the ASP.NET Web application from Visual Studio. ASP.NET Development Server is responsible for executing all the requests and responses from the client. Now after the end of development, when you want to host the site on some server to allow other people to access, concept of web servers comes in between. A web server is responsible for providing the response for all the requests that are coming from clients. The below diagram shows the typical deployment structure of an ASP.NET Web application with a single IIS.
Clients request for resources and IIS process the request and send back to clients. If you want to know more details on How IIS Processes the request, please read one of my articles about “How IIS Process ASP.NET Request?”.
Web Farm
This is the case where you have only one web server and multiple clients requesting for resources from the same server. But when are is huge amount of incoming traffic for your web sites, one standalone server is not sufficient to process the request. You may need to use multiple servers to host the application and divide the traffic among them. This is called “Web Farm”. So when you are hosting your single web site on multiple web servers over load balancer is called “Web Farm”. The below diagram shows the overall representation of Web Farms.
In general web farm architecture, a single application is hosted on multiple IIS Server and those are connected with the VIP (Virtual IP) with Load Balancer. Load Balancer IPs are exposed to external world to access. So whenever some request will come to server from clients, it will first hit the Load Balancer, then based on the traffic on each server, LB distributes the request to the corresponding web server. These web servers may share the same DB server or may be they can use a replicated server in the back end.
So, in a single statement, when we host a web application over multiple web servers to distribute the load among them, it is called Web Farm.
Web Garden
Now, let’s have a look at what is Web Garden? Both the terms sound the same, but they are totally different from each other. Before starting with Web Garden, I hope you have a fundamental idea of what an Application Pool is and what a Worker Process is. If you have already read the article, “How IIS Processes ASP.NET Request ?”, then I can expect that you now have a good idea about both of them.
Just to recall, when we are talking about requesting processing within IIS, Worker Process (w3wp.exe) takes care of all of these. Worker Process runs the ASP.NET application in IIS. All the ASP.NET functionality inside IIS runs under the scope of worker process. Worker Process is responsible for handling all kinds of request, response, session data, cache data. Application Pool is the container of worker process. Application pool is used to separate sets of IIS worker processes and enables a better security, reliability, and availability for any web application.
Now, by default, each and every Application pool contains a single worker process. Application which contains the multiple worker process is called “Web Garden”. Below is the typical diagram for a web garden application.
In the above diagram, you can see one of the applications containing the multiple worker processes, which is now a web garden.
So, a Web application hosted on multiple servers and access based on the load on servers is called Web Farms and when a single application pool contains multiple Worker processes, it is called a web garden.
Create Web Garden in IIS 6 and IIS 7
Now, I am going to show how you can change the Number of Worker processes in both IIS 6 and IIS 7. For IIS 6, Right Click on Application Pool > Properties > Goto Performance Tab.
In the “Performance Tab” section, you would have one option called “Web Garden” where worker process sets to “1”, you can set the number of worker processes that you required.
For IIS 7, Right Click on Application Pool > Go To Advance Settings > In Process Model section, you will have “Maximum Worker Processes”. You can change it more than 1 to make it as a web garden.
In the above image, you can also check the definition of Web Garden.
You can find one of my previous articles on the basics of the same over here.
Advantages of Web Farm and Web Garden
Now, let’s have a look into the advantages of both the Web Farms and Web Gardens.
Advantages of Web Farm
- It provides high availability. If any of the servers in the farm goes down, Load balancer can redirect the requests to other servers.
- Provides high performance response for client requests.
- Provides better scalability of the web application and reduces the failure of the application.
- Session and other resources can be stored in a centralized location to access by all the servers.
Advantages of Web Garden
- Provides better application availability by sharing requests between multiple worker process.
- Web garden uses processor affinity where application can be swapped out based on preference and tag setting.
- Less consumption of physical space for web garden configuration.
How to Manage Session in Web Farm Mode?
While using session, requests are distributed among different servers. By default, session mode is set to In Proc where session data is stored inside worker process memory. But, in Web farm mode, we can share the session among all the servers using a single session store location by making it Out proc (State Server or SQL Server Mode). So, if some of the servers go down and request is transferred to the other server by the Load balancer, session data should be available for that request.
In the above diagram, you can see that we can both the IIS server sharing the same session data which is stored in out of worker process. You can read one of my previous articles “Exploring Session in ASP.NET” where I have explained how you can configure session mode for Out Process mode.
How to Manage Session in Web Garden Mode?
When we are using Web garden where request is being taken care of by different worker process, we have to make the session mode as out process session mode as described earlier. For Web Garden, we have to configure the out process within the same server but for different worker process.
While using Web garden with your application, you need make a couple of configuration settings in web.config in
<process Model>
section where you need to set certain properties like cpuMask
, RequestLimit
, webGarden
,ClientConnectCheck
, etc.Summary
When we host a web application over multiple web servers to distribute the load among them, it is called Web Farm and when one application has multiple worker processes, it is called a Web garden.
In this blog post, I have explained the very basics of what a Web Farm is and what a Web Garden is. As this blog post contains the basic information to understand the fundamentals of web farms and web garden concept, I will be posting a separate article with details configuration setting for web garden and web farm. You can read the following articles for more information:
References Web Farm and Web Garden
WEB FARM:
A hosting environment consisting of multiple web servers is said to be a Web Farm. Usually a load balancer is used to tie together the web servers, which routes incoming requests amongst the servers within the web farm.
And these incoming requests are routed in a variety of formats: One from them is to use IP affinity (also called client affinity or sticky session); it's working is to route the incoming requests to the same web server for the duration of the web application session. It has a benefit that Session state data can be maintained in-process, just as it would on a single web server hosting environment, without the complications from alternating between web servers. However, a down-side to IP affinity is in not taking full advantage of the web farm capability in fully distributing and routing all requests and sessions.
USE: The Web farms are used in enterprise environments for highly-used web applications to provide fail-safe and reliable services. Web farms offload incoming traffic by alternating between servers and by evenly distributing web application load. This increases response time, performance, and reliability. Additional web servers may be added or taken away from a web farm to increase or decrease the web application performance, as necessary for target environment.
Advantages of a Web Farm
A hosting environment consisting of multiple web servers is said to be a Web Farm. Usually a load balancer is used to tie together the web servers, which routes incoming requests amongst the servers within the web farm.
And these incoming requests are routed in a variety of formats: One from them is to use IP affinity (also called client affinity or sticky session); it's working is to route the incoming requests to the same web server for the duration of the web application session. It has a benefit that Session state data can be maintained in-process, just as it would on a single web server hosting environment, without the complications from alternating between web servers. However, a down-side to IP affinity is in not taking full advantage of the web farm capability in fully distributing and routing all requests and sessions.
USE: The Web farms are used in enterprise environments for highly-used web applications to provide fail-safe and reliable services. Web farms offload incoming traffic by alternating between servers and by evenly distributing web application load. This increases response time, performance, and reliability. Additional web servers may be added or taken away from a web farm to increase or decrease the web application performance, as necessary for target environment.
Advantages of a Web Farm
- It Provides better scalability by handling large capacity
- Due to centralized monitoring of the web sessions good web site administration.
- Optimum utilization of resources that can be shared to service clients
- It Provides redundancy by reducing failures with the help of fault tolerance techniques
- It Provides availability and better performance due to load balancing
WEB GARDEN:
Web garden is a scenario in which a single machine has multiple asp.net worker processes running simultaneously. A web garden is utilized on a multi-core web server. To achieve more robust execution and processing of the C# ASP .NET web application threads, each worker process within the application pool would execute on an individual processor. It is created within Internet Information Services (IIS) by creating an application pool, selecting the Performance tab, and under the "Web Garden" section, setting the maximum number of worker processes to a value greater than 1.
USE: Rather than using the typical hosting environments, the web gardens use more resources, and may also be slower in performance due to which there is unnecessary complexity. It has useful scenarios which may include when a non-CPU bound application needs to execute a long running request, such as an intensive computational request, long database transaction, or other long process. In both cases, a web garden could offer a solution by offloading the single worker process and distributing incoming requests amongst the workers in the application pool.
The larger gain for web gardens is not speed, but rather robustness. Due to their robustness, enabling web gardens can often be a good way to see if a C# ASP .NET web application will function correctly in a multi-server web farm environment. Often, if a web application performs well in a garden scenario, it will typically be easier to migrate to a web farm.
Advantages of Web Garden
- It increases application availability
- Less consumption of physical space with better capacity
- Optimum utilization of processes running on multiple processors located in a single server
- Finer grained partitioning of Web servers help to control the administration of web sites individually, though they reside on the same server
- With the concept of Processor affinity (binding the application to processor with the help of CPU masks), applications can be swapped out and restarted on the fly.
- IMPLEMENTATION OF WEB FARM IN .NET:
To implement a web farm in .Net, the following changes have to be made in a web.config file:
Mode = [inproc/StateServer/SqlServer]
The inproc option is to be used when there is no web farm, StateServer when performance is required while SqlServer, if reliability is needed, especially for mission critical applications.
- IMPLEMENTATION OF WEB FARM IN .NET:To implement a web garden in .Net, the following changes have to be made in a web.config file:
- webGarden=[true]
Option, false used, if web garden is not necessary. - CpuMask=8
Value for this section implies the decimal number, whose binary form represents the sequence of processors running ASP.net processes on a multiprocessor server.
- webGarden=[true]
- Difference between "Web farms" and "Web garden":
Web farms consist of two or more web servers of the same configuration and they stream the same kind of contents to minimize failures, hence web farms are used to have some redundancy. It consists of two or more web servers of the same configuration and they stream the same kind of contents. When any request is received there is switching / routing logic that decides which web server from the farm handles the request. Whereas in short we can define a model in which multiple processes run on multiple CPUs in a single server machine which is known as a web garden. Let's discuss that with the help of models:
All requests to IIS are routed to "aspnet_wp.exe" for IIS 5.0 and "w3wp.exe" for IIS 6.0. In a normal case i.e. without a web garden we have one worker process instance ("aspnet_wp.exe" / "w3wp.exe") across all requests. This one instance of worker process uses the CPU processor as directed by the operating system:
But when we enable a web garden for a web server it creates different instances of the worker process and each of these worker processes runs on different CPUs. You can see in the diagram below we have different worker process instances created which run on different CPUs.
*************************************************************************A single application pool in IIS represents a single w3wp.exe process. Having multiple w3wp.exe process within a single app pool on a single server is called a 'Web Garden' (not the same as a 'Web Farm' which is multiple servers serving up the same site). The main purpose for having multiple app pools is for application isolation by having distinct differences in Framework versions (i.e. one on .NET 2.0 and one on .NET 4.0), differing managed pipelines, differing identities run under, etc.'Application Domain' is the process of separating applications into their own process so code run in another app does not affect another, and is isolated from other applications. This happens naturally in IIS when setting up separate web sites. 1 website is not effected by code running on another website on that same server. There is no need to set up separate application pools for each website. Even a single IIS worker process will handle process isolation. You might be concerned about some things that are automatically handled for you and are not a problem because IIS takes care of it for you.Typically the biggest misunderstanding is between a Web Garden and a Web Farm. Or when to create separate application pools within IIS. If you would like to read further, check out the following (2) links:Configuring Web Gardens with IIS 6.0 (IIS 6.0):Application Domains:However, this is really pushing over to the IIS side of things more than .NET or ASP.NET, so you might want to also try re-posting to the IIS forums for some more detailed or *expert* help:Application vs. Application Domain vs. Application Pool
An application pool is a container to execute one or more applications/virtual directories, which means for a single application pool, one or more than one websites can be mapped. In a application pool, more than one worker processor can exists. if each website in application pool is mapped to individual worker process, and if any issues occurs in one worker process, only that worker process willstored and restart, the other process will still run.By default, Each and every Application pool contains a single worker process. Application which contains the multiple worker process is called “Web GardenApplication vs. AppDomainA question was asked on a forum that I frequent which I thought was worth writting a blog about.Q: What is the difference between an application and an Appdomain? I understand from my research so far that an Appdomain is a container within which ASPX runs and that Apppool is a process that starts the w3wp.exe worker process within which ASP applications run.A: That’s a good question. Here are some key differences: - An application is an IIS term, but it’s one that ASP.NET utilizes. Essentially it creates a sandbox, or a set of boundaries to separate different sites, or parts of sites, from the others.
- An AppDomain is a .NET term. (In IIS7, AppDomains play a larger role within IIS, but for the most part it’s anASP.NET term)
- An AppDomain contains InProc session state (the default session state mode). So if an AppDomain is killed/recycled, all of your session state information will be lost. (if you are using the default InProc session state)
- Applications can have multiple AppDomains in them although often times there is a one-to-one relationship between them.
- In IIS6 and greater, there is the option of creating groups, or “pools” of applications that can be bundled together or separated; however the server administer decides. These are called Application Pools. Each app pool runs under its own w3wp.exe worker process.
- In IIS, it’s easy to see an application. A new website is a separate application and any subfolder can be marked as an application. When they are, the icon beside the folder turnes into a picture of some gears. By right-clicking on the folder, you have the option of marking a folder as an application or removing it as an application, if it already is one. Also, in IIS6, in the Application Pools section, you can see all of the applications and which app pool they live under.
- ASP.NET, on the other hand, doesn’t give much visibility into AppDomains, at least not from any visual tools. This is done behind the scenes. Programmatically you can create them, tear them down or see a list of all running AppDomains.
- You can recycle an application from IIS. In IIS5, you can’t do it directly unless you recycle the entire web server, but in IIS6 and greater, you can recycle the application pool that the application lives under. It will gracefully die off and a new application will start up to replace it. Or, to word it another way, another w3wp.exe worker process will be started and then the old one will die off after it completes any currently running page requests.
- You can recycle an AppDomain in ASP.NET through the ‘touch trick’. There are a few ways to do it, but the most straight forward is to edit your web.config file in notepad and add a space to an insignificant place. Then save the file. This will cause the AppDomain to recycle. This *does not* touch the IIS application though.
- Recycling an AppDomain will come pretty close to starting ASP.NET fresh again for that particular ASP.NETapplication, so although it doesn’t recycle the apppool, it can give ASP.NET a fresh start in many situations.
- *
If you only have a single site in your app pool, then an app pool and an App-domain recycle will be quite similar. The app pool recycle will recycle the entire w3wp.exe process while the App-domain will recycle the .NET App-domain only, but since most of what that needs to be recycled lives in the App-domain, they will achieve the same thing. It's just a matter of which is easier for you to do. But, if the App-domain recycle doesn't do the trick, then try a full app pool recycle. This will depend on your situation.
If you have multiple sites in the app pool, then an App-domain is preferred because it won't touch any of the other sites or applications in the app pool and is isolated to just the single application/App-domain in the app pool.
Worker Process, Work threads, Application Pool, AppDomain, Web Site,
Worker Process
=============
A worker process is user-mode code whose role is to process requests, such as processing requests to return a static page, invoking an ISAPI extension or filter, or running a Common Gateway Interface (CGI) handler.
Worker processes use HTTP.sys to receive requests and to send responses by using HTTP. Worker processes also run application code, such as ASP.NET applications and XML Web services. You can configure IIS to run multiple worker processes that serve different application pools concurrently. This design separates applications by process boundaries and helps achieve maximum Web server reliability.
The w3wp.exe worker process isn’t ASP.NET specific, and is used to handle any kind of requests. The specific worker process then decides which ISAPI modules to load according to the type of resources it needs to serve.
Application Pool
=============
An Application Pool can contain one or more applications and allows us to configure a level of isolation between different Web applications
Web Application VS Worker Process
=============
Incoming requests are forwarded from the application pool queue to the right worker process via a module loaded in
IIS
6 calledWeb Administration Service (WAS).
This module is responsible for reading worker process – web application bindings from the
IIS
metabase and forwarding the request to the right worker process.
Aach application pool runs in its own worker process, errors in one application pool will not affect the applications running in other application pools.
AppDomain
=============
AppDomain can be considered as a Lightweight process which is both a container and boundary.
The .NET runtime uses an AppDomain as a container for code and data, just like the operating system uses a process as a container for code and data.
As the operating system uses a process to isolate misbehaving code, the .NET runtime uses an AppDomain to isolate code inside of a secure boundary.
The CLR isolates each application domain from all other application domains and prevents the configuration, security, or stability of a running .NET applications
from affecting other applications.
from affecting other applications.
An AppDomain can be destroyed without effecting the other Appdomains in the process.
Mulitple Appdomains can exist in Win32 process.
Win32 processes provide isolation by having distinct memory addresses. The .Net runtime enforces AppDomain isolation by keeping control over the use of memory. All memory in the App domain is managed by the run time so the runtime can ensure that AppDomains Do not access each others memory.
ApplicationPool VS AppDomain
==============
Appdomain is a container within which ASPX runs.
AppPool is a process that starts the w3wp.exe worker process within which ASP applications run.
Threading in ASP.NET Pipeline
==============
ASP.NET creates a distinct AppDomain for each application housed in its worker process, but what has not yet been mentioned is how threads are allocated and dispatched to service those requests.
To begin with, ASP.NET uses the process-wide CLR thread pool to service requests. The size of this pool is configurable in theprocessModel element of machine.config, and is set to a default of 25 worker threads and 25 I/O threads.
In IIS 6.0, there is no dedicated worker process for ASP.NET since it is integrated into the process model exposed by IIS 6.0, which lets you designate whether a particular virtual directory lives in a distinct worker process (w3wp.exe) or in a worker process shared by other virtual directories. In this scenario, ASP.NET services requests on worker threads drawn from the process-wide CLR thread pool.
For each request that comes in, a new instance of the appropriate HttpApplication-derived class is created, as are the associated modules for that application. To avoid reallocating applications and modules too often, each AppDomain maintains a pool of applications and modules. The maximum size of the application pool is the same as the size of the thread pool, so by default, up to 25 requests per worker process can be processed concurrently, each with its own application and module set.
Worker Processes (IIS 6.0)
ASP.NET Internals – IIS and the Process Model
AppDomain concept in ASP.Net
Application vs. AppDomain
References http://blogs.msdn.com/b/tess/archive/2008/08/19/questions-on-application-domains-application-pools-and-unhandled-exceptions.aspx
Questions on application domains, application pools and unhandled exceptions
From what i read, my understanding is that a website has an app pool associated with it. This app pool leads to the creation of a w3wp.exe process. Inside this app pool/w3wp.exe process, an application domain is created.Tess: This is correct. In IIS you can create different application pools that have different healthmonitoring settings, run under different user contexts etc. and when you create a web site you choose which application pool it will run under. Each application pool will then spawn it's own w3wp.exe process (or multiple if you have web gardening turned on) when the first request comes in.The process (w3wp.exe) contains multiple application domains, typically a shared domain, a default domain, a system domain and one application domain per web application (virtual directory marked as application).
An application domain recycling is different than an application pool/proccess (w3wp.exe) recycling, right?Tess: Yes. An appdomain can recycle without recycling the process. Simplified an appdomain is a process within the process with it's own statics (cache/session etc.), but all appdomains in the process share the same GC, threadpool, finalizer thread etc.An appdomain recycle is triggered by a few things like web.config changes, directory name changes etc. You can find most of the appdomain recycle reasons in this post. When an appdomain recycles the process stays up, however when the process goes down the appdomains in the process will of course also go down.
Can unhandled exceptions cause the application domain to recycle ?Tess: It depends on what you mean by unhandled exceptions. In ASP.NET there is the concept of unhandled exceptions that are caught by the global error handler or page error handler. i.e. the ones that give you the yellow exception output when you view a page. They will be listing as unhandled exceptions in eventvwr, but in reality they are handled by the page error handler, and they will neither crash the appdomain or the application/w3wp.exe process.If on the other hand you have an exception that occurrs on a non-request thread, such as a timer thread or the finalizer thread and you dont have a try/catch block around it, it is really an unhandled exception, and such unhandled exceptions will cause the process to go down and take all the appdomains with it.
What exactly happens inside the application domain when an unhandled exception occurs ?Tess: The process shuts down, and the appdomains are unloaded so anything inside it is gone including session vars etc.
Is it possible to have IIS run each User Session in a separate App Domain. If Yes, Could you please let me settings in the config file that affect this.Is there a setting in any of the config files that will prevent the application domain from recycling ?Tess: There is a legacyUnhandledExceptionPolicy see this post for more info, that will cause a 2.0 process to behave as 1.1, i.e. not shut down the process and instead just quit processing the current thread of execution. I would seriously advice against using it though other than as a temporary measure while you troubleshoot the unhandled exception as it may cause your process to behave erratically, since you don't really know what has processed and what hasn't. For example if an exception occurrs during finalization you will not know if you have released all the native handles you were supposed to or not.
I am assuming that you dont mean one app domain per user, as this would mean that you would have a lot of appdomains:) so I am not really sure that I am understanding your question...
If the question is about having each app domain/website in a separate process, then you can do so by assigning them to different application pools.
If the question is about how you can save session state even over app domain restarts, the answer is to use out of process session state, like asp.net state server or sql server session state.
If the question is about having each app domain/website in a separate process, then you can do so by assigning them to different application pools.
If the question is about how you can save session state even over app domain restarts, the answer is to use out of process session state, like asp.net state server or sql server session state.
An application pool can contain many asp.net applications, each with its own appdomain. In other words, a w3wp.exe process will serve an application pool with one or more asp.net applications/appdomains.
If you're reading this article, you've no doubt created an ASP.NET Web page with various Web controls. Typically one creates Web controls statically, by explicitly specifying them in the HTML section of an ASP.NET Web page. For example, one might create an ASP.NET Web page that contains an HTML message and a TextBox, which would contain the following code:
http://weblogs.asp.net/owscott/archive/2007/09/02/application-vs-appdomain.aspx
Does every ASP.NET Web Application has a Single Application Domain?
An Application Domain is the logical and physical boundary created around every .NET application by the Common Language Runtime (CLR).
- One web application runs in a single Application Domain but may communicate via web/remote services with applications in other domains.
- The CLR may allow multiple .NET applications to be run in a single Application Domain, so it means that an Application Domain may be shared by different applications which can in that case communicate with each other "directly".
Most times though, the relationship between a web application and an application domain is one-to-one.
You may read the following article (very short, but nicely written) which explains what are Application Domains and how they may be useful: http://www.beansoftware.com/NET-Tutorials/Application-Domain.aspx.
Also, on his blog, Scott Forsyth explains the differences between an application (IIS term), a web application (ASP.NET term) and application domains.
*********************************************************************************
References ASP.NET Application and Page Life Cycle
Introduction
In this article, we will try to understand what the different events are which take place right from the time the user sends a request, until the time the request is rendered on the browser. So we will first try to understand the two broader steps of an ASP.NET request and then we will move into different events emitted from ‘
HttpHandler
’, ‘HttpModule
’ and ASP.NET page object. As we move in this event journey, we will try to understand what kind of logic should go in each and every one of these events.
This is a small Ebook for all my .NET friends which covers topics like WCF, WPF, WWF, Ajax, Core .NET, SQL, etc. You can download the same from here or else you can catch me on my daily free training here.
The Two Step Process
From 30,000 feet level, ASP.NET request processing is a 2 step process as shown below. User sends a request to the IIS:
- ASP.NET creates an environment which can process the request. In other words, it creates the application object, request, response and context objects to process the request.
- Once the environment is created, the request is processed through a series of events which is processed by using modules, handlers and page objects. To keep it short, let's name this step as MHPM (Module, handler, page and Module event), we will come to details later.
In the coming sections, we will understand both these main steps in more detail.
Creation of ASP.NET Environment
Step 1: The user sends a request to IIS. IIS first checks which ISAPI extension can serve this request. Depending on file extension the request is processed. For instance, if the page is an ‘.ASPX page’, then it will be passed to ‘aspnet_isapi.dll’ for processing.
Step 2: If this is the first request to the website, then a class called as ‘
Step 3: The newly created application domain creates hosting environment, i.e. the ‘
Step 4: Once all the core ASP.NET objects are created, ‘
Note: The first time an ASP.NET page is attached to an application, a new instance of ‘
Step 5: The
Step 6:
Note: For more details, read this.
Step 2: If this is the first request to the website, then a class called as ‘
ApplicationManager
’ creates an application domain where the website can run. As we all know, the application domain creates isolation between two web applications hosted on the same IIS. So in case there is an issue in one app domain, it does not affect the other app domain.Step 3: The newly created application domain creates hosting environment, i.e. the ‘
HttpRuntime
’ object. Once the hosting environment is created, the necessary core ASP.NET objects like ‘HttpContext
’ , ‘HttpRequest
’ and ‘HttpResponse
’ objects are created.Step 4: Once all the core ASP.NET objects are created, ‘
HttpApplication
’ object is created to serve the request. In case you have a ‘global.asax’ file in your system, then the object of the ‘global.asax’ file will be created. Please noteglobal.asax file inherits from ‘HttpApplication
’ class.Note: The first time an ASP.NET page is attached to an application, a new instance of ‘
HttpApplication
’ is created. Said and done to maximize performance, HttpApplication
instances might be reused for multiple requests.Step 5: The
HttpApplication
object is then assigned to the core ASP.NET objects to process the page.Step 6:
HttpApplication
then starts processing the request by HTTP module events, handlers and page events. It fires the MHPM event for request processing.Note: For more details, read this.
The below image explains how the internal object model looks like for an ASP.NET request. At the top level is the ASP.NET runtime which creates an ‘
Appdomain
’ which in turn has ‘HttpRuntime
’ with ‘request’, ‘response’ and ‘context’ objects.Process Request using MHPM Events Fired
Once ‘
Before we move ahead, let's understand what are ‘
HttpApplication
’ is created, it starts processing requests. It goes through 3 different sections ‘HttpModule
’ , ‘Page
’ and ‘HttpHandler
’. As it moves through these sections, it invokes different events which the developer can extend and add customize logic to the same.Before we move ahead, let's understand what are ‘
HttpModule
’ and ‘HttpHandlers
’. They help us to inject custom logic before and after the ASP.NET page is processed. The main differences between both of them are:- If you want to inject logic based in file extensions like ‘.ASPX’, ‘.HTML’, then you use ‘
HttpHandler
’. In other words, ‘HttpHandler
’ is an extension based processor. - If you want to inject logic in the events of ASP.NET pipleline, then you use ‘
HttpModule
’. ASP.NET. In other words, ‘HttpModule
’ is an event based processor.
You can read more about the differences from here.
Below is the logical flow of how the request is processed. There are 4 important steps MHPM as explained below:
Step 1(M: HttpModule): Client request processing starts. Before the ASP.NET engine goes and creates the ASP.NET
Step 2 (H: ‘HttpHandler’): Once the above 6 events are fired, ASP.NET engine will invoke
Step 3 (P: ASP.NET page): Once the
Step4 (M: HttpModule): Once the page object is executed and unloaded from memory,
The below figure shows the same in a pictorial format.
Below is the logical flow of how the request is processed. There are 4 important steps MHPM as explained below:
Step 1(M: HttpModule): Client request processing starts. Before the ASP.NET engine goes and creates the ASP.NET
HttpModule
emits events which can be used to inject customized logic. There are 6 important events which you can utilize before your page object is created BeginRequest
, AuthenticateRequest
, AuthorizeRequest
,ResolveRequestCache
, AcquireRequestState
and PreRequestHandlerExecute
.Step 2 (H: ‘HttpHandler’): Once the above 6 events are fired, ASP.NET engine will invoke
ProcessRequest
event if you have implemented HttpHandler
in your project.Step 3 (P: ASP.NET page): Once the
HttpHandler
logic executes, the ASP.NET page object is created. While the ASP.NET page object is created, many events are fired which can help us to write our custom logic inside those page events. There are 6 important events which provides us placeholder to write logic inside ASP.NET pages Init
, Load
,validate
, event
, render
and unload
. You can remember the word SILVER
to remember the events S – Start (does not signify anything as such just forms the word) , I – (Init) , L (Load) , V (Validate), E (Event) and R (Render).Step4 (M: HttpModule): Once the page object is executed and unloaded from memory,
HttpModule
provides post page execution events which can be used to inject custom post-processing logic. There are 4 important post-processing events PostRequestHandlerExecute
, ReleaserequestState
, UpdateRequestCache
andEndRequest
.The below figure shows the same in a pictorial format.
In What Event Should We Do What?
The million dollar question is in which events should we do what? Below is the table which shows in which event what kind of logic or code can go.
Section | Event | Description |
HttpModule | BeginRequest | This event signals a new request; it is guaranteed to be raised on each request. |
HttpModule | AuthenticateRequest | This event signals that ASP.NET runtime is ready to authenticate the user. Any authentication code can be injected here. |
HttpModule | AuthorizeRequest | This event signals that ASP.NET runtime is ready to authorize the user. Any authorization code can be injected here. |
HttpModule | ResolveRequestCache | In ASP.NET, we normally use outputcache directive to do caching. In this event, ASP.NET runtime determines if the page can be served from the cache rather than loading the patch from scratch. Any caching specific activity can be injected here. |
HttpModule | AcquireRequestState | This event signals that ASP.NET runtime is ready to acquire session variables. Any processing you would like to do on session variables. |
HttpModule | PreRequestHandlerExecute | This event is raised just prior to handling control to the HttpHandler . Before you want the control to be handed over to the handler any pre-processing you would like to do. |
HttpHandler | ProcessRequest | Httphandler logic is executed. In this section, we will write logic which needs to be executed as per page extensions. |
Page | Init | This event happens in the ASP.NET page and can be used for:
In this section, we do not have access to viewstate, postedvalues and neither the controls are initialized.
|
Page | Load | In this section, the ASP.NET controls are fully loaded and you write UI manipulation logic or any other logic over here. |
Page | Validate | If you have valuators on your page, you would like to check the same here. |
Render | It’s now time to send the output to the browser. If you would like to make some changes to the final HTML which is going out to the browser, you can enter your HTML logic here. | |
Page | Unload | Page object is unloaded from the memory. |
HttpModule | PostRequestHandlerExecute | Any logic you would like to inject after the handlers are executed. |
HttpModule | ReleaserequestState | If you would like to save update some state variables like session variables. |
HttpModule | UpdateRequestCache | Before you end, if you want to update your cache. |
HttpModule | EndRequest | This is the last stage before your output is sent to the client browser. |
A Sample Code for Demonstration
With this article, we have attached a sample code which shows how the events actually fire. In this code, we have created a ‘
Below is the class for ‘
HttpModule
’ and ‘Httphandler
’ in this project and we have displayed a simple response write in all events, below is how the output looks like.Below is the class for ‘
HttpModule
’ which tracks all events and adds it to a global collection.public class clsHttpModule : IHttpModule
{
......
void OnUpdateRequestCache(object sender, EventArgs a)
{
objArrayList.Add("httpModule:OnUpdateRequestCache");
}
void OnReleaseRequestState(object sender, EventArgs a)
{
objArrayList.Add("httpModule:OnReleaseRequestState");
}
void OnPostRequestHandlerExecute(object sender, EventArgs a)
{
objArrayList.Add("httpModule:OnPostRequestHandlerExecute");
}
void OnPreRequestHandlerExecute(object sender, EventArgs a)
{
objArrayList.Add("httpModule:OnPreRequestHandlerExecute");
}
void OnAcquireRequestState(object sender, EventArgs a)
{
objArrayList.Add("httpModule:OnAcquireRequestState");
}
void OnResolveRequestCache(object sender, EventArgs a)
{
objArrayList.Add("httpModule:OnResolveRequestCache");
}
void OnAuthorization(object sender, EventArgs a)
{
objArrayList.Add("httpModule:OnAuthorization");
}
void OnAuthentication(object sender, EventArgs a)
{
objArrayList.Add("httpModule:AuthenticateRequest");
}
void OnBeginrequest(object sender, EventArgs a)
{
objArrayList.Add("httpModule:BeginRequest");
}
void OnEndRequest(object sender, EventArgs a)
{
objArrayList.Add("httpModule:EndRequest");
objArrayList.Add("<hr>");
foreach (string str in objArrayList)
{
httpApp.Context.Response.Write(str + "<br>") ;
}
}
}
Below is the code snippet for ‘
HttpHandler
’ which tracks ‘ProcessRequest
’ event.public class clsHttpHandler : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
clsHttpModule.objArrayList.Add("HttpHandler:ProcessRequest");
context.Response.Redirect("Default.aspx");
}
}
We are also tracking all the events from the ASP.NET page.
public partial class _Default : System.Web.UI.Page
{
protected void Page_init(object sender, EventArgs e)
{
clsHttpModule.objArrayList.Add("Page:Init");
}
protected void Page_Load(object sender, EventArgs e)
{
clsHttpModule.objArrayList.Add("Page:Load");
}
public override void Validate()
{
clsHttpModule.objArrayList.Add("Page:Validate");
}
protected void Button1_Click(object sender, EventArgs e)
{
clsHttpModule.objArrayList.Add("Page:Event");
}
protected override void Render(HtmlTextWriter output)
{
clsHttpModule.objArrayList.Add("Page:Render");
base.Render(output);
}
protected void Page_Unload(object sender, EventArgs e)
{
clsHttpModule.objArrayList.Add("Page:UnLoad");
}}
Below is how the display looks like with all events as per the sequence discussed in the previous section.
Zooming ASP.NET Page Events
In the above section, we have seen the overall flow of events for an ASP.NET page request. One of the most important sections is the ASP.NET page, we have not discussed the same in detail. So let’s take some luxury to describe the ASP.NET page events in more detail in this section.
Any ASP.NET page has 2 parts, one is the page which is displayed on the browser which has HTML tags, hidden values in form of viewstate and data on the HTML inputs. When the page is posted, these HTML tags are created in to ASP.NET controls with viewstate and form data tied up together on the server. Once you get these full server controls on the behind code, you can execute and write your own login on the same and render the page back to the browser.
Now between these HTML controls coming live on the server as ASP.NET controls, the ASP.NET page emits out lot of events which can be consumed to inject logic. Depending on what task / logic you want to perform, we need to put this logic appropriately in those events.
Note: Most of the developers directly use the
Note: Most of the developers directly use the
page_load
method for everything, which is not a good thought. So it’s either populating the controls, setting view state, applying themes, etc., everything happens on the page load. So if we can put logic in proper events as per the nature of the logic, that would really make your code clean.Seq | Events | Controls Initialized | View state Available | Form data Available | What Logic can be written here? |
1 | Init | No | No | No |
Note: You can access form data etc. by using ASP.NET request objects but not by Server controls.Creating controls dynamically, in case you have controls to be created on runtime. Any setting
initialization.Master pages and them settings. In this section, we do not have access to viewstate , posted values and neither the controls are initialized. |
2 | Load view state | Not guaranteed | Yes | Not guaranteed | You can access view state and any synch logic where you want viewstate to be pushed to behind code variables can be done here. |
3 | PostBackdata | Not guaranteed | Yes | Yes | You can access form data. Any logic where you want the form data to be pushed to behind code variables can be done here. |
4 | Load | Yes | Yes | Yes | This is the place where you will put any logic you want to operate on the controls. Like flourishing a combobox from the database, sorting data on a grid, etc. In this event, we get access to all controls, viewstate and their posted values. |
5 | Validate | Yes | Yes | Yes | If your page has validators or you want to execute validation for your page, this is the right place to the same. |
6 | Event | Yes | Yes | Yes | If this is a post back by a button click or a dropdown change, then the relative events will be fired. Any kind of logic which is related to that event can be executed here. |
7 | Pre-render | Yes | Yes | Yes | If you want to make final changes to the UI objects like changing tree structure or property values, before these controls are saved in to view state. |
8 | Save view state | Yes | Yes | Yes | Once all changes to server controls are done, this event can be an opportunity to save control data in to view state. |
9 | Render | Yes | Yes | Yes | If you want to add some custom HTML to the output this is the place you can. |
10 | Unload | Yes | Yes | Yes | Any kind of clean up you would like to do here. |
*********************************************************
Where we can add Dynamic control in OUR Page.
1) Reference Dynamic Controls in ASP.NET
For More Information on Working with Dynamically Created Controls... |
---|
After you have read this article, consider reading the following articles for a more in-depth look at working with dynamically created controls in an ASP.NET Web page:
|
Introduction
If you're reading this article, you've no doubt created an ASP.NET Web page with various Web controls. Typically one creates Web controls statically, by explicitly specifying them in the HTML section of an ASP.NET Web page. For example, one might create an ASP.NET Web page that contains an HTML message and a TextBox, which would contain the following code:
What is your name? |
The code above specifies two Web controls:
- A LiteralControl (the "What is your name" HTML gets converted into a LiteralControl when the ASP.NET Web page is requested from a browser for the first time), and
- A TextBox Web control
The above code explicitly specifies the controls that should appear on the ASP.NET Web page (granted, the HTML being converted into a LiteralControl is a bit implicit). Did you know that you can dynamically add controls to an ASP.NET Web page? In this article we'll look at how to create controls, add them to an ASP.NET page dynamically, and, finally, how to enumerate through the controls on a page.
The Page
Class
When an ASP.NET Web page is first visited by a user it is converted into a class that inherits the
Page
class. If you use code-behind you're already aware of this - your code-behind class has to explicitly inherit the Page
class. By inheriting the Page
class, the ASP.NET Web page has access to the various useful properties, methods, and events of the Page
class.
For example, the
Page_Load
event handler is triggered when the Page
class's Load
event is fired. Similarly, you've no doubt used a number of the Page
class's properties, such as IsPostBack
, IsValid
, Request
, Response
, Session
, Cache
, etc.
The
Page
class is derived (indirectly) from the Controls
class, which has a property called Controls
, which is a collection representing the controls contained by the Page
class, which is simply the controls on the ASP.NET Web page. Hence, to add controls to an ASP.NET Web page we will add them to this collection.
If the above three paragraphs have utterly confused you, don't worry! A couple examples should help clear things up.
Adding a Dynamic Control to an ASP.NET Web Page
In order to add a control to an ASP.NET Web page we first need to create an instance of the control we wish to add. For our example, we'll add a Label control to the Web page. Hence, we first need to create the Label control, which we can do in our
Page_Load
event handler like so:
|
Pretty simple, eh? Next, we need to set the various Label properties we're interested in. For this example, let's set the
Text
and the Font.Bold
property:
|
Finally, we need to add this control to the Web page. Not surprisingly, the
Controls
property has an Add
method, which is demonstrated in the following code:
|
Take a moment to check out the live demo. Note that the control is added to the end of the Web page. This is because by the time the
Page_Load
handler has fired the other controls on the page (the LiteralControl that comprises the HTML markup) have already been added. The Add
method adds the Label control to the end of the Controls
collection.
While the
Controls
collection contains an AddAt
method, allowing the developer to specify specifically where in the Controls
collection the new control should be added, if we want the control to appear in a fixed location within the Web page (say, between the two <HR>
s (horizontal lines) in the live demo), we have to somehow break up the HTML markup so that it is comprised of two LiteralControls instead of one, so we can place our Label control in the correct spot (as opposed to the very end of the HTML content or the very beginning).
To accomplish this, we need to use a PlaceHolder Web control, specifying explicitly where in the ASP.NET Web page it belongs. For example, imagine we have the following HTML in our Web page:
|
and we want to add our Label control to the Web page such that it appears between the two
<HR>
tags. To accomplish this, we first add a PlaceHolder control specifically where we want the Label control to appear:
|
To complete this exercise, in the
Page_Load
event handler we replace Controls.Add(lblMessage)
with LabelPlaceHolder.Controls.Add(lblMessage)
. This adds the Label control to the PlaceHolder's Controls
collection. The reason the PlaceHolder control has a Controls
property is because it is derived from the Control
class - in fact, all ASP.NET controls are. As aforementioned, the Control
class has a Controls
property, which is a collection of all of the children controls in the control at hand. Hence, we are adding the Label control lblMessage
to the PlaceHolder control. (See the live demo for the complete source code...)
In Part 2 we'll look at how to enumerate through the controls in an ASP.NET Web page. Also, we'll look at some real-world applications for dynamically adding controls!
Part 2:-
Dynamic Controls in ASP.NET, Part 2
In Part 1 we examined how to add controls to an ASP.NET Web page, and how to specify the precise location of the control using a PlaceHolder control. In this part we'll examine how to enumerate through the controls on a page and some real-world uses of dynamically adding controls to an ASP.NET Web page.
Enumerating through the Controls on an ASP.NET Web Page
Since the
Controls
property is a collection that supports the IEnumerable
interface, you can simple iterate through the collection using a For Each ... Next
loop in VB.NET or aforeach
loop in C#. (For the remainder of this article I will be using C# code samples.) To loop through the controls in the Page
, simply use the following code:
|
Take a moment to view the live demo. You'll note that the controls listed to be in the page are:
- LiteralControl
- Label
- LiteralControl
- HtmlForm
- ResourceBasedLiteralControl
You may be wondering where the TextBox control is, and why it isn't listed on the live demo. This is because the TextBox is a child control of the Web Form control (the HtmlForm control). In order to view all of the controls on the Web page, we must iterate through the
Controls
collection, and at each control, check to see if the control has any children controls; if it does, we need to iterate recursively through its children controls, applying the same logic. (In order to determine if a control has children controls, we can simply check to see if the control's Controls
collection's Count
property is greater than 0.)What is the ResourceBasedLiteralControl? |
---|
I found myself wondering this very thing when I first viewed the live demo. There's no mention of a ResourceBasedLiteralControl in the docs and a search on Google revealed nothing helpful. I turned to the ASP.NET Forums and got an answer from DmitryR, an ASP.NET Team member. DmitryR said:[The choice of using a ResourceBasedLiteralControl vs. a LieralControl is] based on size, it is a perf optimization -- static HTML of size over 1K(?) ends up as a utf-8 encoded resource, saving the conversion cost and string size. |
The following code example illustrates how to recursively iterate through all of the controls on the page. It utilizes recursion - if you are unfamiliar or rusty with recursion, I'd recommend that you read Recursion - Why It's Cool first.
|
Ok, this is Neat, but is it Useful?
Hopefully you've found the material that we've covered thus far to be interesting, if nothing else. But, if you're like me, when you first hear about this topic you may find yourself thinking, "Well, yeah, this is neat and all, but when in the world would I use it?" Personally I have yet to use it in a real-world application, but can envision a number of potential uses.
Imagine that you want to have surveys or questionnaires on your Web site. Ideally each survey would have a database record, and a set of rows indicating what the questions were and what types of questions they were. For example, you might have a survey that had three questions: one a Yes/No, one a write-in, and one being a selection from five potential options. (In this case you'd need a couple of DropDownLists and a TextBox.) In any event, rather than have to create a new ASP.NET Web page for each potential survey, you could create one generic page that accepts a survey ID through the querystring, and then dynamically adds the appropriate questions and controls accompanying the questions. See? A useful, real-world application of the material we just covered! ;-)
Conclusion
In this article we examined how to dynamically add controls to an ASP.NET Web page. Furthermore, we looked at how to iterate through the
Controls
collection as well as how to recursively iterate through the entire set of controls on a page. For more information on working with dynamically added controls, be sure to read: Working with Dynamically Created Controls.
Happy Programming!
Working with Dynamically Created Controls
Refernce Working with Dynamically Created Controls
Introduction
In last week's article, Dynamic Controls in ASP.NET, I examined how to use the
Controls
collection to dynamically add a control to an ASP.NET Web page. Additionally, I illustrated how to enumerate through the Controls
collection, both via a simple For Each ... Next
loop and using recursion to completely enumerate through all of the controls on a page, as well their children, their children's children, and so on.
Since publishing that article there have been a number of readers who have asked roughly the same question: when enumerating through the list of controls how can I set some of the controls properties. Put another way, imagine that you wanted to find all TextBox Web controls and set their
Text
property to some value, or perhaps you wanted to find the first DropDownList control and determine the SelectedItem
.
Before beginning this article, make sure you have closely read Dynamic Controls in ASP.NET and understand the concepts presented in that article.
Finding a Particular Control by its Type
The
Control
class contains a GetType()
method that returns a Type
class instance. The ToString()
method of the Type
class returns a string providing an English description of the type. For example, if in our Page_Load
event handler we had:Dim txtName as New TextBox() |
we will get the output:
System.Web.UI.WebControls.TextBox
. Hence, if we want to search for controls of a particular type, we can loop through all of our controls and check to see if the current control we're examining has the type we're interested in. If it does, then we can take whatever action we'd like to.
As an example, let's create an ASP.NET Web page that will dynamically create a user-specified number of TextBoxes, and then loop through all the controls, finding all of the TextBoxes. The HTML portion of our page might look like:
|
Essentially what we have here is a Web form with a TextBox asking the user to enter a value for the number of TextBoxes that should be created dynamically. A RangeValidator is included to ensure that the user enters an integer value between 1 and 10. A button then follows, which, when clicked, will cause the form to be posted back and the
CreateTextBoxes
event handler to fire. Finally, the TextBoxesHere
PlaceHolder is the location where we'll place the dynamically created TextBoxes.
The source code needs to include a
CreateTextBoxes
event handler, which will create the specified number of TextBoxes. This is fairly simple to implement, as we saw in theDynamic Controls in ASP.NET article.
|
In the first line, we read the number the user-entered number into a variable
n
. We then loop from 0 up to n
, creating a TextBox at each iteration, "attaching" the new TextBox to the TextBoxesHere
PlaceHolder. Finally, we call IterateThroughChildren
. This is the function we examined in Dynamic Controls in ASP.NET, which recursively iterates through all of the controls on the page. It is within this function that we will be checking to see if the current control we're enumerating through is a TextBox.
|
The
IterateThroughChildren
steps through each control in the ASP.NET page. In our loop through the parent
control's Controls
collection, we check to see if the control is a TextBox by checking the GetType().ToString()
value.Another Way to Determine the Control's Type... |
---|
The code above gets the Control c 's type using GetType() and comparing its string value to "System.Web.UI.WebControls.TextBox". A better approach would be to use the is operator (or TypeOf , in Visual Basic). That is, we could replacec.GetType().ToString().Equals("System.Web.UI.WebControls.TextBox") with c is TextBox (or, in VB, TypeOf c Is TextBox ).Thanks to Jarom K. and other alert 4Guys readers who wrote in to suggest this enhancement. |
We also check to see if the
ID
property is null
or not. The ID
is a property of the Control
class, and, if specified, contains a string value. For example, the TextBox where the user was asked to enter how many dynamic TextBoxes they wanted to create had an ID
of txtTBCount
. If no ID is explicitly specified (as with the dynamically created TextBoxes, seeing as we didn't set the ID
property), the control's ID
property will be null
.
The reason we check if the
ID
is null
is because we only want to fiddle with the dynamically created TextBoxes - that is, we don't want to alter the TextBox txtTBCount
. Hence, we'll only enter the if
statement part if both the control's type is that of a TextBox and the TextBox does not have an ID
specified. The only controls for which these two conditions will hold true are those dynamically created TextBoxes.
At this point we know when we're dealing with a particular type of control, but once we find such a control, how do we tweak its properties? We'll look at how to accomplish this task in Part 2.
Working with Dynamically Created Controls, Part 2
In Part 1 we looked at how to find a control of a particular type by enumerating through the
Controls
collection. In this part we'll look at how to set and read the property values of the control we're interested in.Setting a Control's Properties
At this point we know when we're dealing with a particular type of control, but once we find such a control, how do we tweak its properties? That is, in the
if
statement above, once I've found a TextBox I may wish to set its Text
property, or its Columns
property. How can we do this?
Intuitively, you may say, well, why not set the TextBox's
Columns
property like so:c.Columns = 10; |
While this may seem the intuitive approach, unfortunately it is an incorrect one. The reason being is that
c
is a variable of type Control
- the Control
class does not contain a property called Columns
. What we must do is cast the control c
into a TextBox, and then we can set the Columns
property like we normally would.
In C# to cast a variable, simple place the type you wish to cast the variable to (in parenthesis) immediately before the variable, like:
// Cast c to a TextBox |
To both cast
c
to a TextBox and set the Columns
property in one line of code we can do:((TextBox) c).Columns = 10; |
(If you are using VB.NET you will need to use the
CType
function like so: CType(c, TextBox).Columns = 10
)
Hence, to set the
Text
and Columns
properties of each of the dynamically created TextBoxes we would need to adjust our IterateThroughChildren
like so:
|
Notice here we are setting the
Text
property to a string that contains an integer counting variable (count
). This variable is incremented each time we find a new TextBox. Hence, the n
dynamic TextBoxes will have the text messages TextBox 1
, TextBox 2
, and so on, up to TextBox n
. We also set the Columns
property to a value of 10.Conclusion
In this article we examined how to find a control in the
Controls
collection by its type, and then, once found, how to set some of its properties. This material covered in this article is a natural extension from the material in last week's article, Dynamic Controls in ASP.NET. In cases where you are dynamically adding controls, there is likely the need to find those controls and set (or read) various properties. Hopefully the techniques discussed in this article will help you in your future endeavors!
Happy Programming!
Reference
Dynamic Web Controls, Postbacks, and View Statehttp://aspnet.4guysfromrolla.com/articles/092904-1.aspx
Introduction
As I've written about in two previous articles here on 4Guys - Dynamic Controls in ASP.NET and Working with Dynamically Created Controls - ASP.NET makes it easy to programmatically add Web controls. Armed with this capability, you can offer a truly customized experience for your users. For example, your site might load particular navigational elements as user controls, based upon the logged on user's preferences. Or when collecting information from your users, you might display different input fields prompting for different data based on the user's age, location, gender, and so on.
One of the main challenges with working with dynamically added controls is that these controls must be programmatically added on each postback. That is, you can't just load these controls on the first page load, and then not reload them on subsequent postbacks. Failure to explicitly add the controls on each postback will cause the controls to literally disappear on postbacks. To further complicate things, the point in the page's lifecycle when dynamic controls are added is important if you want to maintain changed values across postback. For example, imagine you had a Web page that displayed a series of input form fields based on the user visiting the page. The idea here would be to allow the visitor enter some values into these custom input form fields, and then submit the form, having the data saved. If the dynamic Web controls are not added at the correct time in the page's lifecycle, the values entered by the visitor will be lost on postback.
In this article we will examine how to add dynamic Web controls to a page in such a manner that you will not need to worry about losing form field values on postback. Specifically, we'll look at how to create a page whose form fields are dependent upon the user visiting the page, and how this user can enter their data into these form fields and have it saved on form submission. Since this article builds upon concepts discussed earlier, please make sure you have read both Dynamic Controls in ASP.NET andWorking with Dynamically Created Controls before tackling this article.
Understanding the Page Lifecycle
As page developers, we often think about ASP.NET Web pages consisting of two distinct portions: an HTML portion and a code-behind class. However, behind the scenes, when an ASP.NET Web page is requested for the first time (or for the first time after the page has changed) the HTML portion is autogenerated into a class from which the code-behind class is derived from. In essence, an ASP.NET Web page is represented, then, as a single class. Whenever an ASP.NET page is requested from the Web server, the corresponding page's class is instantiated and its
ProcessRequest()
method is invoked. This method kicks off the page lifecycle. The page lifecycle is a sequence of stages that the ASP.NET page's corresponding class progresses through. The end goal of the lifecycle is to generate the page's appropriate markup, which is then sent back to the requesting browser.
The page lifecycle is composed of a number of steps, the following ones being the ones of interest for this article:
- Instantiation,
- Initialization,
- Load View State,
- Load,
- Save View State
HtmlForm
(the <form runat="server">
), numerous LiteralControls
(static HTML content in the page's HTML portion is represented as LiteralControls
in the hierarchy), and the Web controls you added to the page's HTML portion. The control hierarchy is created by the autogenerated class. Since every time an ASP.NET page is requested, be it the first time or on a subsequent postback, the page class is reinstantiated and reiterates its lifecycle, each request causes the control hierarchy to be rebuilt from scratch in the Instantiation stage.
As mentioned earlier, the ASP.NET page's autogenerated class's responsibility is to create the control hierarchy from the HTML portion. To understand this process, let's look at a concrete example. This example - the complete text and images below - is taken from another article of mine, Understanding ASP.NET View State, published on MSDN Online in May 2004.
Imagine you have an ASP.NET Web page with the following HTML portion:The page's control hierarchy created in the Instantiation stage reflects the markup in the page's HTML portion. When we add controls dynamically to an ASP.NET Web page, we are essentially building onto this control hierarchy, but at a later stage in the page lifecycle.When this page is first visited, a class will be autogenerated that contains code to programmatically build up the control hierarchy. The control hierarchy for this example can be seen in the figure below.
<html> <body> <h1>Welcome to my Homepage!</h1> <form runat="server"> What is your name? <asp:TextBox runat="server" ID="txtName"></asp:TextBox> <br />What is your gender? <asp:DropDownList runat="server" ID="ddlGender"> <asp:ListItem Select="True" Value="M">Male</asp:ListItem> <asp:ListItem Value="F">Female</asp:ListItem> <asp:ListItem Value="U">Undecided</asp:ListItem> </asp:DropDownList> <br /> <asp:Button runat="server" Text="Submit!"></asp:Button> </form> </body> </html>
This control hierarchy is then converted to code that is similar to the following:
The C# source code above is not the precise code that is autogenerated by the ASP.NET engine. Rather, it's a cleaner and easier to read version of the autogenerated code. To see the full autogenerated code - which won't win any points for readability - navigate to the
Page.Controls.Add( new LiteralControl(@"<html>\r\n<body>\r\n <h1>Welcome to my Homepage!</h1>\r\n")); HtmlForm Form1 = new HtmlForm(); Form1.ID = "Form1"; Form1.Method = "post"; Form1.Controls.Add( new LiteralControl("\r\nWhat is your name?\r\n")); TextBox TextBox1 = new TextBox(); TextBox1.ID = "txtName"; Form1.Controls.Add(TextBox1); Form1.Controls.Add( new LiteralControl("\r\n<br />What is your gender?\r\n")); DropDownList DropDownList1 = new DropDownList(); DropDownList1.ID = "ddlGender"; ListItem ListItem1 = new ListItem(); ListItem1.Selected = true; ListItem1.Value = "M"; ListItem1.Text = "Male"; DropDownList1.Items.Add(ListItem1); ListItem ListItem2 = new ListItem(); ListItem2.Value = "F"; ListItem2.Text = "Female"; DropDownList1.Items.Add(ListItem2); ListItem ListItem3 = new ListItem(); ListItem3.Value = "U"; ListItem3.Text = "Undecided"; DropDownList1.Items.Add(ListItem3); Form1.Controls.Add( new LiteralControl("\r\n<br /> \r\n")); Button Button1 = new Button(); Button1.Text = "Submit!"; Form1.Controls.Add(Button1); Form1.Controls.Add( new LiteralControl("\r\n</body>\r\n</html>")); Controls.Add(Form1);WINDOWS\Microsoft.NET\Framework\Version\Temporary ASP.NET Files
folder and open one of the.cs
or.vb
files.
One thing to notice is that, when the control hierarchy is constructed, the properties that are explicitly set in the declarative syntax of the Web control are assigned in the code. (For example, the Button Web control has itsText
property set to "Submit!" in the declarative syntax –Text="Submit!"
– as well as in the autogenerated class —Button1.Text = "Submit!";
.
After the Instantiation stage, the page lifecycle enters the Initialization stage. In this stage, the page's
Init
event is fired, along with the Init
event of the page's server controls.
Following the Initialization stage, the page's view state is restored in the Load View State stage. Each ASP.NET server control is capable of maintaining its state across postbacks through a mechanism known as view state. View state is utilized when a control's state - its properties - are modified programmatically. Recall that in the Instantiation stage, when the control hierarchy is build, the controls' properties are assigned their default values (namely the values specified in their declarative syntax). If any properties are set programmatically, in the code-behind class, then these changes must be remembered across postbacks. Any state change is remembered across postback through view state.
For More About View State... |
---|
A profound understanding of view state isn't vital for this article. What's vital is to realize that prior to the Load View State the controls' properties are assigned the values specified in the declarative syntax in the HTML portion. After the Load View State, the controls' properties have the actual values (assuming there have been changes to their state on a prior postback). However, if you are interested in learning more about ASP.NET's view state, be sure to read: Understanding ASP.NET View State. |
Following the Load View State stage, the page enters the Load stage, which fires the
Load
event for the page and its controls. You are likely familiar with the Load stage, since virtually every ASP.NET Web page out there has some code in its Page_Load
event handler, which is the event handler that runs when the page's Load
event fires. Sometime after the Load stage, the Save View State stage begins, which entails persisting the view state of the controls on the page into a hidden form field named__VIEWSTATE
. (This hidden form field is how this view state is persisted across postbacks.)
These four stages in the page lifecycle are just a subset of the stages the page proceeds through during its lifecycle. For a more in-depth look at the lifecycle you can readDino Esposito's article: The ASP.NET Page Object Model.
Adding Controls at the Right Time
We already know that when adding controls dynamically through the page's code portion the controls must be added on every postback. But when in the page lifecycle should the controls be added? At first guess, we might decide to put such code in the
Page_Load
event handler, causing the controls to be added during the Load stage of the page's lifecycle. This would work fine if we don't need to worry about saving the controls' view state across postbacks, but if we do need to persist the view state of the dynamically added controls the Load stage is not where we should be adding these controls.
If we need our dynamically added controls to maintain their view state it is paramount that these controls be added before the Load View State stage. That is, these controls must exist within the page's control hierarchy before the view state is loaded. There's only one stage before Load View State - Initialization. That means, if we want our dynamic controls to persist view state we must add them to the control hierarchy in the page's
Init
event.
If you are using Visual Studio .NET, the code-behind class already contains an event handler for the page's
Init
event. This event handler (named Page_Init
in VB.NET code-behind classes and OnInit
in C# code-behind classes) is tucked away in the hidden "Web Form Designer Generated Code" region. What I typically do is create a separate method in the code-behind class and simply call this method from the Init
event handler. Once you have configured everything so that the dynamic controls are added during the Initialization stage, you can then read/write the controls' properties in the Load stage. You'll find that the users' interactions with the dynamic controls remains "remembered" across postbacks if you follow this pattern.A Real-World Example...
In a current project I'm working on, I needed the ability to create various input form fields based upon information about the user who was visiting the page. Each user in the system belonged to one of a set of possible categories, and a number of the input form fields on this page were specific to a category. (For example, users in the category "Employee" might have a drop-down list from which they select their boss, whereas users in the category "Manager" would not have this drop-down list, but rather might have a couple of TextBoxes for information about their division and team.)
One particular data-entry page needed to display the appropriate input form fields, populate them with the user's current responses (if they had provided any), and then provide the user the ability to update (or save for the first time) their information. This involved three steps:
- Create the input form fields based upon the user visiting the page
- Populate the dynamic form fields with the user's values (if any)
- Save the user's responses upon the click of a "Save" button
LoadUI()
that I then have called from the page's Init
event handler. LoadUI()
's sole task is to create the dynamic controls based upon the current user's category. The pseudocode for this method looks as follows:
|
The code shown above starts by determining the user's type. This is performed by an application layer class with a method called
GetUserType()
. The specifics of this method are not important; needless to say, it simply returns the user type of the currently logged on user. Next, I use a series of conditional statements to determine what set of controls to add. (In practice, I actually store the controls to add in a database, and in my LoadUI()
method I retrieve the set of controls to dynamically add based on the user's type. The benefit of this approach is that adjusting the custom input form fields for a particular user type is as simple as modifying the database - there's no need to touch any of the ASP.NET code. However, with my hard-coded approach shown above, any changes to the input forms for different types would require a modification of theLoadUI()
code and a recompilation/redeployment.)
On each page visit, be it the first visit to the page or on a postback, the
LoadUI()
method will be invoked during the page's Initialization stage. Next, we need to have the user's current values (if they exist) displayed in the custom controls when the page is first visited. This is done in the Page_Load
event handler using the following code:
|
When loading the current values, we only do so on the first visit to the page (hence my check for
Not Page.IsPostBack
). To load the current values, I first need to determine the user's type, and then load and populate the values of the dynamic form fields appropriately. In order to set the properties and call the methods of the dynamically created Web controls, I need to be able to reference the controls in the control hierarchy. In Working with Dynamically Created Controls we saw how to use the FindControl()
method to obtain a reference to a control in the control hierarchy. (Again, in practice, I don't use multiple conditionals, but rather determine what dynamic controls need to be populated based on information in the database. This allows me to forgo the conditionals and just have a couple of lines of code that queries the database for the values for the appropriate controls based on the user's type, and then finds those controls and assigns the user's values.)
The final step is to allow the user to update their information and save any changes back to the database. The Web page contains a Button Web and a corresponding
Click
event handler. In the Click
event handler I again iterate through the dynamically added controls based on user type, and update the database accordingly.
|
Conclusion
In this article we saw how to work with dynamic controls so that their values and view state can be correctly persisted across postbacks. Dynamic controls, as evidenced in this articles and others on 4Guys, offer a great deal of capability, but using dynamic controls can be frustrating due to lost controls or view state if the controls are not added to the hierarchy appropriately. As we saw in this article, the general pattern to follow is:
- Add the dynamic controls on each page visit in the page's Initialization stage,
- Read/write the dynamic controls' properties and methods in the
Page_Load
event handler.
A Follow-Up Discussion... |
---|
After posting this article an alert reader, Wessam Zeidan, emailed me sharing that dynamically loaded controls could be loaded in thePage_Load event handler if care was taken in the order with which the control was added to the Controls collection and when its properties were set. For a more in-depth discussion on this be sure to read my blog entries: Control Building and ViewState Lesson for the Day and Controls Building and ViewState Redux. |
Happy Programming!
********************************************************
http://aspnet.4guysfromrolla.com/demos/printPage.aspx?path=/articles/092904-1.aspx
http://aspnet.4guysfromrolla.com/demos/printPage.aspx?path=/articles/092904-1.aspx
Dynamic Web Controls, Postbacks, and View State
Where we can add Dynamic control in OUR Page.
Understanding the Page Lifecycle
As page developers, we often think about ASP.NET Web pages consisting of two distinct portions: an HTML portion and a code-behind class. However, behind the scenes, when an ASP.NET Web page is requested for the first time (or for the first time after the page has changed) the HTML portion is autogenerated into a class from which the code-behind class is derived from. In essence, an ASP.NET Web page is represented, then, as a single class. Whenever an ASP.NET page is requested from the Web server, the corresponding page's class is instantiated and its
ProcessRequest()
method is invoked. This method kicks off the page lifecycle. The page lifecycle is a sequence of stages that the ASP.NET page's corresponding class progresses through. The end goal of the lifecycle is to generate the page's appropriate markup, which is then sent back to the requesting browser.
The page lifecycle is composed of a number of steps, the following ones being the ones of interest for this article:
- Instantiation,
- Initialization,
- Load View State,
- Load,
- Save View State
Adding Controls at the Right Time
We already know that when adding controls dynamically through the page's code portion the controls must be added on every postback. But when in the page lifecycle should the controls be added? At first guess, we might decide to put such code in the
Page_Load
event handler, causing the controls to be added during the Load stage of the page's lifecycle. This would work fine if we don't need to worry about saving the controls' view state across postbacks, but if we do need to persist the view state of the dynamically added controls the Load stage is not where we should be adding these controls.
If we need our dynamically added controls to maintain their view state it is paramount that these controls be added before the Load View State stage. That is, these controls must exist within the page's control hierarchy before the view state is loaded. There's only one stage before Load View State - Initialization. That means, if we want our dynamic controls to persist view state we must add them to the control hierarchy in the page's
Init
event.
No comments:
Post a Comment