When you think ASP, think...
Recent Articles xml
All Articles
ASP.NET Articles
Related Web Technologies
User Tips!
Coding Tips
spgif spgif

Book Reviews
Sample Chapters
JavaScript Tutorials
MSDN Communities Hub
Official Docs
Stump the SQL Guru!
Web Hosts
Author an Article
spgif spgif

ASP ASP.NET ASP FAQs Feedback topnav-right
Print this Page!
Published: Wednesday, December 10, 2008

Key Configuration Settings When Deploying a Web Application

By Scott Mitchell


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!

- continued -

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.
When an unhandled exception occurs in a production environment it is important that the user not see the exception details page, for such information could constitute a security risk. For instance, the line of code where the exception was raised might include sensitive information in the source code, such as an ad-hoc SQL query or, even worse, a database connection string. Even if the code shown in the exception details page doesn't reveal any such tidbits, by showing the details of the exception you are revealing some of the inner workings of how your application works to the visitor. This may give a malicious visitor additional information on how to compromise your application. Furthermore, the exception details page is ugly a bewildering to most users. It's best to show them a custom error page whose look and feel mimics the look and feel of your website.

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:

  1. The compilation of ASP.NET pages takes longer (since some batch optimizations are disabled)
  2. Code can execute slower (since some additional debug paths are enabled)
  3. Much more memory is used within the application at runtime
  4. Scripts and images downloaded from the WebResources.axd handler are not cached
Scott continues:
"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.


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!

  • By Scott Mitchell

    Further Reading

  • Gracefully Responding to Unhandled Exceptions - Displaying User-Friendly Error Pages
  • Tracing in ASP.NET
  • Don't run production ASP.NET Applications with debug="true" Enabled
  • The <deployment> Configuration Option
  • Beware of Deploying Debug Code in Production

  • ASP.NET [1.x] [2.0] | ASPMessageboard.com | ASPFAQs.com | Advertise | Feedback | Author an Article