Thursday, March 3, 2011

App.config - custom section not working.

I recently started building a console version of a web application. I copied my custom sections from my web.config. to my app.config. When I go to get config information i get this error:

An error occurred creating the configuration section handler for x/y: Could not load type 'x' from assembly 'System.Configuration

The line that it is not liking is:

return ConfigurationManager.GetSection("X/Y") as Z;

Anyone run into something like this?

I was able to add

<add key="IsReadable" value="0"/>

in the appSettings and read it.

Addition:

I do actually have this defined about the custom section:

  <configSections>
    <sectionGroup name="x">
      <section name="y" type="zzzzz"/>
    </sectionGroup>

  </configSections>
From stackoverflow
  • it sounds like your config-section handler is not defined

    <configSection>
        <section
                name="YOUR_CLASS_NAME_HERE"
                type="YOUR.NAMESPACE.CLASSNAME, YOUR.NAMESPACE, Version=1.1.0.0, Culture=neutral, PublicKeyToken=PUBLIC_TOKEN_ID_FROM_ASSEMBLY"
                allowLocation="true"
                allowDefinition="Everywhere"
              />
    </configSection>
    
    Brian G : How much of that type section is required?
    Daok : You do not require Culture and PublicKey to solve your problem. Check my short version below.
    Steven A. Lowe : @Daok: I was just following orders! ;-)
  • If you want a custom config handler you have to define the class and reference it as shown by Steven Lowe. You can inherit from predefined handlers, or you can just use the value/key pair that is offered in appSetting section as you noted.

  • At the top of your file you require to have configSection tag with inside the section.

    You can have sectionGroup too. Example:

    <configuration>
       <configSections>
         <sectionGroup name="x">
           <section name="y" type="a, b"/>
         </sectionGroup>
        <configSections>
    </configuration>
    
  • This class works as a general custom configuration section handler for any type...

    public class XmlConfigurator : IConfigurationSectionHandler
        {
            public object Create(object parent, object configContext, XmlNode section)
            {
                if (section == null) return null;
                Type sectionType = Type.GetType((string)(section.CreateNavigator()).Evaluate("string(@configType)"));
                XmlSerializer xs = new XmlSerializer(sectionType);
                return xs.Deserialize(new XmlNodeReader(section));
            }
        }
    

    In your app.config, add

      <section name="NameofConfigSection"  type="NameSpace.XmlConfigurator, NameSpace.Assembly"/>
    

    And in the configuration section element, add an attribute to specify the type you want the root element deserialized into..

    <?xml version="1.0" encoding="utf-8" ?>
    
    <NameofConfigSection configType="NameSpace.NameofTypeToDeserializeInto, Namespace.Assembly" >
    
     ... 
    
    </NameofConfigSection>
    
    emddudley : IConfigurationSectionHandler is deprecated in .NET 2.0 and above. Inherit from ConfigurationSection instead.
    Charles Bretana : But, as far as I can see, you can't duplicate the functionality that the code above provides (that is, being able to deserialize ANY configuration secrion with the same 'universal' handler) using the newer methodology... Using ConfigurationSection, you have to write a new and diffe5rent derived class for each new configuration section you want to deserialize...
  • I had this identical issue recently. I created a custom sectiongroup for a web application(ran just fine), but when I ported this layer to a console app, the sectiongroup was failing.

    You were correct in your question regarding how much of the "type" is required in your section definition. I've modified your configuration section with an example below:

    <configSection>
        <section
            name="yourClassName"
            type="your.namespace.className, your.assembly"
            allowLocation="true"
            allowDefinition="Everywhere" />
    </configSection>
    

    You'll notice, the type now has class name followed by assembly name. This is required for interaction outside of a web environment.

    NOTE: Assembly name does not necessarily equal your namespace(for a given section).

0 comments:

Post a Comment