Pro ASP.NET 2.0 In CSharp 2005 (2005) [eng]
.pdf
618 C H A P T E R 1 7 ■ R E S O U R C E S A N D L O C A L I Z AT I O N
Text Directions
Finally, you need a way to specify the text direction in international applications, because some cultures read from left to right and others read from right to left.
You can use a couple of controls in ASP.NET, such as the Panel control and the WebPart control, to deal with this. Therefore, it makes sense to define a property in either the global resources or the local resources for the text direction and to use explicit localization expressions for setting the direction property of these controls. For setting this property directly in the root element of your HTML file, you must use the runat="server" attribute to the <html> tag itself, and then you can apply explicit localization expressions to it, as shown in the following code excerpt:
<html runat="server"
dir='<%$ Resources:ValidationResources, TextDirection %>' xmlns="http://www.w3.org/1999/xhtml" >
...
</html>
Summary
In this chapter you learned the fundamentals of creating international web applications with ASP.NET. First, you learned how .NET manages resources for applications and how you can access those resources programmatically. Furthermore, you saw that resources are not only useful for localization but also for other things, such as embedded default templates for reports (these can act as a fallback solution if no templates exist in other directories), additional setup scripts, or XML fragments used by your application.
Second, you learned about how the CLR manages culture-specific resources. The CLR selects embedded resources based on the CultureInfo set on the Thread.CurrentUICulture property. It includes a fallback mechanism (often referenced as hub and spoke) for locating resources by searching from the closest matching culture resources to the more general culture resources in a defined hierarchy of cultures. If it cannot find a matching culture, it uses the application’s default culture for localization.
Finally, you learned how ASP.NET and Visual Studio support you with localizing web applications through local page resources as well as shared application resources. You learned how to access these resources programmatically as well as declaratively through implicit and explicit localization expressions.
620 C H A P T E R 1 8 ■ W E B S I T E D E P L OY M E N T
Figure 18-1. IIS management console
IIS and URL Processing
Web applications are accessed over HTTP by clients typing a URL into a browser. The browser passes this request to the server (in this case IIS), which actually processes the request.
When IIS receives a request, its first step is to examine the requested URL. A typical URL for a web application might take the following format:
http://WebServer/OnlineStore/catalog.aspx
If the website configured on the server does not run on the default port, 80, you have to specify the site’s port in the URL. The following example accesses the same page on the same server but uses the port number 1234 because the website is running on this port and not on port 80.
http://WebServer:1234/OnlineStore/catalog.aspx
In this case, the first portion (WebServer:1234) identifies the name of the web server computer on a local network and the port. The second portion (OnlineStore) identifies the virtual directory where the ASP.NET application is stored. The third portion (catalog.aspx) indicates the requested file. The file extension gives IIS the necessary information for deciding how the request will be processed. Every file extension is registered in IIS and connected with the so-called ISAPI extension, as shown in Figure 18-2.
As you can see, every file extension is connected to a DLL file. Actually, these DLLs are the ISAPI extensions responsible for processing requests for URLs, with a requested file having a specific file extension connected with this ISAPI DLL. For example, the file extension .asp is connected with the asp.dll ISAPI extension. That means the classic ASP runtime is defined within this ISAPI extension.
Any file extensions, such as .aspx and .asmx, that should be processed by the ASP.NET runtime are connected with the appropriate aspnet_isapi.dll ISAPI extension. These entries are automatically added to the IIS configuration when installing the .NET Framework on the target machine. As every version of the .NET Framework resides in a separate directory, every web application can be configured with the necessary version of the ASP.NET ISAPI extension. Therefore, using multiple versions of ASP.NET side by side (for example, ASP.NET 1.0, 1.1, and 2.0) for different web applications is possible without any types of side effects. You will learn more about side-by-side execution later in the section “ASP.NET Side-By-Side Execution.”
C H A P T E R 1 8 ■ W E B S I T E D E P L OY M E N T |
621 |
Figure 18-2. ISAPI filter configurations
■Tip With ASP.NET 1.0 and 1.1, you had to ensure that every virtual directory was mapped to the correct version of the ASP.NET ISAPI extension by configuring the virtual directory with the command-line tool aspnet_regiis.exe, because the installation of the .NET Framework 1.1 automatically configured every virtual directory for ASP.NET 1.1. That means after you installed .NET 1.1, every ASP.NET application automatically executed with the 1.1 runtime version. If you still wanted to use the 1.0 version of the runtime, you had to call the aspnet_regiis.exe tool included with .NET 1.0 to register the ISAPI extensions for the virtual directory appropriately. ASP.NET 2.0 installs an additional property page to the virtual directory properties that allows you to configure a virtual directory for a specific version of ASP.NET by just selecting the version from a combo box. This property page then automatically configures all the mappings correctly for you.
Because the file requested in the previous URL has the extension .aspx, IIS recognizes that it’s a request for an ASP.NET resource, and it passes the request to ASP.NET. Interestingly enough, IIS will pass the request to ASP.NET even if the file doesn’t exist. That allows ASP.NET to add extensions that don’t actually correspond to physical pages. One example is the trace.axd extension, which allows local developers to see recent debugging output.
Of course, URLs can come in many flavors. If your web server is publicly accessible over the Internet, clients might connect to it using an IP address or a registered domain name.
Here are two examples:
http://145.0.5.5/OnlineStore/catalog.aspx
http://www.MyBusiness.com/catalog.aspx
622 C H A P T E R 1 8 ■ W E B S I T E D E P L OY M E N T
Finally, you’ve no doubt noticed that not all URLs include the portion with the filename. For example, you might make a request like this:
http://WebServer/OnlineStore
In this case, if OnlineStore is a virtual directory, IIS will search for one of the default documents and automatically run that. By default IIS will check first for a Default.htm file, then will check for Default.asp, index.htm, iisstart.asp, and finally will check for the ASP.NET file Default.aspx. As a result, it’s always a good idea to name your web application’s home page Default.aspx. (Of course, you can configure this list of default documents using IIS, as described in the “Managing Websites” section of this chapter.)
■Tip Even if you don’t know the name of the computer you’re working on, you can still easily request a local page using the loopback address. The loopback address is 127.0.0.1, and the alias is localhost. The loopback address and alias always point to the current computer and are extremely useful while testing. For example, you can enter http://localhost/OnlineStore/catalog.aspx to request an ASP.NET page from the OnlineStore virtual directory on the local computer.
■Tip As mentioned previously, you can configure multiple websites on one IIS server. Every website has to run on a separate port. This port has to be specified in the URL, as shown previously when accessing a web application running in one site, except the port has the default value of 80. Basically that means you can have only one website running on port 80. But IIS supports the notion of host headers. In the website’s properties in the Advanced Web Site Identification dialog box, you can configure a host header for the website. Using this setting you can have multiple websites running on the same port. (Of course, every website then needs a different value for the host header setting.) Your web server needs to be made accessible through multiple machine names whereas every machine name maps to a configured host header value. In that case, IIS determines the website that contains the web application that serves the request based on the requested web server’s machine name. It compares the machine name with the host header values of the websites and selects the website with the host header name that matches this machine name.
Request Processing with IIS and ASP.NET
When IIS receives a request for static content, such as an HTML page or a graphic, it serves the file immediately (assuming there aren’t any settings that prevent this file from being accessed in the current security context). Any file registered with a specific ISAPI DLL is not processed by IIS directly but through the registered ISAPI DLL.
That said, for an ASP.NET request, IIS just performs some preprocessing steps, such as checking security, and then forwards the request to the aspnet_isapi.dll extension. But the extension itself doesn’t process the request. Although the processing models are different between IIS 5.x and IIS 6.0, the ISAPI extension forwards the request in any case to the managed ASP.NET runtime, as you can see in the high-level architecture shown in Figure 18-3.
As you can see in Figure 18-3, the ASP.NET runtime works completely independently from the actual web server. That said, you now know why Visual Studio is able to use the integrated Visual Web Developer Web Server. The Visual Web Developer Web Server is just another host for the ASP.NET runtime, and you can even create your own ASP.NET runtime host.
624 C H A P T E R 1 8 ■ W E B S I T E D E P L OY M E N T
As soon as the isolation level for a classic ISAPI extension–based application is set to High, IIS executes the ISAPI application in a separate dllhost.exe process. As mentioned, ASP.NET applications run in their own, isolated worker process. The applications are isolated through application domains. Application domains are mechanisms of the CLR for isolating .NET components running in the same host process for security and reliability reasons. In addition, this worker process provides a completely configurable process model that defines several settings for increasing the reliability of web applications; settings include process recycling, worker process memory
limits, request queuing, and much more. Table 18-1 outlines the most important settings of the <processModel> element in the machine.config configuration file. (You can find a complete list in the documentation for the <processModel> element on MSDN Online.)
Table 18-1. The <processModel> Element in the machine.config File
Configuration |
Description |
enable |
Enables or disables the ASP.NET process model. If the process |
|
model is enabled, the ASP.NET runtime is executed in its own |
|
worker process. If not, ASP.NET applications are executed directly in |
|
the web server process. |
timeout |
Specifies how long ASP.NET waits for a worker process before it |
|
creates a new instance of the worker process. Therefore, if a worker |
|
process hangs for some reason, other ASP.NET applications are still |
|
available, because the runtime creates a new worker process. |
idleTimeout |
Every worker process requires some resources in memory. |
|
Therefore, if requests come in infrequently, the runtime can shut |
|
down the process for saving resources. This value specifies how long |
|
the runtime waits for shutting down the worker process if it is idle |
|
and not processing any requests. |
shutdownTimeout |
In a normal situation the ASP.NET runtime sends a signal to the |
|
worker process for shutting down normally. If the worker process |
|
takes longer for shutting down than configured with this setting, it |
|
just kills the worker process abnormally. |
requestLimit |
If the number of requests processed by a worker process exceeds |
|
this number, the runtime launches another worker process. The old |
|
worker process completes processing the requests of the previously |
|
attached requests and shuts down afterward. |
requestQueueLimit |
If the number of requests in the worker process’s queue to be |
|
processed exceeds this number, ASP.NET returns a 503 (server too |
|
busy) error. This is useful in particular for mitigating denial-of- |
|
service attacks in terms of required resources. (If too many requests |
|
come in and every request requires a large amount of memory, the |
|
resources on the server might not be enough.) You should carefully |
|
configure this setting. The other problem is that if you configure this |
|
setting with a too-low number, probably too many users would get a |
|
503 error. This could result in a denial-of-service attack again in |
|
terms of blocking real users’ requests while an attacker is flooding |
|
the server with senseless requests. Therefore, the setting alone is not |
|
enough for mitigating denial-of-service attacks (although it’s hard |
|
mitigating them in general). Finding the appropriate application |
|
architecture and avoiding things such as storing lots of data for |
|
anonymous users are essential tasks. |
restartQueueLimit |
Specifies the maximum number of requests queued while waiting |
|
for the worker process to restart after an abnormal termination. |
C H A P T E R 1 8 ■ W E B S I T E D E P L OY M E N T |
625 |
Configuration |
Description |
memoryLimit |
Specifies the maximum amount of memory in percent of the total |
|
memory available on a system that can be used by the worker |
|
process. If this amount is exceeded, the runtime automatically |
|
launches a new process, reassigns requests to this new process, |
|
and shuts down the old process. But remember, even if you have a |
|
system with more than 2 GB of RAM and have configured this |
|
setting appropriately, you might get an out-of-memory exception if |
|
the process requires more than 2 GB of RAM. The reason for that is |
|
that the operating system itself by default doesn’t allow a process to |
|
have more than 2 GB. By enabling the so-called 4GB RAM TUNING |
|
feature on the operating system, a process can have up to 3 GB |
|
of RAM. |
webGarden |
This setting is especially important for multiprocessor environ- |
|
ments. Basically, it allows the runtime to start more than one worker |
|
process on one machine for request processing if the machine has |
|
more than one CPU. Actually, you can start exactly one process per |
|
CPU if web gardening is enabled for improving the performance |
|
of your web application. This setting is used together with the |
|
cpuMask setting. |
cpuMask |
This setting is used in conjunction with the webGarden setting. |
|
If web gardening is enabled, this setting specifies a bitmask that |
|
enables web application processing for different CPUs in the |
|
system. Every CPU is represented by a bit, and if this bit is set to 1, |
|
the ASP.NET runtime starts a worker process for the CPU. The |
|
bitmask is stored as a hexadecimal value in this setting. |
username |
Every process on a Windows system has to run under a specific |
|
identity. The user name of the process model element specifies the |
|
identity under which the worker process will run. Each access to the |
|
file system or to any other unmanaged operating system resources is |
|
verified against the process’s identity. The default for this setting is |
|
Machine, which actually is a special setting that identifies the local |
|
machine’s ASPNET user account. |
password |
Specifies the password for the user account used for the worker |
|
process. By default this is set to the value AutoGenerate, which uses |
|
the password automatically generated during the installation of the |
|
.NET Framework. |
responseDeadlockInterval |
The ASP.NET runtime “pings” the worker process in regular intervals |
|
to verify if it is still alive. The process has to respond to this ping in |
|
the time specified in this setting. If the process hangs for any reason |
|
and doesn’t respond in the time specified here, the runtime starts a |
|
new instance of the process and reassigns all requests in the request |
|
queue. |
maxWorkerThreads |
Allows you to configure the number of threads used for processing |
|
requests within one worker process. |
maxIoThreads |
Specifies the maximum number of IO threads per worker process |
|
instance. |
|
|
As successful as it is, this process model has two significant flaws. First, if an application running directly in the web server process crashes, it can crash the whole web server. For that reason, the IIS product team added the possibility of configuring isolation levels and executing web applications in separate processes, which solves this problem. However, by default this behavior is
not applied to ASP.NET applications, because they run in the external ASP.NET worker process (aspnet_wp.exe). It just affects classic ASP applications or any other type of ISAPI extension
626C H A P T E R 1 8 ■ W E B S I T E D E P L OY M E N T
(such as PHP, Perl, or custom C++ ISAPI extensions). To apply this behavior to ASP.NET, you have to disable the process model through the <processModel> element in machine.config, as described previously. Disabling the ASP.NET process model means you cannot use the process model features described. Furthermore, it means that for every process an instance of the CLR has to be loaded. Of course, you should keep in mind that loading more instances of the CLR means that more memory is required.
Second, when taking a closer look at Figure 18-4, you can probably see that the process model has another, much bigger problem. Take a close look at the request flow in Figure 18-4! You’ll see two context switches within the flow: the first one happens between the kernel mode network stack and the web server running in user mode, and the second context switch happens between the web server process and the external dllhost.exe or aspnet_wp.exe worker process. Context switches are expensive operations, especially if processes are running under different users. Data marshaling has to happen, and data must be exchanged between processes. To increase performance and reliability, the IIS product team has significantly changed the architecture of IIS with the release of Windows Server 2003, as you will see in the section “IIS 6.0 Process Model” of this chapter.
Custom Identities for the Worker Process
As you have seen already in Table 18-1, the <processModel> element includes a user name and password combination. By default the user name is set to Machine, and the password is set to Autogenerate. This setting automatically selects the ASPNET account, which is a low-privileged account generated with the installation of ASP.NET. Of course, the password is generated during installation as well and therefore unknown (which is not really a problem, because the ASPNET user is not intended to be used for interactive logon sessions).
Of course, if your code needs additional permissions (and it often will to access a file, database, registry key, and so on), you can either grant ASPNET these permissions or instruct ASP.NET to use a different account. In some cases, such as accessing network resources, it is necessary to create a separate user account. In this case you can enter the user name and password of another user in the <processModel> element, as follows:
<processModel enable="true" ...
userName="MyUser" password="{the@password1}" ... />
Of course, the fact that the user name and password are not encrypted in this file is not really beautiful. Even worse, the new configuration encryption cannot be used with the <processModel> element. Fortunately, another tool (which needs to be downloaded separately) exists for encrypting this data (as well as user name and password settings stored in the <identity> configuration entry). This tool is aspnet_setreg.exe, and you can download it from the Microsoft website. The .NET runtime automatically decrypts the information. (This functionality has been added with a patch for ASP.NET 1.0 and is included in ASP.NET 1.1.)
IIS 6.0 Process Model
Windows Server 2003 was the first operating system released after the launch of the Trustworthy Computing Initiative. IIS 6.0, therefore, is the first web server from Microsoft developed completely within the parameters of the new security directives created during this initiative. These directives have changed the whole development process in relation to security.
Actually, IIS 6.0 is not just a product upgrade; it’s a complete rewrite of the product with security and reliability taken into consideration from the first moment of the development life cycle for the product. The basic concepts such as websites, virtual directories, and the metabase (which is stored as XML in IIS 6.0) are still the same and configured in the same way, but the way the server processes requests is significantly different, as you can see in Figure 18-5.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
C H A P T E R 1 8 ■ W E B S I T E D E P L OY M E N T |
627 |
|||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Figure 18-5. The IIS 6.0 process model
The web server is now split into several components. Instead of receiving requests from the TCP/IP network stack, Windows Server 2003 includes a kernel mode driver called HTTP.SYS, which is responsible for receiving HTTP requests from clients. The kernel mode forwards requests to any process that registers itself for specific URLs. Therefore, any application that registers with the kernel mode driver can receive HTTP requests without running a whole web server.
■Note The method described previously will be used in the next generation of the operating system not only for HTTP but also for several other protocols. The next generation of the messaging system, code-named Indigo, will leverage this infrastructure as a hosting model as well. The hosting model is currently referenced as WebHost and provides the basic runtime environment for several protocols (TCP, SOAP, and so on).
IIS leverages this infrastructure for launching so-called W3C worker processes (W3WP.EXE). Every worker process runs one or more applications, either ASP.NET-based applications or other types of web applications. These worker processes provide a mechanism for isolation. As applications are running in separate processes, a crash of one application doesn’t affect other applications at all. In addition, IIS 6.0 introduces WAS, which monitors the activities of worker processes. If a worker process fails, WAS automatically restarts the process so that the application is still available after the crash. Furthermore, you can configure a separate identity for every worker process. This allows you to configure additional isolation through permissions of the account that’s configured for the worker process.
The worker processes are configured through application pools in the IIS management console, which includes new configuration options for this process model. For every application pool, the web server creates an instance of a worker process. Web applications (virtual directories) are assigned to these application pools. Each application pool can run as many applications as you want. The configuration for the application pools on one application replaces the isolation level known from IIS 5.x configurations. Figure 18-6 shows the IIS management console with the application pools as well as the property page of one virtual directory with the application pool configured.
Application pools allow you to easily configure different web applications to run under different accounts with different resource usage limits, use multiple CPUs, and provide even more robust web application isolation. Of course, the drawback is that these separate instances of the IIS worker process load separate instances of the CLR, which consumes additional memory.
