10 Things ASP.NET Developers Should Know About Web.config Inheritance and Overrides

The ASP.NET configuration system is build around the idea of inheritance:

Each Web.config file applies configuration settings to the directory that it is in and to all of the child directories below it. Settings in child directories can optionally override or modify settings that are specified in parent directories. Configuration settings in a Web.config file can optionally be applied to individual files or subdirectories by specifying a path in a location element.

The root of the ASP.NET configuration hierarchy is the systemroot\Microsoft.NET\Framework\versionNumber\CONFIG\Web.config file, which includes settings that apply to all ASP.NET applications that run a specific version of the .NET Framework. Because each ASP.NET application inherits default configuration settings from the root Web.config file, you need to create Web.config files only for settings that override the default settings.

For a lot of sites, you don't really need to know about that - you can get by with one Web.config file for the site. But, knowing how the inheritance works - and how to control it - can really help out.

I've noticed that a lot of the questions I answer questions on forums, StackOverflow, and internal e-mail lists can be solved by better understanding how ASP.NET configuration inheritance and overrides work. And so, a bunch of tips about how ASP.NET configuration inheritance and overrides work! I'll start with some basics, but there are some towards the end I'll bet most ASP.NET developers don't know.

Tip 1: Using Web.config files in site subfolders

And ASP.NET website's Web.config is part of an inheritance chain. Your website's subfolders can have Web.config - an example is the Web.config file in an ASP.NET MVC application's View folder which does things like preventing directly viewing the View templates:

2012-01-12 23h57_09

This allows for setting general settings at the site level and overriding them when necessary. Any settings in the base Web.config that aren't overridden in the subfolder stay in effect, so the "child" Web.config can be pretty small. You can continue to nest them, so sub-sub-subfolders can get their own Web.config if needed. Some of the most common uses of subfolders are to restrict permission (e.g. requiring authentication or restricting access to resources), but you can also use them to do things like include default namespaces in Views, toggle handlers, etc.

Tip 2: Understand how your site Web.config inherits its settings

But there's an inheritance chain above the site, too. Here's a simplified version from the MSDN docs:

Configuration level

File name

File description

Server

Machine.config

The Machine.config file contains the ASP.NET schema for all of the Web applications on the server. This file is at the top of the configuration merge hierarchy.

IIS

ApplicationHost.config

ApplicationHost.config is the root file of the IIS 7.0 configuration system. It includes definitions of all sites, applications, virtual directories, and application pools, as well as global defaults for the Web server settings. It is in the following location:

%windir%\system32\inetsrv\config

Root Web

Web.config

The Web.config file for the server is stored in the same directory as the Machine.config file and contains default values for most of the system.web configuration sections. At run time, this file is merged second from the top in the configuration hierarchy.

Web site

Web.config

The Web.config file for a specific Web site contains settings that apply to the Web site and inherit downward through all of the ASP.NET applications and subdirectories of the site.

ASP.NET application root directory

Web.config

The Web.config file for a specific ASP.NET application is located in the root directory of the application and contains settings that apply to the Web application and inherit downward through all of the subdirectories in its branch.

ASP.NET application subdirectory

Web.config

The Web.config file for an application subdirectory contains settings that apply to this subdirectory and inherit downward through all of the subdirectories in its branch.

So your website's configuration's actually inherited a bunch of settings that were set at the server level. That's nice for a few reasons:

  1. It allows the ASP.NET / IIS teams to migrate settings that aren't commonly modified from the project template Web.config files to server defaults, keeping your Web.config files smaller and more readable. For example, ASP.NET 4 migrated a bunch of handler registrations to Machine.config, so the Empty ASP.NET Application Web.config is slimmed down to about 8 lines.
  2. You can override things at the server level as needed, and they'll take effect for all applications. For example, you can set <deployment retail="true"> on production servers to disable trace output and debug capabilities.
  3. You can find a lot of useful information in the Machine.config default settings since they're stored in plain text. For example, the ASP.NET Membership Provider has some defaults set for password requirements and the membership database, and you can look them up by looking in the appropriate .NET framework version's Machine.config. For a default installation of ASP.NET 4, that's found in C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Config\machine.config with a quick search for <membership>.

Tip 3: Understand how your Web.config inherits IIS configuration settings

This overlaps a bit of Tip 2, but it bears repeating. Long-time ASP.NET developers (myself included) are prone to thinking of ASP.NET and IIS configuration separately, but that all changed with IIS 7. This is all pretty old news, as IIS 7 has been out for a while, but it hasn't been completely absorbed by ASP.NET developers.

