70

我开发的 Web 应用程序通常需要相互依赖的配置设置,并且当我们在每个环境之间移动时,也有一些设置必须更改。

我们所有的设置目前都是简单的键值对,但创建自定义配置部分会很有用,这样当两个值需要一起更改或需要为环境更改设置时,它会很明显。

创建自定义配置部分的最佳方法是什么?在检索值时是否有任何特殊注意事项?

4

6 回答 6

84

使用属性、子配置部分和约束

还有可能使用自动处理管道的属性,以及提供轻松添加约束的能力。

我在这里提供一个示例,来自我自己在我的一个站点中使用的代码。有一个限制,我规定了任何一个用户可以使用的最大磁盘空间量。

MailCenterConfiguration.cs:

namespace Ani {

    public sealed class MailCenterConfiguration : ConfigurationSection
    {
        [ConfigurationProperty("userDiskSpace", IsRequired = true)]
        [IntegerValidator(MinValue = 0, MaxValue = 1000000)]
        public int UserDiskSpace
        {
            get { return (int)base["userDiskSpace"]; }
            set { base["userDiskSpace"] = value; }
        }
    }
}

这是在 web.config 中设置的,如下所示

<configSections>
    <!-- Mailcenter configuration file -->
    <section name="mailCenter" type="Ani.MailCenterConfiguration" requirePermission="false"/>
</configSections>
...
<mailCenter userDiskSpace="25000">
    <mail
     host="my.hostname.com"
     port="366" />
</mailCenter>

子元素

子 xml 元素mail在与上述相同的 .cs 文件中创建。在这里,我在端口上添加了约束。如果端口分配的值不在此范围内,则运行时将在加载配置时报错。

MailCenterConfiguration.cs:

public sealed class MailCenterConfiguration : ConfigurationSection
{
    [ConfigurationProperty("mail", IsRequired=true)]
    public MailElement Mail
    {
        get { return (MailElement)base["mail"]; }
        set { base["mail"] = value; }
    }

    public class MailElement : ConfigurationElement
    {
        [ConfigurationProperty("host", IsRequired = true)]
        public string Host
        {
            get { return (string)base["host"]; }
            set { base["host"] = value; }
        }

        [ConfigurationProperty("port", IsRequired = true)]
        [IntegerValidator(MinValue = 0, MaxValue = 65535)]
        public int Port
        {
            get { return (int)base["port"]; }
            set { base["port"] = value; }
        }

采用

然后要在代码中实际使用它,您所要做的就是实例化 MailCenterConfigurationObject,这将自动从 web.config 中读取相关部分。

邮件中心配置.cs

private static MailCenterConfiguration instance = null;
public static MailCenterConfiguration Instance
{
    get
    {
        if (instance == null)
        {
            instance = (MailCenterConfiguration)WebConfigurationManager.GetSection("mailCenter");
        }

        return instance;
    }
}

另一个文件.cs

public void SendMail()
{
    MailCenterConfiguration conf = MailCenterConfiguration.Instance;
    SmtpClient smtpClient = new SmtpClient(conf.Mail.Host, conf.Mail.Port);
}

检查有效性

我之前提到过,当加载配置并且某些数据不符合您设置的规则(例如在 MailCenterConfiguration.cs 中)时,运行时会抱怨。当我的网站启动时,我倾向于尽快了解这些事情。解决此问题的一种方法是在 _Global.asax.cx.Application_Start_ 中加载配置,如果配置无效,您将收到异常通知。您的站点不会启动,而是会在黄屏死机中显示详细的异常信息。

全球.asax.cs

protected void Application_ Start(object sender, EventArgs e)
{
    MailCenterConfiguration.Instance;
}
于 2008-08-05T22:17:29.610 回答
13

Quick'n 脏:

首先创建您的ConfigurationSectionConfigurationElement类:

public class MyStuffSection : ConfigurationSection
{
    ConfigurationProperty _MyStuffElement;

    public MyStuffSection()
    {
        _MyStuffElement = new ConfigurationProperty("MyStuff", typeof(MyStuffElement), null);

        this.Properties.Add(_MyStuffElement);
    }

    public MyStuffElement MyStuff
    {
        get
        {
            return this[_MyStuffElement] as MyStuffElement;
        }
    }
}

public class MyStuffElement : ConfigurationElement
{
    ConfigurationProperty _SomeStuff;

    public MyStuffElement()
    {
        _SomeStuff = new ConfigurationProperty("SomeStuff", typeof(string), "<UNDEFINED>");

        this.Properties.Add(_SomeStuff);
    }

    public string SomeStuff
    {
        get
        {
            return (String)this[_SomeStuff];
        }
    }
}

然后让框架知道如何处理web.config中的配置类:

<configuration>
  <configSections>
    <section name="MyStuffSection" type="MyWeb.Configuration.MyStuffSection" />
  </configSections>
  ...

实际上在下面添加您自己的部分:

  <MyStuffSection>
    <MyStuff SomeStuff="Hey There!" />
  </MyStuffSection>

然后你可以在你的代码中使用它:

MyWeb.Configuration.MyStuffSection configSection = ConfigurationManager.GetSection("MyStuffSection") as MyWeb.Configuration.MyStuffSection;

if (configSection != null && configSection.MyStuff != null)
{
    Response.Write(configSection.MyStuff.SomeStuff);
}
于 2008-08-05T12:51:16.430 回答
5

在 MSDN 上有一个很好的示例,它使用ConfigurationCollection和 .NET 4.5 用于 web.config 中的自定义部分,其中包含配置项列表。

于 2013-09-19T15:39:43.160 回答
4

自定义配置是非常方便的事情,并且通常应用程序最终需要可扩展的解决方案。

对于 .NET 1.1,请参阅文章http://aspnet.4guysfromrolla.com/articles/020707-1.aspx

注意:上述解决方案也适用于 .NET 2.0。

.NET 2.0 具体解决方案请参考文章http://aspnet.4guysfromrolla.com/articles/032807-1.aspx

于 2009-02-13T13:45:37.817 回答
3

您可以使用部分处理程序来完成此操作。在http://www.codeproject.com/KB/aspnet/ConfigSections.aspx有一个关于如何编写的基本概述,但是它指的是 app.config,这与编写一个用于 web 的几乎相同。配置。这将允许您在配置文件中拥有自己的 XML 树并进行一些更高级的配置。

于 2008-08-05T12:25:20.850 回答
2

我发现最简单的方法是使用appSettings section

  1. 将以下内容添加到 Web.config:

    <appSettings>
        <add key="MyProp" value="MyVal"/>
    </appSettings>
    

  2. 从您的代码访问

    NameValueCollection appSettings = ConfigurationManager.AppSettings;
    string myPropVal = appSettings["MyProp"];
    

于 2017-02-04T17:59:32.160 回答