c# - 导致配置加载错误的自定义 App.config 部分

标签 c# .net app-config

我在我的 app.config 文件中使用自定义配置部分,根据 Jan Remunda 在这里的帖子:How to create custom config section in 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="from@host.com" />
    <ErrorRecipients>
      <ErrorRecipient address="example@example.com" />
      <ErrorRecipient address="example@example.com" />
    </ErrorRecipients>
  </ErrorEmailer>
</configuration>

我添加了这些配置元素:

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;
        }
    }
}

此配置元素集合:

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;
    }
}

还有这个配置部分:

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;
        }
    }
}

但是在运行程序并尝试运行此程序时出现“配置系统无法初始化”错误:

var config = ErrorEmailer.GetConfig();
Console.WriteLine(config.SmtpServer.Address);

最佳答案

configSections 元素必须是 configuration 元素的第一个子元素。试试这个:

<?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="from@host.com" />
    <ErrorRecipients>
      <ErrorRecipient address="example@example.com" />
      <ErrorRecipient address="example@example.com" />
    </ErrorRecipients>
  </ErrorEmailer>
</configuration>

此外,您需要将自定义配置节类型的命名空间和程序集放在您的元素中。拿这个:

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

并像这样添加程序集:

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

如果您没有使用配置类型所在的程序集来限定命名空间路径,.NET 会假定您指的是 System.Configuration 程序集。

关于c# - 导致配置加载错误的自定义 App.config 部分,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18598432/

相关文章:

javascript - 如何在链接按钮中使用<%= %>?

c# - DictionarySectionHandler 和 NameValueSectionHandler 之间有区别吗?

c# - 为什么另一个应用程序窗口标题中的文本不正确?

c# - 带有 GridSplitter 的 WPF 扩展器

c# - 从 C# Web 应用程序登录 SQL Server 失败

.net:System.Web.Mail 与 System.Net.Mail

.net - 如何为 .NET 控制台应用程序设置配置文件?

java - 如何使 Spring 将值注入(inject)静态字段

c# - DirectoryServices.DirectoryEntry 组调用 ("remove") 和属性 ["member"].remove 之间的差异

c# - 可以传入通用实体并访问公共(public)属性吗?