Web.config location element demystified

thomasardal

Thomas Ardal

Posted on November 18, 2020

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.

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:

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:

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>
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

You already guessed it. When navigating to /sub/, the message is 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>
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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

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>
Enter fullscreen mode Exit fullscreen mode

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:

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/*">
Enter fullscreen mode Exit fullscreen mode

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.

Would your users appreciate fewer errors?

elmah.io is the easy error logging and uptime monitoring service for .NET. Take back control of your errors with support for all .NET web and logging frameworks.

➡️ Error Monitoring for .NET Web Applications ⬅️

This article first appeared on the elmah.io blog at https://blog.elmah.io/web-config-location-element-demystified/

💖 💪 🙅 🚩
thomasardal
Thomas Ardal

Posted on November 18, 2020

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related