Key Configuration Settings When Deploying a Web Application
By Scott Mitchell
Introduction
The configuration information for an ASP.NET application is stored in one or more XML-based configuration files named
Web.config.
The default configuration settings for all web applications on the web server are spelled out in the Web.config file in the
$WINDOWS$\Microsoft.NET\Framework\version\CONFIG folder. These default settings can be added to over overridden for a specific
web application by the Web.config file in that application's root directory. Moreover, these configuration settings can be customized
for a web application on a folder-by-folder basis by adding Web.config files to the application's subfolders.
The Web.config file spells out an array of configuration settings, including: database connection strings, authentication and URL authorization
rules, and the behavior that unfolds when an unhandled exception occurs, among many others. Many configuration settings differ between the development
environment and the production environment. For example, when you are developing an ASP.NET application on your desktop you are likely using a different
database than when the application is in production. Consequently, the database connection strings in Web.config need to be updated
when deploying an application.
Some of these types of configuration settings must be changed when deploying an application, like database connection strings. Failure to modify the configuration information when deploying will cause the web application not to work in production. These types of configuration settings are easy to remember to change. But there are a number of configuration settings that should be changed when deploying an application, but if they are not changed the application will still work in production. These configuration settings are easy to forget to change, and forgetting to change them can reduce the performance of your application or make it more vulnerable to attacks from malicious users. This article details a handful of configuration settings that fit into this latter category. Read on to learn more!
Enabling Custom Errors
In .NET applications, an illegal operation - an invalid cast, attempting to reference a null value, trying to connect to a database that's been taken offline, and so on - raises an exception. Exceptions can be caught and handled directly in code through the use of
Try / Catch
blocks. For ASP.NET applications, if the exception is not handled in code, it bubbles up to the ASP.NET runtime, which raises an
HttpUnhandledException. How the ASP.NET runtime
responds to an HttpUnhandledException depends on your application's configuration settings. The runtime will do one of three things:
- Display a generic error page that simply reports that a runtime error has transpired,
- Display an error page with error details, including the exception that was raised and, if the code is compiled with debug symbols, a stack trace and a few lines of code around where the exception was thrown.
- A custom error page, which is an ASP.NET page that you create that the user is redirected to.
The Web.config file contains a <customErrors> element
that dictates which of the three outcomes detailed above unfolds in the face of an unhandled exception. The mode attribute
of the <customErrors> element can have one of three values:
On- the "Runtime Error" page or custom, user-friendly error page is shown to all visitors in the face of an unhandled exception.Off- the exception details page is shown to all visitors in the face of an unhandled exception.remoteOnly- remote users - those not coming through localhost - see the "Runtime Error" page or custom, user-friendly error page; local visitors - the developers, typically - see the exception details page.
For more information on using the <customErrors> element see: Gracefully
Responding to Unhandled Exceptions - Displaying User-Friendly Error Pages.
| Use Health Monitoring or ELMAH to Log and Notify Developers When an Unhandled Exception Occurs |
|---|
If you notice that your web application on production is generating unhandled exceptions, you may be tempted to update the Web.config
file's <customErrors> element's mode property to Off so that you can see the error details and fix
the cause of the problem. The downside with this approach is that while you have custom errors disabled, all other visitors are seeing the same exception
details screen as you are. Ideally, an ASP.NET application in production should log all unhandled exceptions to a database and e-mail the details
to the site's developers. That way, you are immediately alerted whenever an error occurs in production and you can consult the error log and leave
the custom error logic in tact rather than trying to reproduce the error while having custom errors disabled.
There are two prominent libraries for logging unhandled exceptions: ELMAH and Health Monitoring. For more information on ELMAH read Using HTTP Modules and Handlers to Create Pluggable ASP.NET Components. For more on Health Monitoring check out my article series, Health Monitoring in ASP.NET. |
Turn Off Output Tracing
Output tracing enables developers to display request information at the bottom of a page or from a special URL,
Trace.axd. Tracing
can be configured at the page-level through the Trace attribute in the @Page directive, or can be configured for the entire
web application using the <trace> element in Web.config.
Having tracing enabled in a production environment is ill advised because the trace log displays sensitive information including cookies,
information stored in session state, and any diagnostic information written to the trace log. With tracing enabled, a malicious user could visit
the Trace.axd page and see the trace logs for the last several requests to the application.
To prevent trace information from appearing in a production website you can either disable tracing altogether or configure it so that it's only accessible
when coming through localhost. The <trace> element has two Boolean attributes that specify these particular settings: enabled
and localOnly. For more information see the <trace> element
technical documentation and Tracing in ASP.NET.
Turn Off Debugging Support
When an ASP.NET page is visited for the first time or for the first time after it has been modified, the declarative markup in the page is automatically compiled into a class and is then "executed" by the ASP.NET runtime in order to generate the content to return to the requesting client. This conversion from declarative markup to source code, and the source code's compilation, is seamlessly handled by the ASP.NET runtime when the request is made. Various settings regarding this compilation process can be configured via the
<compilation>
element in Web.config. Furthermore, the source code in the ASP.NET pages' code-behind classes can either be compiled automatically by
the web server or explicitly by the developer before deployment. If you build your application using Visual Studio's Web Site Project model and deploy
the code files (rather than a compiled assembly) then you are using the automatic compilation model, and the <compilation> element's
settings also apply to the auto-compilation of the code-behind classes.
The <compilation> element includes a debug attribute that indicates whether to compile the code in debug mode or in
retail mode. Code compiled in the debug mode includes addition debug symbols and other performance-draining information that is required during debug time.
For applications in the development environment, where you will actively be debugging your application, it makes sense to have the debug attribute
set to true. But when deploying your application, make sure you set this attribute to false. Doing so will improve the performance of your application
by more quickly compiling these resources and using less memory when a page is visited.
For a more detailed discussion of this configuration setting and why it should be set to false, see Scott Guthrie's
blog entry, Don't run production ASP.NET Applications with debug="true"
Enabled. In it, Scott lists four effects of having the debug attribute set to true:
- The compilation of ASP.NET pages takes longer (since some batch optimizations are disabled)
- Code can execute slower (since some additional debug paths are enabled)
- Much more memory is used within the application at runtime
- Scripts and images downloaded from the
WebResources.axdhandler are not cached
"This last point is particularly important, since it means that all client-javascript libraries and static images that are deployed via
WebResources.axd will be continually downloaded by clients on each page view request and not cached locally within the browser. This
can slow down the user experience quite a bit for things like [ASP.NET AJAX], controls like TreeView/Menu/Validators, and any other third-party
control or custom code that deploys client resources. Note that the reason why these resources are not cached when debug is set to true is
so that developers don't have to continually flush their browser cache and restart it every-time they make a change to a resource handler (our
assumption is that when you have debug=true set you are in active development on your site)."
To get optimal performance from your website, make sure that the Web.config file in production has the <compilation>
element's debug attribute set to false.
Forcing Deployment Configuration Best Practices Using the <deployment retail="true" /> Setting
If you are deploying your web application to a machine that you have control over, such as a web server within your company's intranet or a dedicated web server at a web host provider, you can use the
<deployment> element
in machine.config to force all applications on the web server to adhere to the recommendations provided above (namely, using a custom
error page, disabling output tracing, and not having the auto-compiled code compiled in debug mode). Simply add the following markup to the
machine.config file within the <system.web> element:
<deployment retail="true" />
|
Note: You'll find the machine.config file in the $WINDOWS$\Microsoft.NET\Framework\version\CONFIG folder.
That's all there is to it! To undo this setting, you can remove this element or set the retail attribute to false (the default). Keep in
mind that the <deployment> element can only appear in machine.config, and not Web.config, and applies
to all websites on the server.
Conclusion
There are a variety of configuration settings relevant for an ASP.NET application, and some of these settings should differ based on whether the application is in a development environment or a production environment. This article looked at three configuration settings that do not need to be changed when deploying an application, but definitely should be changed for performance- and security-related reasons. If you have control over the web server you can force these best practice configuration settings by adding
<deployment retail="true" /> to the server's machine.config
file.
Happy Programming!
Further Reading
debug="true" Enabled<deployment> Configuration Option



