关于asp.net:如何定义带有潜在子元素和属性的自定义web.config部分?

关于asp.net:如何定义带有潜在子元素和属性的自定义web.config部分?

How do I define custom web.config sections with potential child elements and attributes for the properties?

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

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

创建自定义配置节的最佳方法是什么?检索值时有什么特殊注意事项吗?


使用属性,子配置节和约束

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

我在这里展示一个示例代码,该代码示例是我在一个站点中使用自己的代码。有一个约束,我决定允许任何一个用户使用的最大磁盘空间量。

MailCenterConfiguration.cs:

1
2
3
4
5
6
7
8
9
10
11
12
13
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中进行设置

1
2
3
4
5
6
7
8
9
10
<configSections>
    <!-- Mailcenter configuration file -->
    <section name="mailCenter" type="Ani.MailCenterConfiguration" requirePermission="false"/>
</configSections>
...
<mailCenter userDiskSpace="25000">
    <mail
     host="my.hostname.com"
     port="366" />
</mailCenter>

子元素

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

MailCenterConfiguration.cs:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
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中读取相关部分。

MailCenterConfiguration.cs

1
2
3
4
5
6
7
8
9
10
11
12
13
private static MailCenterConfiguration instance = null;
public static MailCenterConfiguration Instance
{
    get
    {
        if (instance == null)
        {
            instance = (MailCenterConfiguration)WebConfigurationManager.GetSection("mailCenter");
        }

        return instance;
    }
}

AnotherFile.cs

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

检查有效性

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

Global.asax.cs

1
2
3
4
protected void Application_ Start(object sender, EventArgs e)
{
    MailCenterConfiguration.Instance;
}

快速\\'n肮脏:

首先创建您的ConfigurationSection和ConfigurationElement类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
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中处理您的配置类:

1
2
3
4
5
<configuration>
  <configSections>
    <section name="MyStuffSection" type="MyWeb.Configuration.MyStuffSection" />
  </configSections>
  ...

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

1
2
3
  <MyStuffSection>
    <MyStuff SomeStuff="Hey There!" />
  </MyStuffSection>

然后您可以在代码中使用它,如下所示:

1
2
3
4
5
6
MyWeb.Configuration.MyStuffSection configSection = ConfigurationManager.GetSection("MyStuffSection") as MyWeb.Configuration.MyStuffSection;

if (configSection != null && configSection.MyStuff != null)
{
    Response.Write(configSection.MyStuff.SomeStuff);
}

在MSDN上有一个很好的示例,它使用ConfigurationCollection和.NET 4.5在web.config中的自定义节中列出了配置项列表。


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

对于.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


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


我发现的最简单的方法是使用appSettings部分。

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

    1
    </appSettings>

  • 通过您的代码进行访问

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


  • 推荐阅读