ASP.NET custom configuration section declaration breaks IIS Manager Configuration Editor
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:
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:
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:
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!:
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.
Solution 1:
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>