前几天由于公司的业务需求,某个系统需要设置一些配置参数,将这些参数保存在数据库显得过于的复杂,并且系统频繁的读取配置信息不合适,不便于以后的管理,显然保存在配置文件中是最好的方式了。后面需要对这些配置信息进行修改管理,管理员当然不希望参数每次去变时去直接修改网站根目录下的Web.config文件,要是能够另外的保存一个文件,并且其它的网站能够同时访问这个文件,直接进行修改就最好了。
好了我们根据这个具体的实际需求来进行下面的步骤:
一、将网站的配置信息保存到单独配置文件
我们的配置信息一般保存在网站根目录下的Web.config文件的appSettings中,这里我们将其中的公共配置信息取出来,保存在另外一个单独的文件里面 。
在网站下新建一个文件夹Configs,添加一个配置文件AIsys.config ,在这里的配置文件中添加配置信息
<?xml version="1.0" encoding="utf-8"?>
<AISettings>
<add key="timeout" value="5"/>
<add key="maxnum" value="10"/>
<add key="minnum" value="3"/>
<add key="enabled" value="true"/>
</AISettings>
二、创建减值对应的类AIKeyValueElement和元素集合类AIKeyValueElementCollection
using System;
using System.Configuration;
namespace ApplicationModel.ConfigModel
{
/// <summary>
/// 键值对应类
/// </summary>
public class AIKeyValueElement : ConfigurationElement
{
/// <summary>
/// key
/// </summary>
[ConfigurationProperty("key", IsRequired = true)]
public string Key
{
get { return this["key"].ToString(); }
set { this["key"] = value; }
}
/// <summary>
/// value
/// </summary>
[ConfigurationProperty("value")]
public string Value
{
get { return this["value"].ToString(); }
set { this["value"] = value; }
}
}
[ConfigurationCollection(typeof(AIKeyValueElement))]
public class AIKeyValueElementCollection : ConfigurationElementCollection
{
public AIKeyValueElementCollection() : base(StringComparer.OrdinalIgnoreCase) { }
/// <summary>
/// 集合中指定键的元素
/// </summary>
new public AIKeyValueElement this[string name]
{
get { return (AIKeyValueElement)base.BaseGet(name); }
set
{
if (base.Properties.Contains(name)) base[name] = value;
else base.BaseAdd(value);
}
}
/// <summary>
/// 创建新元素(重写)
/// </summary>
protected override ConfigurationElement CreateNewElement()
{
return new AIKeyValueElement();
}
/// <summary>
/// 获取元素的键
/// </summary>
protected override object GetElementKey(ConfigurationElement element)
{
return ((AIKeyValueElement)element).Key;
}
}
}
三、创建和你的单独配置文件相对应的配置类
using System.Configuration;
namespace ApplicationModel.ConfigModel
{
public class AIsysConfig : ConfigurationSection
{
private static ConfigurationProperty _property = new ConfigurationProperty(string.Empty, typeof(AIKeyValueElementCollection), null, ConfigurationPropertyOptions.IsDefaultCollection);
/// <summary>
/// 配置列表
/// </summary>
[ConfigurationProperty("", Options = ConfigurationPropertyOptions.IsDefaultCollection)]
private AIKeyValueElementCollection KeyValues
{
get { return (AIKeyValueElementCollection)base[_property]; }
set { base[_property] = value; }
}
/// <summary>
/// 最大点
/// </summary>
public int maxnum
{
get
{
int _value = 0;
if (KeyValues["maxnum"] != null) int.TryParse(KeyValues["maxnum"].Value, out _value);
return _value;
}
set
{
if (KeyValues["maxnum"] == null) KeyValues["highNum"] = new AIKeyValueElement() { Key = "maxnum", Value = value.ToString() };
else KeyValues["maxnum"].Value = value.ToString();
}
}
/// <summary>
/// 最小点
/// </summary>
public int minnum
{
get
{
int _value = 0;
if (KeyValues["minnum"] != null) int.TryParse(KeyValues["minnum"].Value, out _value);
return _value;
}
set
{
if (KeyValues["minnum"] == null) KeyValues["minnum"] = new AIKeyValueElement() { Key = "minnum", Value = value.ToString() };
else KeyValues["minnum"].Value = value.ToString();
}
}
/// <summary>
/// 是否开启
/// </summary>
public bool enabled
{
get
{
bool _value = true;
if (KeyValues["enabled"] != null) bool.TryParse(KeyValues["enabled"].Value, out _value);
return _value;
}
set
{
if (KeyValues["enabled"] == null) KeyValues["enabled"] = new AIKeyValueElement() { Key = "enabled", Value = value.ToString() };
else KeyValues["enabled"].Value = value.ToString();
}
}
/// <summary>
/// 超时时间
/// </summary>
public double timeout
{
get
{
double _value = 0;
if (KeyValues["timeout"] != null) double.TryParse(KeyValues["timeout"].Value, out _value);
return _value;
}
set
{
if (KeyValues["timeout"] == null) KeyValues["timeout"] = new AIKeyValueElement() { Key = "timeout", Value = value.ToString() };
else KeyValues["timeout"].Value = value.ToString();
}
}
}
}
四、配置Web.config
修改Web.config中的配置节加入配置信息,并且设置配置路径
<configuration>
<configSections>
<section name="AISettings" type="ApplicationModel.ConfigModel.AIsysConfig, ApplicationModel"/>
</configSections>
.
.
.
<AISettings configSource="Configs\AIsys.config" />
</configuration>
五、读取配置信息
public ActionResult Index()
{
var config = WebConfigurationManager.OpenWebConfiguration("~");
var aisysConfig = config.GetSection("AISettings") as ApplicationModel.ConfigModel.AIsysConfig;
return Json(new
{
TimeOut = aisysConfig.timeout,
MaxNum = aisysConfig.maxnum,
MinNum = aisysConfig.minnum,
Enabled = aisysConfig.enabled
}, JsonRequestBehavior.AllowGet);
}
测试返回的结果正常
{"TimeOut":5,"MaxNum":10,"MinNum":3,"Enabled":true}
六、写入配置信息
public ActionResult Write()
{
var config = WebConfigurationManager.OpenWebConfiguration("~");
var aisysConfig = config.GetSection("AISettings") as ApplicationModel.ConfigModel.AIsysConfig;
aisysConfig.timeout = 6;
aisysConfig.maxnum = 20;
aisysConfig.minnum = 1;
aisysConfig.enabled = false;
config.Save();
return Index();
}
测试返回的结果正常。并且配置信息已修改
{"TimeOut":6,"MaxNum":20,"MinNum":1,"Enabled":false}
七、其它网站配置相同的config文件进行管理
根据前面的业务需求,需要的是另外一个站点对config文件进行管理,这里我们另外新建一个网站,但是config文件得用同一个,最开始想到的是在IIS中使用虚拟路径,将前面的网站的配置路径信息加进来,如下图所示
虚拟路径配置好之后进行测试,发现会报错,在处理向该请求提供服务所需的配置文件时出错。请检查下面的特定错误详细信息并适当地修改配置文件。
后面发现配置IIS虚拟路径不行,必须要将文件夹做一个映射到WebApplicationB站点
这里我们使用一个junction工具进行一个文件夹的映射,可以参考我的博客对于Windows下NTFS连接点管理工具-junction工具说明
这里我们用一条命令在WebApplicationB站点创建一个文件夹对应WebApplicationA
junction F:\ConfigTestSolution\WebApplicationB\Configs "F:\ConfigTestSolution\WebApplicationA\Configs"
八、修改配置文件之后的站点重启问题
如果在实际使用过程中,可以会发现Configs文件夹下面的配置文件修改会导致站点重启,解决这一问题,在Web.config中加入restartOnExternalChanges="false" 即可
<section name="AISettings" restartOnExternalChanges="false" type="ApplicationModel.ConfigModel.AIsysConfig, ApplicationModel"/>
参考文章:http://www.cnblogs.com/mzwhj/p/3589887.html