Web.config location element demystified

I haven't actually met a lot of people who knew the details about the hierarchy of Web.config files and how to utilize the location element. In fact, I've heard multiple people ask "why is there a Web.config file in the Views folder of my MVC application?". Even ASP.NET Core projects require a Web.config file (generated on publish) and you can still use some of the features in there to control the execution of your ASP.NET Core website. When you have finished this post you should be an expert.

Web.config location element demystified

If we forget about Web.config being an XML file with the disadvantages this causes, it is a pretty powerful feature when hosting a website on IIS.

Web.config hierarchy

Before we start discussing the location element, I want to introduce you to the concept of having multiple Web.config files. You already know the one generated in the root of a new project:

Web.config file

This file controls a lot of features in this application, like application settings and HTTP modules and handlers. In a real application you typically have subdirectories, which will allow you to handle requests to an URL like /sub/. The settings inside the Web.config file are available for both the root as well as any subdirectories. Let's say you want some settings specific and visible for /sub/ only, you can place an overwriting Web.config file inside the sub folder. To illustrate, let's create a simple example where appSettings are overwritten.

For the example, I've created a folder named sub and a new Default.aspx file inside that folder. This example is using WebForms but it could be anything on top of IIS. Inside the sub folder, I'm also placing a new Web.config file:

Nested Web.config file

In the appSettings element of the Web.config file located in the root, I'll create a new setting named Message:

<configuration>
  <appSettings>
    <add key="Message" value="Frontpage"/>
  </appSettings>
  ...
</configuration>

In the appSettings element of the Web.config file located in the Sub folder, I'll create a similar setting also named Message:

<configuration>
  <appSettings>
    <add key="Message" value="Subpage"/>
  </appSettings>
</configuration>

Notice how the first file contains more configuration (represented by the three dots) and the configuration in the Web.config file in the Sub folder only contains the overwriting config.

To test that everything is working, replace the content of the Default.aspx file in the Sub folder with the following markup:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebApplication9.sub.Default" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<body>
    <h1>Hello from <%= ConfigurationManager.AppSettings["Message"] %></h1>
</body>
</html>

You already guessed it. When navigating to /sub/, the message is Hello from Subpage:

Hello from Subpage

Location element

Finally! This is why you came here in the first place, right? While having Web.config files spread across folders, sometimes it is just easier to configure everything in the same place. The location element lets us do exactly that. By specifying a location start and end tag inside the web application, we have a "mini" Web.config file included in the normal Web.config. Confused? Let's re-create the previous scenario, but with everything included in the same Web.config file:

<configuration>
  <appSettings>
    <add key="Message" value="Frontpage"/>
  </appSettings>
  <location path="Sub">
    <appSettings>
      <add key="Message" value="Subpage"/>
    </appSettings>
  </location>
  ...
</configuration>
If you are creating your own example, make sure to delete the Web.config file in the Sub folder.

Inside the location element, I've added a new appSettings element. In fact, the possible nested elements of location are the ones from the configuration element. This means you can add a system.webServer element or any other element allowed for a Web.config file inside location.

allowOverride

Besides the path attribute on the location element, there's another interesting attribute named allowOverride. With this attribute, you can lock the content of the location element. Let's create an example illustrating how this works.

You can combine the use of both the location element and a Web.config file in a subdirectory. ASP.NET will always use the configuration closest to the page you are requesting. In the scenario where we have appSettings specified in three different locations, when requesting /Sub/ IIS will look for configuration in the following order:

  1. In a Web.config file in the Sub folder.
  2. In a location element with path set to Sub in the Web.config file in the root folder.
  3. In the Web.config file in the root folder.

To test this, add the Web.config file from the first example to the Sub folder and replace the content with this:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <appSettings>
    <add key="Message" value="Web.config in Sub folder"/>
  </appSettings>
</configuration>

When running the application, you will see the new message:

Hello from Web.config in Sub folder

To lock the configuration in the Web.config file in the root directory, add allowOverride="false":

<configuration>
  <appSettings>
    <add key="Message" value="Frontpage"/>
  </appSettings>
  <location path="Sub" allowOverride="false">
    <appSettings>
      <add key="Message" value="Subpage"/>
    </appSettings>
  </location>
  ...
</configuration>

Launching the project will now cause an exception, since the Web.config file in the Sub folder is trying to override settings that it isn't allowed to:

Error when launching

Wildcard and regular expression

I've seen question after question, requesting the use of wildcards, regular expressions and similar in the path attribute of the location element. Like being able to target something like all sub-directories with a specific naming pattern:

<location path="languages/*">

I'm sorry to be the one to break it to you. It's not possible. The path attribute requires an absolute path to an existing file or directory.

elmah.io: Error logging and Uptime Monitoring for your web apps

This blog post is brought to you by elmah.io. elmah.io is error logging, uptime monitoring, deployment tracking, and service heartbeats for your .NET and JavaScript applications. Stop relying on your users to notify you when something is wrong or dig through hundreds of megabytes of log files spread across servers. With elmah.io, we store all of your log messages, notify you through popular channels like email, Slack, and Microsoft Teams, and help you fix errors fast.

See how we can help you monitor your website for crashes Monitor your website