Iis – ASP.NET custom configuration section declaration breaks IIS Manager Configuration Editor

configurationiisiis-7iis-7.5

I have a simple .NET custom configuration component that allows me to specify a custom configuration group and section in my ASP.NET 2.0 (the web project targets .NET Framework 3.5) web application's web.config file:

In my web.config I have the following declarations:

<configuration>

  <configSections>
    <sectionGroup 
      name="SimpleConfigGroup"
      type="CustomSettingsLib.SimpleConfigGroup, CustomSettingsLib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=7a58d3af5d6768c9">
      <section 
        name="SimpleConfigSection"
        type="CustomSettingsLib.SimpleConfigSection, CustomSettingsLib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=7a58d3af5d6768c9"/>
    </sectionGroup>
  </configSections>

  <SimpleConfigGroup>
    <SimpleConfigSection MySetting="Hello World" />
  </SimpleConfigGroup>

</configuration>

There are a couple of classes that provide access to this custom configuration section that reside in a class library project called CustomSettingsLib:

SimpleConfigGroup.cs:

using System.Configuration;
namespace CustomSettingsLib
{
  public class SimpleConfigGroup : ConfigurationSectionGroup
  {
    [ConfigurationProperty("SimpleConfigSection")]
    public SimpleConfigSection SimpleConfigSection
    {
      get { return (SimpleConfigSection)this.Sections["SimpleConfigSection"]; }
    }
  }
}

SimpleConfigSection.cs:

using System.Configuration;
namespace CustomSettingsLib
{
  public class SimpleConfigSection : ConfigurationSection
  {
    [ConfigurationProperty("MySetting", IsRequired = false)]
    public string MySetting
    {
      get { return (string)this["MySetting"]; }
    }
  }
}

The code to read the MySetting value looks like (Default.aspx.cs):

using System;
using System.Configuration;
using System.Web.Configuration;
using CustomSettingsLib;

namespace WebApplication4
{
  public partial class Default : System.Web.UI.Page
  {
    protected void Page_Load(object sender, EventArgs e)
    {
      Configuration config = WebConfigurationManager.OpenWebConfiguration("/");
      SimpleConfigGroup group = 
              config.GetSectionGroup("SimpleConfigGroup") as SimpleConfigGroup;
      SimpleConfigSection section = group.SimpleConfigSection;
      Response.Write(section.MySetting);
    }
  }
}

This works great and my web application can read the MySetting value from my web.config file.

Because these settings will be used in many web applications on Windows 2008 R2+IIS7.5 I then created an IIS Configuration Schema extension to allow this setting to be edited in IIS Manager's Configuration Editor feature rather than having to hand edit the web.config file.

I added an IIS configuration schema extension file to:

%systemroot%\system32\inetsrv\config\schema

<configSchema>
  <sectionSchema name="SimpleConfigGroup">
    <element name="SimpleConfigSection">
      <attribute name="MySetting" 
                 type="string" 
                 validationType="nonEmptyString" />
    </element>
  </sectionSchema>
</configSchema>

I then added the following section definition to IIS's applicationHost.config file in the <configSections> element:

<section name="SimpleConfigGroup" 
         overrideModeDefault="Allow" 
         allowDefinition="Everywhere" />

The problem I am having is that when I open IIS Manager's Configuration Editor for the site:

enter image description here

Then select SimpleConfigGroup from the section drop down list it reports the following vague error:

"There was an error while performing
this operation."
Details:
Filename:
\?\e:\sites\site1\web.config
Error:

Here is a screen shot of this error:

enter image description here

If I remove the .NET <sectionGroup> declaration from the site's web.config file I can edit the custom setting just fine using IIS Manager's Configuration Editor. However my web application can't run because the <sectionGroup> config info is required for the custom config section and for .NET to be able to parse the web.config file.

I've tried adding the <sectionGroup> to the root machine.config (and even dropping the configuration assembly into the .NET 2.0 framework assemblies folder) but I get the same error. I also tried signing the configuration assembly thinking there may be a trust issue but that hasn't helped either.

What I find strange is that the usual .NET Framework <configSections> in machine.config don't upset the IIS Manager Configuration Manager, nor do the .NET 3.5 System.Web.Extensions <sectionGroup> definitions in an ASP.NET 2.0 site, e.g. for system.web yet my custom config sections do.

Why is this? Is it a bug in the IIS Manager Configuration Editor?