CarlosAg summed this up well in a post from 2006(!) which explained The New Configuration System in IIS 7.  I'm not going to rehash his post here - go read it. Some important takeaways are that both the ApplicationHost.config and Machine.config feed into the configuration settings in your site's Web.config, as shown in Carlos' diagram:

In addition to the understanding how things work part of it, this is also good to know because - based on the info in Tip 2 - you can see what the base settings are, and how you can override them in your application's Web.config. This is why you can do pretty advanced things like configure rules on for the URL Rewrite Module in your application's web.config.

Of course, server administrators don't necessarily want to allow any application on the server to modify settings via Web.config, so there are configurable policies in the ApplicationHost.config which state whether individual applications can override settings. There's also an Administration.config file which controls things like Module registration.

There's one kind of new update to this list - using aspnet.config for Application Pool tuning. It's found in the same directory as Machine.config, and it's been around since .NET 2.0. However, as of ASP.NET 4 it's been expanded to handle things like concurrency and threading, as explained in Scott Forsyth's post, Setting an aspnet.config File per Application Pool. While not something most ASP.NET developers will need to use, it's good to know that you can control things like maxConcurrentRequestsPerCPU, maxConcurrentThreadsPerCPU and requestQueueLimit at the application pool level.

Tip 4: Location, location

While it's nice to be able to override settings in a subfolder using nested Web.config files, that can become hard to manage. In a large application, it can be difficult to manage settings because you can't see the effective permissions in one place. Another option is to use the <location> element to target settings to a specific location. For example, I previously showed how to use this to allow large file uploads to a specific directory in an ASP.NET application using the location element:

<location path="Upload">
    <system.web>

        <httpRuntime executionTimeout="110" 
                     maxRequestLength="20000" />
    </system.web>
</location>

Tip 5: Clearing parent settings when adding to a collection

Sometimes you want to remove all inherited settings and start fresh. A common place you'll see this is in handler, module, connection string and provider registration - places where configuration is used to populate a collection. Scott Guthrie blogged about an example in which just adding a new Membership Provider causes problems, because you end up with two providers - the default, and the one you just added. It's important to clear the collection before adding your new provider using the <clear/> element, like this:

<membership>
      <providers>
          <clear/>
          <add name="AspNetSqlMembershipProvider"
              type="System.Web.Security.SqlMembershipProvider, 
                    System.Web, Version=2.0.0.0, 
                    Culture=neutral, 
                    PublicKeyToken=b03f5f7f11d50a3a"
              connectionStringName="MyDatabase"
              enablePasswordRetrieval="false"
              (additional elements removed for brevity)
          />
      </providers>
</membership> 

As Scott explains, failure to <clear/> the collection first results in both providers attempting to handle membership, which probably isn't what you intended.

Tip 6: Locking settings with with allowOverride and inheritInChildApplications

You may need to prevent sub-applications from overriding or extending settings. You can do that with the allowOverride attribute, which does exactly what the name suggests - the same way a sealed class prevents changes via a derived class. The MSDN documentation summarizes this well:

You can lock configuration settings in ASP.NET configuration files (Web.config files) by adding an allowOverride attribute to a location element and setting the allowOverride attribute to false. Then within the location element, you can define the configuration section that you want to lock. ASP.NET will throw an exception if another configuration file attempts to override any configuration section that is defined within this locked location element.

Using a location element with an allowOverride=false attribute locks the entire configuration section. You can also lock individual configuration elements and attributes using lockItem, lockElements, lockAttributes, lockAllAttributesExcept, and lockAllElementsExcept.

That last part there - using attributes on sections - works because those lock attributes are among the general attributes inherited by section elements.

Tip 7: Disinheriting your child applications with inheritInChildApplications="false"

If you've got settings that should only apply to the parent application and shouldn't be inherited, you can use the inheritInChildApplications attribute on any section or location element. That makes the settings at the current level, but inheriting applications and subfolders don't have to bother with clearing and rebuilding configuration just to remove those settings.

This came up in a recent question on StackOverflow:  Unloading parts of a web.config file from a child application

Since Web.config is so heavily built on the concept of inheritance, it's not surprising that turning it off for a section can have some side effects. The aptly self-named "Run Things Proper Harry," a.k.a. rtpHarry, has written up two good posts covering usage and important things to be aware of.

Tip 8: Use configSource to separate configuration into separate files

While I've been discussing modification of Web.config settngs through inheritance, it only makes sense to mentions some useful ways to handle overriding Web.config settings.

