Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom App.config section causing configuration load error

I am using a custom configuration section in my app.config file to automatically email certain administrators when an error in the application occurs based on Jan Remunda's post here: How to create custom config section in app.config?

App.config:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
  </startup>

  <configSections>
    <section name="ErrorEmailer" type="EmailTester.ErrorEmailer" />
  </configSections>

  <ErrorEmailer>
    <SmtpServer address="mail.smtphost.com" />
    <FromAddress address="[email protected]" />
    <ErrorRecipients>
      <ErrorRecipient address="[email protected]" />
      <ErrorRecipient address="[email protected]" />
    </ErrorRecipients>
  </ErrorEmailer>
</configuration>

And I have added these configuration elements:

public class ErrorRecipient : ConfigurationElement
{
    [ConfigurationProperty("address", IsRequired = true)]
    public string Address
    {
        get
        {
            return this["address"] as string;
        }
    }
}

public class SmtpServer : ConfigurationElement
{
    [ConfigurationProperty("address", IsRequired = true)]
    public string Address
    {
        get
        {
            return this["address"] as string;
        }
    }
}

public class FromAddress : ConfigurationElement
{
    [ConfigurationProperty("address", IsRequired = true)]
    public string Address
    {
        get
        {
            return this["address"] as string;
        }
    }
}

This Configuration Element Collection:

public class ErrorRecipients : ConfigurationElementCollection
{
    public ErrorRecipient this[int index]
    {
        get
        {
            return base.BaseGet(index) as ErrorRecipient;
        }
        set
        {
            if (base.BaseGet(index) != null)
            {
                base.BaseRemoveAt(index);
            }
            this.BaseAdd(index, value);
        }
    }

    public new ErrorRecipient this[string responseString]
    {
        get { return (ErrorRecipient)BaseGet(responseString); }
        set
        {
            if (BaseGet(responseString) != null)
            {
                BaseRemoveAt(BaseIndexOf(BaseGet(responseString)));
            }
            BaseAdd(value);
        }
    }

    protected override ConfigurationElement CreateNewElement()
    {
        return new ErrorRecipient();
    }

    protected override object GetElementKey(ConfigurationElement element)
    {
        return ((ErrorRecipient)element).Address;
    }
}

And this Configuration Section:

public class ErrorEmailer : ConfigurationSection
{

    public static ErrorEmailer GetConfig()
    {
        return (ErrorEmailer)System.Configuration.ConfigurationManager.GetSection("ErrorEmailer") ?? new ErrorEmailer();
    }

    [ConfigurationProperty("ErrorRecipients")]
    [ConfigurationCollection(typeof(ErrorRecipients), AddItemName = "ErrorRecipient")]
    public ErrorRecipients ErrorRecipients
    {
        get
        {
            object o = this["ErrorRecipients"];
            return o as ErrorRecipients;
        }
    }

    [ConfigurationProperty("SmtpServer")]
    public SmtpServer SmtpServer
    {
        get
        {
            object o = this["SmtpServer"];
            return o as SmtpServer;
        }
    }

    [ConfigurationProperty("FromAddress")]
    public FromAddress FromAddress
    {
        get
        {
            object o = this["FromAddress"];
            return o as FromAddress;
        }
    }
}

But I get a "Configuration system failed to initialize" error when running the program and trying to run this:

var config = ErrorEmailer.GetConfig();
Console.WriteLine(config.SmtpServer.Address);
like image 297
jokulmorder Avatar asked Dec 20 '22 00:12

jokulmorder


1 Answers

The configSections element must be the first child of the configuration element. Try this:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="ErrorEmailer" type="EmailTester.ErrorEmailer" />
  </configSections>
  <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
  </startup>
  <ErrorEmailer>
    <SmtpServer address="mail.smtphost.com" />
    <FromAddress address="[email protected]" />
    <ErrorRecipients>
      <ErrorRecipient address="[email protected]" />
      <ErrorRecipient address="[email protected]" />
    </ErrorRecipients>
  </ErrorEmailer>
</configuration>

Furthermore, you need to put the namespace and assembly of your custom config section type in your section element. Take this:

<section name="ErrorEmailer" type="EmailTester.ErrorEmailer" />

and add the assembly like this:

<section name="ErrorEmailer"
         type="EmailTester.ErrorEmailer, My.Containing.Assembly.Goes.Here" />

If you don't qualify the namespace path of your config type with the assembly it is contained in, .NET assumes you mean the System.Configuration assembly.

like image 76
Timothy Shields Avatar answered Apr 20 '23 00:04

Timothy Shields