在ASP.NET2.0里不但进一步扩展了配置文件web.config,更为重要的是系统提供了一组API函数,让我们可以以编程的方式从配置文件里提取信息
首先,先看看如果从web.config里提取appSettings里的配置值,示例代码如下:
<appSettings>
<add key="pagetitle" value="http://blog.netbei.com/Job Site Starter Kit (Ver.1.0)"></add>
<add key="sitelogo" value="logo.gif"></add>
<add key="advertiseemail" value="sales@somesite.com"></add>
</appSettings>
利用ASP.NET2.0提供的一组API函数,您可以很容易的获取AppSettingsSection里所有的Keys/value组对,如下:
Configuration config = WebConfigurationManager.OpenWebConfiguration(Request.ApplicationPath);
AppSettingsSection appSettings = (AppSettingsSection) config.GetSection("appSettings");
string[] appKeys = appSettings.Settings.AllKeys;
for (int i = 0; i < appSettings.Settings.Count; i++)
{
//这里只进行简单的输出
Response.Write(appSettings.Settings[appKeys[i]].Value);
Response.Write("<BR>");
}
上面代码只是进行简单的输出所有Key的value值,然而,你可能想获取的仅仅是某一个key的值,这也非常简单,如下:
Configuration config = WebConfigurationManager.OpenWebConfiguration(Request.ApplicationPath);
AppSettingsSection appSettings = (AppSettingsSection)config.GetSection("appSettings")
string pateTitle= appSettings.Settings["pagetitle"].Value; //获取key为patetitle的value值
string siteLogo= appSettings.Settings["siteLogo"].Value; //获取key为sitelogo的value值
对于数据库连接字符串,在ASP.NET2.0里提供了专门的配置节如下:
<connectionStrings>
<add name="connectionstring"
connectionString="Data Source=SQLEXPRESS;AttachDbFilename=JsskDb.mdf; … .."/>
<add name="MyProviderConnectionString"
connectionString="Data Source=SQLEXPRESS;Integrated Security=True; … …"/>
</connectionStrings>
这样我们很容易获取数据库连接字符串如下:
Configuration config = WebConfigurationManager.OpenWebConfiguration(Request.ApplicationPath);
ConnectionStringsSection conSection = (ConnectionStringsSection)config.GetSection("connectionstring ");
ConnectionStringSettingsCollection conCollection = conSection.ConnectionStrings;
foreach (ConnectionStringSettings conSetting in conCollection)
{
Response.Write(conSetting.ConnectionString);
Response.Write("<BR>");
}
另外,利用API函数,你同时还可以在代码里更改web.config数据库连接的配置的值,如下
Configuration config = WebConfigurationManager.OpenWebConfiguration(Request.ApplicationPath);
ConnectionStringsSection conSection= (ConnectionStringsSection)config.GetSection("connectionStrings");
conSection.ConnectionStrings["SQLConnectionString"].ConnectionString =
"Data Source=SQLEXPRESS;Integrated Security=True; … …";
config.Save();
这里最有意思的可能就是类的转换,在<appSettings ></appSettings>里,使用的是AppSettingsSection类,在<connectionStrings></ connectionStrings>里使用的的是ConnectionStringsSection类,事实上,ASP.NET2.0提供的一组函数都是“配置节名+Section”的形式提供的类。
在ASP.NET官方网站曾经对此专门介绍,可以找不到该文件了。
在ASP.NET2.0里提供了两种方式对数据库连接字符串加密,一种是使用asp_regii命令,一种是通过代码,下面显示的是通过代码方式对数据库连接字符串加密,代码如下:
Configuration config = WebConfigurationManager.OpenWebConfiguration(Request.ApplicationPath);
ConfigurationSection configSection = config.GetSection("connectionStrings");
if (configSection.SectionInformation.IsProtected)
{//如果已经加密,就不用再加密了
configSection.SectionInformation.UnprotectSection();
config.Save();
}
else
{
configSection.SectionInformation.ProtectSection ("DataProtectionConfigurationProvider");
config.Save();
}
这样,你检查该文件的配置可能如下:
<connectionStrings configProtectionProvider="DataProtectionConfigurationProvider">
<EncryptedData>
<CipherData>
<CipherValue>AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAAVClqG40BZkCjK40
adynN8gQAAAACAAAAAAADZgAAqAAAABAAAABIhtOW …PE
</CipherData>
</EncryptedData>
</connectionStrings>
在microsoft的dotnet环境中,首推的是xml格式的配置文件(dotnet下实际上是.config格式的),而非以前的ini或者registry.
就.config格式的配置文件dotnet1.1和dotnet2.0也有着很大的变化, 比较显著的差异有:
(1)dotnet1.1中使用的是ConfigurationSettings
而dotnet2.0中使用的是ConfigurationManager
(2)dotnet1.1中的配置文件仅支持读操作,而不支持写操作,如果要完成写操作,则需要用户自己写一个xml文件的写函数来完成(本文也将给出一个例子)
而dotnet2.0中的ConfigurationManager已经可以实现配置文件节点的读写操作,并可以创建自己的group,secton和element,相对来说功能更强大.
本文只是起到一个抛砖引玉的作用,只展现了dotnet2.0的一部分特性,如果要做一些其他的操作,或者想把异常情况考虑的更全面一些,读者可以参考MSDN或者其他资料来做进一步的完善.要使用dotnet2.0中的配置文件功能,需要引用一下类:
using System.Configuration; // configuration setting
using System.Xml;
一、配置文件的读
/*string dbPath = ConfigurationSettings.AppSettings[textBoxkey.Text];
MessageBox.Show(String.Format("DatabasePath = {0}", dbPath));
string data = ConfigurationSettings.AppSettings["Data"];
int iData = int.Parse(data);
MessageBox.Show(String.Format("Data = {0}", iData));*/
// Get the application configuration file.
try
{
System.Configuration.Configuration config =
ConfigurationManager.OpenExeConfiguration(
ConfigurationUserLevel.None);
AppSettingsSection appSection = (AppSettingsSection)config.GetSection("appSettings");
try
{
textBoxPrompt.Text = appSection.Settings[textBoxkey.Text].Value;
}
catch (NullReferenceException)
{
textBoxPrompt.Text = "no such element";
}
}
catch (Exception ex)
{
textBoxPrompt.Text = String.Format("Exception catch: {0}", ex.Message);
string s = ex.ToString();
}
上面注释部分使用的是dotnet1.1中的功能
二、配置文件的写
try
{
System.Configuration.Configuration config =
ConfigurationManager.OpenExeConfiguration(
ConfigurationUserLevel.None);
AppSettingsSection appSection = (AppSettingsSection)config.GetSection("appSettings");
appSection.Settings[textBoxkey.Text].Value = textBoxvalue.Text;
config.Save();
}
catch (Exception ex)
{
textBoxPrompt.Text = String.Format("Exception catch: {0}", ex.Message);
}
在dotnet1.1中要想实现写操作则需要用户自己来实现,以下代码仅仅是一个例子
private void SaveConfig(string Key, string Value)
{
XmlDocument doc = new XmlDocument();
//获得配置文件的路径
string strFileName = Application.StartupPath + ".ConfigurationSettingTest.vshost.exe.config";
doc.Load(strFileName);
//找出名称为add的所有元素
XmlNodeList nodes = doc.GetElementsByTagName("add");
for (int i = 0; i < nodes.Count; i++)
{
//获得当前元素的key属性
XmlAttribute att = nodes[i].Attributes["key"];
//根据元素的第一个属性来判断当前的元素是不是目标元素
if (att.Value == Key)
{
//对目标元素中的第二个属性赋值
att = nodes[i].Attributes["value"];
att.Value = Value;
break;
}
}
//保存上面的修改
doc.Save(strFileName);
}
三、实现自定义sector
(1)先定义一些element和elementcollections
using System;
using System.Collections.Generic;
using System.Text;
using System.Configuration;
namespace ConfigurationSettingTest
{
// element defination
public class ListItemsElement : ConfigurationElement
{
[ConfigurationProperty("name", DefaultValue = "",
IsKey = true, IsRequired = true)]
public string Name
{
get { return ((string)(base["name"])); }
set { base["name"] = value; }
}
[ConfigurationProperty("value", DefaultValue = "",
IsKey = false, IsRequired = false)]
public string Value
{
get
{
return ((string)(base["value"]));
}
set
{
base["value"] = value;
}
}
[ConfigurationProperty("secquence", DefaultValue = "",
IsKey = false, IsRequired = false)]
public string Secquence
{
get
{
return ((string)(base["secquence"]));
}
set
{
base["secquence"] = value;
}
}
[ConfigurationProperty("action", DefaultValue = "",
IsKey = false, IsRequired = false)]
public string Action
{
get
{
return ((string)(base["action"]));
}
set
{
base["action"] = value;
}
}
}
[ConfigurationCollectionAttribute(typeof(ListItemsElement))]
public class ListItemsCollection : ConfigurationElementCollection
{
protected override ConfigurationElement CreateNewElement()
{
return new ListItemsElement();
}
protected override object GetElementKey(ConfigurationElement element)
{
return ((ListItemsElement)(element)).Name;
}
public void Add(ListItemsElement element)
{
this.BaseAdd(element);
}
public void Remove(string key)
{
this.BaseRemove(key);
}
public void Clear()
{
this.BaseClear();
}
public ListItemsElement this[int idx]
{
get { return (ListItemsElement)this[idx]; }
}
}
public class ListElementsSection : ConfigurationSection
{
[ConfigurationProperty("listItems")]
public ListItemsCollection ListItems
{
get
{
return ((ListItemsCollection)(base["listItems"]));
}
}
}
class ConfigSectionData : ConfigurationSection
{
[ConfigurationProperty("id")]
public int ID
{
get
{
return (int)this["id"];
}
set
{
this["id"] = value;
}
}
[ConfigurationProperty("time")]
public DateTime Time
{
get
{
return (DateTime)this["time"];
}
set
{
this["time"] = value;
}
}
}
}
(2)再添加相应的element或者sector,具体方法参见MSDN
/*System.Configuration.Configuration config =
ConfigurationManager.OpenExeConfiguration(
ConfigurationUserLevel.None);
ConfigSectionData data = new ConfigSectionData();
data.ID = 1000;
data.Time = DateTime.Now;
//在加入之前应该先测试是否是存在同样的section,如果有的话先删除,否则会报异常
ConfigSectionData test = config.Sections["TestSection"] as ConfigSectionData;
if (test == null) // not already exist
{
config.Sections.Add("TestSection", data);
}
else // exist
{
config.Sections.Remove("TestSection");
config.Sections.Add("TestSection", data);
}
//ConfigSectionData section = (ConfigSectionData)config.GetSection("TestSection");
config.Save();*/
System.Configuration.Configuration config =
ConfigurationManager.OpenExeConfiguration(
ConfigurationUserLevel.None);
// ListItemsCollection listcollection;
//在加入之前应该先测试是否是存在同样的section,如果有的话先删除,否则会报异常
ListElementsSection test = config.Sections["TestSection"] as ListElementsSection;
if (test == null) // not already exist
{
config.Sections.Add("TestSection", new ListElementsSection());
}
else // exist
{
config.Sections.Remove("TestSection");
config.Sections.Add("TestSection", new ListElementsSection());
}
ListElementsSection appSection = (ListElementsSection)config.GetSection("TestSection");
ListItemsElement listElement = new ListItemsElement();
listElement.Name = "Guanjinzhong";
appSection.ListItems.Add(listElement);
config.Save();
}
注释部分是添加系统默认sector中的element的方法
注意:以上代码都是直接从项目代码中抽取出来的,没有做什么更改,所以不能直接编译运行,在这里贴出来仅作为一个参考