.NET 配置文件反序列化技术详解

.NET框架中,配置文件反序列化是一个常见的需求。自.NET 2.0发布以来,旧的IConfigurationSectionHandler接口已经被弃用,取而代之的是一系列新的类和属性。主要的替代类是ConfigurationElement,但是大多数示例只演示了如何处理带有属性数据的XML。本文将介绍如何反序列化包含文本内容的XML元素。

.NET2.0之前,可以使用IConfigurationSectionHandler接口来反序列化所有类型的配置XML。自.NET2.0发布以来,该接口已被弃用,取而代之的是一系列新的类和属性。虽然大多数XML可以重写为将文本内容移动到属性中,但这样做会丢失XML本身的一些表达能力。

使用代码

在开始之前,需要引用并包含以下命名空间:

using System.Collections.Generic; using System.Configuration; using System.Xml;

所有示例类都在以下命名空间定义中编写:

namespace ConfigurationTextElement { }

第一部分 - 通用示例

向项目的主配置文件添加自定义节。在这个示例中,项目的命名空间和程序集名为ConfigurationTextElement。自定义节名为root,并将存储在名为root.config的文件中。

如果选择将根XML存储在单独的文件中,请确保将文件的Copy to Output Directory属性更改为Copy Always。这将确保在调试期间使用的二进制文件夹中存在该文件。

创建类以处理XML的反序列化并存储其数据。

第一个类将对应于根元素,它也代表配置节。

using System.Configuration; public class Root : ConfigurationSection { }

创建一个懒单例类,它在静态属性中公开根类的实例。在这个示例中,配置类将直接被应用程序使用。

using System.Configuration; namespace ConfigurationTextElement { public class Settings { private static Root _root = null; private Settings() { } public static Root Root { get { if (_root == null) { _root = (Root)ConfigurationManager.GetSection("root"); } return _root; } } } }

创建将存储element1的类,添加适当的基类和属性属性。

public class Element1 : ConfigurationElement { [ConfigurationProperty("attrib1")] public String Attrib1 { get { return this["attrib1"].ToString(); } } [ConfigurationProperty("attrib2")] public String Attrib2 { get { return this["attrib2"].ToString(); } } }

更新根类以包括element1的属性。

public class Root : ConfigurationSection { [ConfigurationProperty("element1")] public Element1 Element1 { get { return (Element1)this["element1"]; } } }

在页面或窗体的OnLoad方法中添加代码以测试attrib1attrib2的值。

protected override void OnLoad(EventArgs e) { base.OnLoad(e); string e1a1; e1a1 = Settings.Root.Element1.Attrib1; }

上述元素相对容易实现,与许多其他可用示例非常相似。下一个元素element2则不那么直接。实际上,尝试使用ConfigurationElement反序列化它将产生以下错误:

配置节不能包含CDATA或文本元素。

创建一个名为ConfigurationTextElement的新类,该类是泛型的,继承自ConfigurationElement,并覆盖其基类的DeserializeElement方法。这个类也是一个泛型类,根据实例化时指定的类型将数据转换并返回。

using System.Collections.Generic; using System.Configuration; using System.Xml; public class ConfigurationTextElement : ConfigurationElement { private T _value; protected override void DeserializeElement(XmlReader reader, bool serializeCollectionKey) { _value = (T)reader.ReadElementContentAs(typeof(T), null); } public T Value { get { return _value; } } } public class Root : ConfigurationSection { [ConfigurationProperty("element1")] public Element1 Element1 { get { return (Element1)this["element1"]; } } [ConfigurationProperty("element2")] public ConfigurationTextElement Element2 { get { return (ConfigurationTextElement)this["element2"]; } } [ConfigurationProperty("element3")] [ConfigurationCollection(typeof(Child1), AddItemName = "child1")] public Element3 Element3 { get { return (Element3)this["element3"]; } } [ConfigurationProperty("element4")] [ConfigurationCollection(typeof(ConfigurationTextElement), AddItemName = "child2")] public Element4 Element4 { get { return (Element4)this["element4"]; } } } public class Element1 : ConfigurationElement { [ConfigurationProperty("attrib1")] public String Attrib1 { get { return this["attrib1"].ToString(); } } [ConfigurationProperty("attrib2")] public String Attrib2 { get { return this["attrib2"].ToString(); } } } public class Element3 : ConfigurationElementCollection { protected override ConfigurationElement CreateNewElement() { return new Child1(); } protected override object GetElementKey(ConfigurationElement element) { return ((Child1)element).Key; } public Child1 this[int index] { get { return (Child1)BaseGet(index); } } new public Child1 this[string key] { get { return (Child1)BaseGet(key); } } public bool ContainsKey(string key) { List keys = new List(BaseGetAllKeys()); return keys.Contains(key); } } public class Element4 : ConfigurationElementCollection { protected override ConfigurationElement CreateNewElement() { return new ConfigurationTextElement(); } protected override object GetElementKey(ConfigurationElement element) { return ((ConfigurationTextElement)element).Value; } public ConfigurationTextElement this[int index] { get { return (ConfigurationTextElement)BaseGet(index); } } } public class Child1 : ConfigurationElement { [ConfigurationProperty("key")] public String Key { get { return this["key"].ToString(); } } [ConfigurationProperty("value")] public String Value { get { return this["value"].ToString(); } } } protected override void OnLoad(EventArgs e) { base.OnLoad(e); string e1a1; string e2; string e3c1_item1; string e3c1_item2; string e4c2_item1; string e4c2_item2; e1a1 = Settings.Root.Element1.Attrib1; e2 = Settings.Root.Element2.ToString(); e3c1_item1 = Settings.Root.Element3[0].Value; e3c1_item2 = Settings.Root.Element3["y"].Value; e4c2_item1 = Settings.Root.Element4[0].Value; e4c2_item2 = Settings.Root.Element4[1].Value; }
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485