技术开发 频道

.net中读写config文件:配置文件操作

  实现代码如下:

public class MySection3 : ConfigurationSection
{
[ConfigurationProperty(
"Command1", IsRequired = true)]
public MyTextElement Command1
{
get { return (MyTextElement)this["Command1"]; }
}

[ConfigurationProperty(
"Command2", IsRequired = true)]
public MyTextElement Command2
{
get { return (MyTextElement)this["Command2"]; }
}
}

public class MyTextElement : ConfigurationElement
{
protected override void DeserializeElement(System.Xml.XmlReader reader, bool serializeCollectionKey)
{
CommandText
= reader.ReadElementContentAs(typeof(string), null) as string;
}
protected override bool SerializeElement(System.Xml.XmlWriter writer, bool serializeCollectionKey)
{
if( writer != null )
writer.WriteCData(CommandText);
return
true;
}

[ConfigurationProperty(
"data", IsRequired = false)]
public string CommandText
{
get { return this["data"].ToString(); }
set { this["data"] = value; }
}
}

 

  小结:

  1. 在实现上大体可参考MySection2,

  2. 每个ConfigurationElement由我们来控制如何读写XML,也就是要重载方法SerializeElement,DeserializeElement

  config文件 - Collection

<MySection444>
<add key="aa" value="11111"></add>
<add key="bb" value="22222"></add>
<add key="cc" value="33333"></add>
</MySection444>

  这种类似的配置方式,在ASP.NET的HttpHandler, HttpModule中太常见了,想不想知道如何实现它们? 代码如下:

public class MySection4 : ConfigurationSection // 所有配置节点都要选择这个基类
{
private static readonly ConfigurationProperty s_property
= new ConfigurationProperty(string.Empty, typeof(MyKeyValueCollection), null,
ConfigurationPropertyOptions.IsDefaultCollection);

[ConfigurationProperty(
"", Options = ConfigurationPropertyOptions.IsDefaultCollection)]
public MyKeyValueCollection KeyValues
{
get
{
return (MyKeyValueCollection)base[s_property];
}
}
}


[ConfigurationCollection(typeof(MyKeyValueSetting))]
public class MyKeyValueCollection : ConfigurationElementCollection // 自定义一个集合
{
// 基本上,所有的方法都只要简单地调用基类的实现就可以了。

public MyKeyValueCollection() : base(StringComparer.OrdinalIgnoreCase) // 忽略大小写
{
}

// 其实关键就是这个索引器。但它也是调用基类的实现,只是做下类型转就行了。
new public MyKeyValueSetting this[string name]
{
get
{
return (MyKeyValueSetting)base.BaseGet(name);
}
}

// 下面二个方法中抽象类中必须要实现的。
protected override ConfigurationElement CreateNewElement()
{
return
new MyKeyValueSetting();
}
protected override
object GetElementKey(ConfigurationElement element)
{
return ((MyKeyValueSetting)element).Key;
}

// 说明:如果不需要在代码中修改集合,可以不实现Add, Clear, Remove
public void Add(MyKeyValueSetting setting)
{
this.BaseAdd(setting);
}
public void Clear()
{
base.BaseClear();
}
public void Remove(string name)
{
base.BaseRemove(name);
}
}

public class MyKeyValueSetting : ConfigurationElement // 集合中的每个元素
{
[ConfigurationProperty(
"key", IsRequired = true)]
public string Key
{
get { return this["key"].ToString(); }
set { this["key"] = value; }
}

[ConfigurationProperty(
"value", IsRequired = true)]
public string Value
{
get { return this["value"].ToString(); }
set { this["value"] = value; }
}
}

  小结:

  1. 为每个集合中的参数项创建一个从ConfigurationElement继承的派生类,可参考MySection1

  2. 为集合创建一个从ConfigurationElementCollection继承的集合类,具体在实现时主要就是调用基类的方法。

  3. 在创建ConfigurationSection的继承类时,创建一个表示集合的属性就可以了,注意[ConfigurationProperty]的各参数。

  config文件 - 读与写

  前面我逐个介绍了4种自定义的配置节点的实现类,下面再来看一下如何读写它们。

  读取配置参数:

MySection1 mySectioin1 = (MySection1)ConfigurationManager.GetSection("MySection111");

  txtUsername1.Text
= mySectioin1.UserName;

  txtUrl1.Text
= mySectioin1.Url;

  MySection2 mySectioin2