Any Web.config section can be moved to a separate file by setting the configSource attribute to a file reference. I've mostly used this for handling connection strings, since it allows you a lot more flexibility over versioning and and deployment. Instead of having different Web.config files for each environment ("Oops! Just deployed the staging Web.config to production!!!"). It looks like this:

<configuration>
  <connectionStrings configSource="connectionStrings.config" />
  ...

Then your connectionStrings.config file only needs to change between environments, and can contain specific settings. It holds the contents of the element you're referring to, so it looks like this:

<connectionStrings>
  <add name="subtextData"
    connectionString="Server=.;Database=staging;Trusted_Connection=True;" />
</connectionStrings>

Another way I've seen this done is to have differently named connection strings config files for each environment (e.g. dev.config, staging.config, production.config). That allows you to check them all in to source control and not worry about getting files with the same name but different contents mixed up, but the tradeoff is that your Web.config in each environment needs to be updated to point to the right config source.

So, this is a handy trick, but isn't quite perfect. A better option is to use Web.config File Transformations.

Tip 9: Use Web.config Transforms to handle environmental differences

I don't hear as much about Web.config Transforms as I'd expect. Maybe they just work and everyone just quietly uses them and doesn't talk about it. But from the questions I see coming up over and over again, I'm not sure that's the case.

I love Web.config Transforms. At my first ASP.NET MVP summit, I was part of a feedback group discussing frustrations with deploying ASP.NET applications. Two themes that came up over and over were difficulties with packaging and managing configuration. That team later produced Web Deployment Packages (a nice format that packages files and settings for a site in a way that can be inspected and modified during installation) and Web.config Transforms.

All the new ASP.NET projects have Web.config transforms already set up - if you expand the Web.config node, you'll see that it's configured to create different settings for Debug and Release mode.

2012-01-17 14h51_29

It's really easy to use - your main Web.config has the base settings for your site, and whenever you build, the transforms for the appropriate build configuration (e.g. Debug or Release) are automatically applied. If you had a Test database that you wanted to use by default, but wanted your Release builds to run against the Production database, you could set it up so that your base Web.config connection string points to the Test Database connection string, like this:

<connectionStrings>
  <add name="ApplicationServices"
      connectionString="[TestDatabase]" />
</connectionStrings>

Then your Web.Release.config overwrites that to point at the Production database, like this:

<?xml version="1.0"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
  <connectionStrings>
    <add name="ApplicationServices" 
        connectionString="[ProductionDatabase]" 
        xdt:Transform="Replace" xdt:Locator="Match(name)"/>
  </connectionStrings>
</configuration>

The syntax is pretty straightforward, but you don't need to worry about that because the comments in the Web.Release.config file already show how to do that.

To be clear: unlike the other examples, this is something that happens at build time, not runtime.

I recently ran into an issue where I wanted to deploy something to AppHarbor and wanted to switch between a local SQL Compact database and the hosted database server, and Web.config Transforms worked just great there.

