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

7,145

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>
Share:
7,145

Related videos on Youtube

Kev
Author by

Kev

###Actively looking for freelance work ###About Me: I'm a professional software developer and have spent my time building provisioning and web based self-service systems for IIS, Apache and Citrix XenServer, amongst other things. My Curriculum Vitae can be viewed on Stack Overflow Careers (might be a bit out of date). Stuff I like to listen to at last.fm You can get in touch here: kevin.e.kenny #@# gmail.com (you know what to do with the # and spaces). No Survey Emails Please. Also not ashamed to admit I like trains, mostly diesels, late Era 8 (BR Sectorisation) and Era 9 onwards :) I'm also interested in signalling if anyone from Network Rail is looking this far down ;)

Updated on September 18, 2022

Comments

  • Kev
    Kev over 1 year

    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.

    • Amro
      Amro almost 11 years
      thanks for the detailed post. Small question, is there a way to programmatically add <configSection> 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
      Amro almost 11 years
      never mind, I just found the answer in your other post: stackoverflow.com/questions/5750213/… . Another possibly useful script: troyparsons.com/blog/2012/10/…
  • Kev
    Kev about 13 years
    Thanks Scott. I've been beating my brains out over this one :)
  • Kev
    Kev about 13 years
    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.
  • Scott Forsyth
    Scott Forsyth about 13 years
    If I understand your description, I believe the issue is that the <configSection> 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 <SimpleConfigGroup> part in your site's web.config.
  • Kev
    Kev about 13 years
    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.
  • Scott Forsyth
    Scott Forsyth about 13 years
    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.
  • Kev
    Kev about 13 years
    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 <section> or <sectionGroup> 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
    Kev about 13 years
    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 <section name="..."> key clashes. Or something like that. I'll dip into the Microsoft.Web.Administration code with reflector when time permits to confirm this.
  • Scott Forsyth
    Scott Forsyth almost 13 years
    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.