= (MySection2)ConfigurationManager.GetSection("MySection222");

  txtUsername2.Text
= mySectioin2.Users.UserName;

  txtUrl2.Text
= mySectioin2.Users.Password;

  MySection3 mySection3
= (MySection3)ConfigurationManager.GetSection("MySection333");

  txtCommand1.Text
= mySection3.Command1.CommandText.Trim();

  txtCommand2.Text
= mySection3.Command2.CommandText.Trim();

  MySection4 mySection4
= (MySection4)ConfigurationManager.GetSection("MySection444");

  txtKeyValues.Text
= string.Join("\r\n",

  (from kv in mySection4.KeyValues.Cast()

  
let s = string.Format("{0}={1}", kv.Key, kv.Value)

  
select s).ToArray());

小结:在读取自定节点时,我们需要调用ConfigurationManager.GetSection()得到配置节点,并转换成我们定义的配置节点类,然后就可以按照强类型的方式来访问了。

 

 

 

 写配置文件:

 Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);

  MySection1 mySectioin1
= config.GetSection("MySection111") as MySection1;

  mySectioin1.UserName
= txtUsername1.Text.Trim();

  mySectioin1.Url
= txtUrl1.Text.Trim();

  MySection2 mySection2
= config.GetSection("MySection222") as MySection2;

  mySection2.Users.UserName
= txtUsername2.Text.Trim();

  mySection2.Users.Password
= txtUrl2.Text.Trim();

  MySection3 mySection3
= config.GetSection("MySection333") as MySection3;

  mySection3.Command1.CommandText
= txtCommand1.Text.Trim();

  mySection3.Command2.CommandText
= txtCommand2.Text.Trim();

  MySection4 mySection4
= config.GetSection("MySection444") as MySection4;

  mySection4.KeyValues.Clear();

  (from s in txtKeyValues.Lines

  
let p = s.IndexOf('=')

  where p
> 0

  
select new MyKeyValueSetting { Key = s.Substring(0, p), Value = s.Substring(p + 1) }

  ).ToList()

  .ForEach(kv
=> mySection4.KeyValues.Add(kv));

  config.Save();

  小结:在修改配置节点前,我们需要调用ConfigurationManager.OpenExeConfiguration(),然后调用config.GetSection()在得到节点后,转成我们定义的节点类型, 然后就可以按照强类型的方式来修改我们定义的各参数项,最后调用config.Save();即可。

  注意:

  1. .net为了优化配置节点的读取操作,会将数据缓存起来,如果希望使用修改后的结果生效,您还需要调用ConfigurationManager.RefreshSection(".....")

  2. 如果是修改web.config,则需要使用 WebConfigurationManager

  读写 .net framework中已经定义的节点

  前面一直在演示自定义的节点,那么如何读取.net framework中已经定义的节点呢?

  假如我想读取下面配置节点中的发件人。

<system.net>
<mailSettings>
<smtp from="Fish.Q.Li@newegg.com">
<network />
</smtp>
</mailSettings>
</system.net>

 读取配置参数:

SmtpSection section = ConfigurationManager.GetSection("system.net/mailSettings/smtp") as SmtpSection;

  labMailFrom.Text
= "Mail From: " + section.From;

  写配置文件:

Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);

  SmtpSection section
= config.GetSection("system.net/mailSettings/smtp") as SmtpSection;

  section.From
= "Fish.Q.Li@newegg.com2";

  config.Save();

  xml配置文件

  前面演示在config文件中创建自定义配置节点的方法,那些方法也只适合在app.config或者web.config中,如果您的配置参数较多, 或者打算将一些数据以配置文件的形式单独保存,那么,直接读写整个XML将会更方便。 比如:我有一个实体类,我想将它保存在XML文件中,有可能是多条记录,也可能是一条。

  这次我来反过来说,假如我们先定义了XML的结构,是下面这个样子的,那么我将怎么做呢?

<?xml version="1.0" encoding="utf-8"?>
<ArrayOfMyCommand xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd
="http://www.w3.org/2001/XMLSchema">
<MyCommand Name="InsretCustomer" Database="MyTestDb">
<Parameters>
<Parameter Name="Name" Type="DbType.String" />
<Parameter Name="Address" Type="DbType.String" />
</Parameters>
<CommandText>insret into .....</CommandText>
</MyCommand>
</ArrayOfMyCommand>

 

0
相关文章