Update:

Based on Scott's suggestion I added the following to my applicationHost.config file (leaving the sectionGroup/section declaration in the web.config file:

<sectionGroup name="SimpleConfigGroup">
  <section name="SimpleConfigSection" 
           allowDefinition="Everywhere" 
           overrideModeDefault="Allow" />
</sectionGroup>

This generates the following error which is understandable because it's already defined in the web.config file:

enter image description here


I tried removing the sectionGroup/section declaration from the web.config but keeping the above sectionGroup declaration in applicationHost. IIS Manager's Configuration editor no longer lists the SimpleConfigGroup section.


I then tried this in applicationHost.config:

<section 
    name="SimpleConfigGroup" 
    allowDefinition="Everywhere" 
    overrideModeDefault="Allow" 
    type="CustomSettingsLib.SimpleConfigGroup, CustomSettingsLib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=7a58d3af5d6768c9"/>

IIS Manager's Configuration Settings editor can now see the section again without error, but because there is no section declaration in web.config the ASP.NET app throws an " Unrecognized configuration section" exception.


I also tried this in applicationHost.config:

<sectionGroup 
   name="SimpleConfigGroup" 
   type="CustomSettingsLib.SimpleConfigGroup, CustomSettingsLib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=7a58d3af5d6768c9">
  <section 
    name="SimpleConfigSection" 
    overrideModeDefault="Allow" 
    allowDefinition="Everywhere"
    type="CustomSettingsLib.SimpleConfigSection, CustomSettingsLib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=7a58d3af5d6768c9"/>
</sectionGroup>

Again, no dice, ASP.NET throws an " Unrecognized configuration section" exception and IIS Manager's Configuration Editor no longer lists the SimpleConfigGroup section.


Progress:

I reverted to first base and re-instated the web.config config section declaration so that the ASP.NET application could read the custom config values. I deleted the customer schema file from the IIS schema folder and reverted applicationHost.config's configSections section back to factory settings.

One of the things I found interesting is that IIS Manager's configuration editor exposes the system.web settings and whilst there is a schema file for this (ASPNET_schema.xml) the schema sections aren't actually referenced in the applicationHost.config file. This leads me to belief that these files or the sectionSchema names are being handled in a special way.

To this end I unlocked the ASPNET_schema.xml file and added my schema definition:

<sectionSchema name="SimpleConfigGroup">
  <element name="SimpleConfigSection">
    <attribute name="MySetting" 
                     type="string" 
                     validationType="nonEmptyString" />
  </element>
</sectionSchema>

This didn't work and SimpleConfigGroup wasn't visible in IIS Manager's Configuration Editor. But no errors were thrown and the ASP.NET app could still read it's custom config values.

I then tried following the conventions used in the ASPNET_schema.xml schema file and added this instead:

<sectionSchema name="SimpleConfigGroup/SimpleConfigSection">
  <attribute name="MySetting" 
             type="string" 
             validationType="nonEmptyString" />
</sectionSchema>

This actually worked!:

enter image description here

The ASP.NET application continues to function and can read the custom config section AND I can edit the custom config section MySetting value in IIS Manager's Configuration Editor.

I then rolled ASPNET_schema.xml back to factory settings and tried recreating the custom SimpleConfigSchema.xml file in IIS's schema folder using the same definition and this works as well.

This is also without adding a reference to the config section in applicationHost.config.

I'm coming to the conclusion that the guidance on extending the schema where both IIS Manager's config editor AND ASP.NET need to consume the same section is slightly bogus.

Best Answer

Hey Kev. This worked for me right away using your examples. Here's where I placed everything:

Path:

%systemroot%\system32\inetsrv\config\schema\simpleconfig.xml

Content:

<configSchema>
  <sectionSchema name="SimpleConfigGroup">
    <element name="SimpleConfigSection">
      <attribute name="MySetting" 
                 type="string" 
                 validationType="nonEmptyString" />
    </element>
  </sectionSchema>
</configSchema>

Path:

%systemroot%\system32\inetsrv\config\applicationHost.config (in <configSections> element).

Content:

<section name="SimpleConfigGroup" 
         overrideModeDefault="Allow" 
         allowDefinition="Everywhere" />

Path:

Site's web.config

Content:

  <SimpleConfigGroup>
    <SimpleConfigSection MySetting="Hello World" />
  </SimpleConfigGroup>