题
我开发的 Web 应用程序通常需要相互依赖的配置设置,并且当我们在每个环境之间移动时,还必须更改一些设置。
目前我们所有的设置都是简单的键值对,但创建自定义配置部分会很有用,这样当两个值需要一起更改或当设置需要针对环境进行更改时就很明显。
创建自定义配置部分的最佳方法是什么?检索值时是否有任何特殊注意事项?
解决方案
使用属性、子配置部分和约束
还可以使用自动处理管道的属性,并提供轻松添加约束的能力。
我在这里展示了一个来自我自己在我的一个网站中使用的代码的示例。在限制条件下,我规定了任何一个用户可以使用的最大磁盘空间量。
邮件中心配置.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 元素 邮件 与上面的文件在同一个 .cs 文件中创建。这里我添加了对端口的限制。如果为端口分配的值不在此范围内,则加载配置时运行时将发出错误消息。
邮件中心配置.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;
}
}
AnotherFile.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;
}
其他提示
又快又脏:
首先创建你的 配置部分 和 配置元素 课程:
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];
}
}
}
然后让框架知道如何处理你的配置类 网络配置:
<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);
}
有一个优秀的 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.config 的应用程序几乎相同。这将允许您在配置文件中拥有自己的 XML 树并进行一些更高级的配置。
我发现最简单的方法是使用 应用程序设置部分.
将以下内容添加到 Web.config:
<appSettings> <add key="MyProp" value="MyVal"/> </appSettings>
从您的代码访问
NameValueCollection appSettings = ConfigurationManager.AppSettings; string myPropVal = appSettings["MyProp"];