Now, that you’ve ensured the requisite packages are installed on your production machine, you should guard some common pitfalls before proceeding to deployment. This is a key part of the pre-deployment checklist. Many of the problems in deployment turn out to be errors in the configuration files. Much of the behavior of ASP.NET can be adjusted in the machine.config and web.config files. One change to the root configuration can have a negative impact on all of the applications running on the server. If you change a setting in these files to gather information during development and forget to return it to the default before rolling out to production, you may face performance or security problems.
When developing a web application, you often want to be able to step through code as it is running in order to find problems. Visual Studio will even offer to automatically modify the web.config file to enable debugging. This is shown in Figure 10-2. This is the source of a common production problem. The dialog warns that debugging should be disabled in production, but it’s easy to forget.
The comment that Visual Studio puts in the web.config file is also a reminder to disable it for deployment:
<system.web> <!-- Set compilation debug="true" to insert debugging symbols into the compiled page. Because this affects performance, set this value to true only during development. --> <compilation debug="true"/>
In production, the primary symptom of this problem is very slow throughput. Instead of having multiple threads trying to serve many requests simultaneously, ASP.NET will use a single thread to run pages. This, of course, greatly reduces efficiency, and requests will start to queue up waiting for their turn or even get rejected outright. This can go undetected if you aren’t monitoring the site carefully (see “Performance Monitoring,” later in this chapter).
When an error occurs during the processing of a page, the stack trace information can be very useful in figuring out what is going wrong. But you don’t want this sort of information to be shown to the end user. The behavior of what to show in error conditions is controlled by the customErrors configuration section.
The default setting for custom errors is remoteOnly. This means that when browsing to localhost on a machine, you will get detailed error reporting, but when viewing the site remotely, custom errors are shown instead. The custom error page is normally a user-friendly error page that hides the technical details of what went wrong. This default setting is designed to allow you to get good information during development but to avoid showing potentially sensitive data to the end user. In many development environments, multiple developers are working together on a single application, so they want additional error information when browsing remotely. You can turn off custom errors by setting the mode to off so that you get the same information whether you are browsing locally or not.
<system.web> The <customErrors> section enables configuration of what to do if/when an unhandled error occurs during the execution of a request. Specifically, it enables developers to configure html error pages to be displayed in place of a error stack trace. <customErrors mode="RemoteOnly" defaultRedirect="GenericErrorPage.htm"> <error statusCode="403" redirect="NoAccess.htm" /> <error statusCode="404" redirect="FileNotFound.htm" /> </customErrors>
After the error is fixed, it is easy to forget to change the mode back to RemoteOnly or On instead of Off. And you probably won’t notice it until some problem arises in the production environment and you discover that error pages are showing customers stack traces instead of something more friendly. Stack traces can give hints about the source code organization, and those hints can sometimes reveal weaknesses to those who may want to attack your site, so it’s important to hide this from users.
Another feature of ASP.NET can result in sharing more information about your server than you intend. The Tracing feature allows you to automatically gather information about the requests being processed. You can then access the trace.axd handler to view the information remotely. This handler is requested from a browser just as though it were a physical page. Remember to view the trace information on the local server if localOnly is true.
<system.web> <trace enabled="true" localOnly="true"/>
The tracing output, shown in Figure 10-3, includes information about the most recent requests, their output size, the makeup of the page, and how long it took to process the page lifecycle events. It also includes a listing of various server variables, which is probably more information than you want to share with users!
The tracing feature is not enabled by default. But if you enable it, remember to disable it again for production web sites. Not only is there the possibility that you are sharing information that you don’t want to, but there is some overhead associated with tracing. If you aren’t using it, there’s no need to tax the performance of your site needlessly.
Because of the number of configuration settings that are not ideal for production environments, there is a global setting that overrides them. The deployment section has a retail attribute. When set to true, the configuration, tracing, and debug sections are overridden to production settings:
<system.web> <deployment retail="true"/>
The deployment setting can only be used at the machine level in the machine.config file. You can’t enable it for just a single application. This setting should always be used on production web servers, so if anyone forgets to modify their web.config on one particular application, this setting will trump those. It’s nice to have a big switch to help you avoid some common mistakes! Be aware, however, that it can also cause confusion when you start toggling one of the other configuration settings and see no effect. Of course, you shouldn’t be doing debugging on a production server anyway, but in rare cases you might need to trace a problem in production that can’t be easily duplicated in a development or test environment.