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.
Hey Kev. This worked for me right away using your examples. Here's where I placed everything:
Path:
Content:
Path:
Content:
Path:
Content: