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.

Kev
  • 7,877
  • 18
  • 81
  • 108
  • thanks for the detailed post. Small question, is there a way to programmatically add `` to `applicationHost.config` without having to manually edit the file? I've tried `appcmd.exe set config ...` but I cant figure out the exact command – Amro May 20 '13 at 11:54
  • never mind, I just found the answer in your other post: http://stackoverflow.com/questions/5750213/edit-config-custom-section-in-iis . Another possibly useful script: http://troyparsons.com/blog/2012/10/managing-iis-configsections-via-script/ – Amro May 20 '13 at 12:27

1 Answers1

3

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>
Scott Forsyth
  • 16,449
  • 3
  • 37
  • 56
  • Thanks Scott. I've been beating my brains out over this one :) – Kev May 09 '11 at 18:17
  • Hi Scott, thanks for looking at this: I know, that was the easy bit and works just fine. But I when add `/configuration/configSections/sectionGroup` and `/configuration/configSections/sectionGroup/section` declarations to the `web.config` file so that .NET can parse my custom config XML this seems to break IIS Manager's Configuration Editor. I've re-jigged the question and added some more detail. – Kev May 09 '11 at 20:39
  • If I understand your description, I believe the issue is that the should only be in applicationHost.config and not anywhere else. Basically you need a) the schema in the schema folder, and b) the section declaration in applicationHost.config and then c) *only* the part in your site's web.config. – Scott Forsyth May 09 '11 at 23:29
  • Hi Scott....solved! I think the MS guidance on defining schema extensions that are also meant to be consumed by ASP.NET are a bit inacurate. See my update. – Kev May 10 '11 at 01:42
  • Excellent, glad you got a working solution. There isn't a chance that you have shared configuration enabled and that your applicationHost.config isn't from the %windir%\system32\inetsrv\config folder? It almost seems like your settings applied to that file aren't taking. You may need to do an iisreset after applying them too since they are picked up when the app pool is created. Your solution uses the config in the site's web.config, which is a good working solution too. – Scott Forsyth May 10 '11 at 02:09
  • No, shared config isn't enabled. In my original approach the schema settings *are* being picked up it's just that the IIS editor chokes. I think this problem is related to duplication of `
    ` or `` where the `name` attribute is like a unique key and that you can never have more than one in a fully resolved/merged configuration (i.e. way back from `machine.config` right through to the deepest possible child `web.config` including merging of settings from `applicationHost.config`).
    – Kev May 10 '11 at 08:52
  • Hence the `ASPNET_schema.xml` schema definitions using a path based notation in the `sectionSchema` name attribute which the configuration editor seems to treat in a special way (i.e. you don't need to explicitely declare the section in `applicationHost.config`) thus avoiding duplicate `
    ` key clashes. Or something like that. I'll dip into the `Microsoft.Web.Administration` code with reflector when time permits to confirm this.
    – Kev May 10 '11 at 08:57
  • Hey Kev. All of this worked for me first try using the components that you provided. Schema held the schema, nothing was placed in .NET config files, apphost held the section declaration (not the site's web.config) and the site's web.config held the actual setting. I had full conf manager support with that setup. My guess is that you may have had artifacts left over from early test that threw off your testing. You have a working solution now, which is the key part. But if you start fresh, it should work with the config that I confirmed. I placed section declaration within the existing one. – Scott Forsyth May 10 '11 at 15:52