There's a lot more to talk about with Web.config Transforms that's beyond the scope here, such as:

  • You can create as many build configurations as you want, with different transforms for each configuration. This makes it simple to switch between different settings in your development environment - say, switching between several development databases or other application settings.
  • You can use the configuration transformation system with any XML file using the SlowCheetah Visual Studio extension. Scott Hanselman's written a post with more information on that here: SlowCheetah - Web.config Transformation Syntax now generalized for any XML configuration file
  • Sayed (the Microsoft developer who's worked on both Web.config Transforms and the SlowCheetah extension) has also built a Package Once Publish Anywhere NuGet package which allows you to defer running the transforms until later, using a PowerShell command. That means you can build one Web Deployment Package with all the transforms included, and run them when you're going to deploy to a specific environment.

There's some good information on MSDN about Web.config Transforms:

Tip 10: Managing Application Restarts on Configuration Changes

There are a lot of moving parts in figuring out the configuration for a website, as illustrated above. For that reason, ASP.NET computes the effective settings for the site and caches them. It only recomputes them (and restarts the application) when a file in the sites configuration hierarchy is modified. You can control that on a section by section level using the restartOnExternalChanges property.

One place where configuration changes don't automatically get recomputed is for external config files set using configSource (as shown in Tip 8). You can control that by setting restartOExternalChanges="true" for that section. There's an example on MSDN that shows this in more detail by creating an external configuration file which is loaded via the configuration API (not referenced via configSource), then toggling the restartOnExternalChanges property and showing the differences in operation.

Summary

The ASP.NET Configuration system does quite a bit - I didn't even mention big topics like using the API for reading and writing values to both local and external config files or creating custom configuration sections. This post focuses on one aspect: getting things done by understanding and leveraging inheritance and overrides. Hopefully this gives you both some new tools for effectively handling configuration and some background that helps in troubleshooting when configuration is working as you'd like.

Are there any essential tips that I missed?

45 Comments

  • Very handy reference. Thanks, Jon!

  • Nice post John. Thanks of sharing!!.

  • Nice summary John.

    For "Tip 8: Use configSource to separate configuration into separate files" Isn't it worth mentioning that changes to the external config file don't cause the app to pick them up? At least that's what I read a while ago.

  • hi Jon Galloway,

    to be quite honest with you i was always confused about this root web.config and local, first two paragraphs cleared up the things and i like this article. :)

    thanks for sharing knowledge.

  • I like the web.config transform thing but it is not real world friendly. Most ASP.NET shops promote their applications between server environments. So an app will go from desktop to dev to stage to production. So build once and xcopy across environments. It would be nice if you could add a separate config to the site and a process ran that merge your settings into the master settings. This way I would not have to touch the original web.config file on the server. ASP.net would be smart enough to merge my settings and maybe optimize them.

  • Great roundup.

    I must admit (blush) that I've not been using the Web.config Transforms but have been controlling different settings with external config files and changing the path to the external files at build time with a PowerShell script. After reading your post I implemented the Transforms and got rid of all the external config files on the project I'm working on. It's so much simpler and cleaner!

    Thanks for the inspiration!

  • Disagree on the use of config transforms for environmental specifics. The transform should be used to setup the application package for the target type of release (i.e. release package, debug package). Web Deploy's parameterization should be the mechanism used to inject environmental parameters at the time of deployment. It can be done through the IIS Manager GUI, command line with msdeploy.exe and a setparam file.

    Encouraging the use of transforms for environmental configuration pieces results in people checking in production connection strings, API keys and such to source control. This undermines the integrity of those values that need to be kept to a minimal set of people to ensure their relative security.

  • @ColinBowern

    You can get around the security issue by giving a dummy Release config for the developers, containing placeholders like %CONNECTIONSTRING% instead of the true values. The server admin can take the release deploy package and use a simple program / script to inject the correct values into the config.

    I have used approach this myself. May just post the code sometime.

  • Hi Jon, Thanks for sharing this great stuff :)

  • Having recently tried to use web config transforms, the bug bear for me and the way I work is that the transforms only happen on deploy, not on build. That means if u have connection strings in web.debug.config and hit f5, you don't get the connection strings.

    I like the config source option as a good convention in naming and folder structure make it easy to manage but also a fine grained level of control as to what settings you use

  • I agree with Joel T.'s comment regarding transformations only happening on deploy, not on build. On more than one occasion I've performed a one-click publish only to realize that while I had the Release build configuration applied, the Debug publish configuration was set and the wrong transformations were applied.

  • Hello,
    I don't know if it is the right place to post my message but I hope that you could look at my post!!
    I'm currently doing the tutoriel MVC Music Store application part7. I'm in the section Adding an Administrative User with the ASP.NET Configuration site, I launched a configuration website on the security tab I get an error "Unable to connect to a SQL Server database" I looked at the internet but I didn't find a solution.
    I use MS SQL Server 2008 R2.
    thank you for you're

  • Hey Jon,
    I am facing problem of continues session.timeout in one of my web application even i set up session time out in web.config file. i set session timeout 1 hour in web.config file.

  • To the one with the session timeout. Does your app recycle when you dont expect it? Persisting it to a db can let them live the time you want

  • Great article! Thanks. By the way, is this also applicable to app.config file?

  • Thanks for the nice blog. It was very useful for me. Keep sharing such ideas in the future as well.

  • Great write-up, I am regular visitor of oneˇs site, maintain up the excellent operate, and It is going to be a regular visitor for a lengthy time.

  • Great post made here. One thing I would like to say is always that most professional areas consider the Bachelors Degree like thejust like the entry level requirement for an online college degree. While Associate Diplomas are a great way to get started, completing your current Bachelors starts up many good opportunities to various careers, there are numerous online Bachelor Diploma Programs available coming from institutions like The University of Phoenix, Intercontinental University Online and Kaplan. Another thing is that many brick and mortar institutions offer Online editions of their diplomas but generally for a greatly higher fee than the providers that specialize in online college diploma plans.

  • Its not my first time to pay a quick visit this web site,
    i am browsing this web page dailly and obtain fastidious data from here daily.

  • Sac Longchamp acheter sur notre boutique en ligne d'économiser environ 50% de rabais, soldes longchamp pas cher prix!

  • Economisez 50% sur le beats by dre sur notre boutique, nous vendre beats by dre pas cher et de haute qualité, beats by dre soldes en ligne !

  • Wir sind einer der Louis Vuitton Taschen Online Shop, wir billige Louis Vuitton Taschen bieten, kaufen Sie es auf unserer Louis Vuitton Outlet online!

  • Sac Longchamp acheter sur notre boutique en ligne d'économiser environ 50% de rabais, soldes longchamp pas cher prix!


  • Having read this I thought it was very enlightening. I appreciate you finding the time and effort to put this information together. I once again find myself personally spending way too much time both reading and leaving comments. But so what, it was still worth it!

  • Good day! Do you know if they make any plugins to safeguard against hackers?
    I'm kinda paranoid about losing everything I've worked hard
    on. Any tips?

  • I like what you guys are usually up too. This kind of clever work
    and reporting! Keep up the superb works guys I've included you guys to our blogroll.

  • Hi there! I simply wish to give you a big thumbs up for your excellent information
    you have got right here on this post. I will be coming back to your web
    site for more soon.

  • Hi there, I would like to subscribe for this blog to obtain newest updates, therefore where can i do
    it please help out.

  • You actually make it seem so easy with your presentation but I find this matter to be really something which I think I would never understand. It seems too complicated and extremely broad for me. I’m looking forward for your next post, I’ll try to get the hang of it!

  • its very useful ..thank u ADMIN.

  • I have been exploring for a little for any high quality
    articles or weblog posts in this sort of house . Exploring
    in Yahoo I eventually stumbled upon this site. Reading this info
    So i'm happy to exhibit that I have an incredibly excellent uncanny feeling I discovered just what I needed. I such a lot no doubt will make certain to do not fail to remember this site and give it a look on a constant basis.

  • Asking questions are truly good thing if you are not understanding
    anything totally, except this post presents fastidious understanding yet.

  • Hi this is kind of of off topic but I was wanting
    to know if blogs use WYSIWYG editors or if you have to manually code with HTML.
    I'm starting a blog soon but have no coding knowledge so I wanted to get advice from someone with experience. Any help would be greatly appreciated!

  • Genuinely when someone doesn't know then its up to other people that they will help, so here it occurs.

  • Excellent blog you have got here.. It's difficult to find high quality writing like yours these days. I seriously appreciate people like you! Take care!!

  • In such times, this work is done by introduction letters for partnership.

    Eye catching and unique are some of the rewards programs available.

    I accompanied Luke to drop off his microgreens at a
    bistro. The payroll should be automated and handled by an outside
    payroll service. Kodak's garage sale attracted interest from unlikely alliances in the form becomes" metadata data" data about data.

  • For most Limited Liabilityes, over five years is probably overkill
    because in today's Limited Liability world: the Limited Liability side first, and so forth. Other than having more minds and perspectives, it is as succinct yet descriptive as possible. But if you do not have enough manpower. 04 Black Rock Kelso CapitalI have owned BKCC on and off over the last months, and maintain detailed process information for continuous process improvement. Use the hotel to your advantage.

  • Moreover, search engine results page concerns such as the ones that were tweaked with the first
    major update prior to the event.

  • You made some really good points there. I looked on the
    net for more info about the issue and found most people will go along with your views on this website.

  • Good web site you have got here.. It's hard to find quality writing like yours these days. I honestly appreciate people like you! Take care!!

  • This has all sorts of software applications, Video Games Rental and movies have been created.
    She wore her long brunette hair up and made sure that she was unattractive, and I was looking forward to the most.
    However, keeping emotions controlled can be difficult
    to keep up with all these threats. There are many websites that offer these
    Video Games Rental; hence you need to carry and win the week.

  • Social Media and get your ex back fromSocial media has both positive and negative
    effects on a relationship.

  • It's not my first time to visit this site, i am visiting this web page dailly and obtain good information from here all the time.

  • C The profound interest in exercise and fitness during this period provided the
    background for the inception of the Olympic and Paralympic rugby video game.
    The Baby Word Game One idea for an ice breaker at a baby shower can be a fun night.

  • I almost never comment, but I read a few of the responses on
    10 Things ASP.NET Developers Should Know About Web.
    config Inheritance and Overrides - Jon Galloway. I actually do have 2 questions for
    you if it's allright. Could it be simply me or do a few of these comments look like they are written by brain dead visitors? :-P And, if you are writing on additional sites, I would like to follow everything new you have to post. Would you list of every one of your social networking pages like your linkedin profile, Facebook page or twitter feed?

Comments have been disabled for this content.