原文地址,原文更规范些,由于帖子内容过长,此处删除了部分内容,建议看原文
http://blog.csdn.net/xuexiaodong2009/article/details/6655818
配置文件也可以做成强类型,配置文件的强类型其实就是使配置文件也具有int,DateTime也可以是其他自定义的类型,而不是普通的String类型,至于强类型和一般类型的区别与好处,再次不在叙述,此处只讲解详细的制作步骤。由于使用了强类型,任何时候只要发现配置文件不满足条件就会抛异常,保存时不满足条件的数据也是不能通过系统保存的。当然你可以通过记事本修改在保存,但读取时会抛异常。 主要包括1单个节点2复合节点,也就是有子节点的节点3配置节4读取配置文件。 一下以一个配置文件为例详细讲解 配置文件
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="Mail" type="WindowsTestConfig.ClientConfiguration,WindowsTestConfig"/>
</configSections>
<Mail LengTh="8">
<Services ServicesPort="808" >
<Service Address="127.0.0.1" Port="805"/>
<Service Address="127.0.0.2" Port="804"/>
<Service Address="127.0.0.3" Port="803" />
<!--<Service Type="NMail.MetricsService.MetricsService, NMail.MetricsService" />-->
</Services>
</Mail>
</configuration> 1单个节点 Service可以认为是单个节点,应为里边没有包含子节点,只有属性。
view plain <Service Address="127.0.0.1" Port="805"/> 需要注意的是: 1配置文件的属性名称是区分大小写的,ConfigurationProperty的第一个参数必须要和属性名称相同 2需要继承自基类ConfigurationElement,并根据属性的多少添加不同的方法 3对于每一种常见的类型都有对应的验证方法,例如int是IntegerValidator,字符是StringValidator,还有其他的,功能更强大的正则表达式验证类型RegexStringValidator,但个人试了试不知道RegexStringValidator好像不好用。 4把string转化为其他类型,需要有一个继承自TypeConverter的子类的特性,可以看看 [TypeConverter(typeof(IPAddressTypeConverter))],而继承自TypeConverter也很简单,只需要重写两个方法而已。 ConfigurationElement官网参考对于此处代码为:
public class IPEndPointElement : ConfigurationElement
{
[ConfigurationProperty("Address", IsRequired = true)]//Address 需要与配置文件的属性名称相对应,是区分大小写的
[TypeConverter(typeof(IPAddressTypeConverter))]//告诉系统,怎么把一个string类型转化为需要的IPAddress 类型,也就是强类型
// [StringValidator(InvalidCharacters = " ~!@#$%^&*()[]{}/;'\"|\\",MinLength = 7, MaxLength = 15)]//字符串验证属性
// [RegexStringValidator(@"^(\d{1,3}\.){3}\d{1,3}{1}quot;)]//正则表达式验证属性
public IPAddress Address
{
get
{
return (IPAddress)this["Address"];
}
set
{
this["Address"] = value;
}
}
[ConfigurationProperty("Port", IsRequired = true, DefaultValue = 80)]///Port 需要与配置文件的属性名称相对应,是区分大小写的
[IntegerValidator(MinValue = 1, MaxValue = 65536)]//int 类型验证,设置区间
public int Port
{
get
{
return (int)this["Port"];
}
set
{
this["Port"] = value;
}
}
public IPEndPoint ToEndPoint()//返回强类型结果
{
return new IPEndPoint((IPAddress)this["Address"], (int)this["Port"]);
}
public override string ToString()
{
return this["Address"] + ":" + this["Port"];
}
}
public class IPAddressTypeConverter : TypeConverter//把一个string怎样转化为IPAddress,需要继承TypeConverter,并重写一下的两个方法就可以了
{
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
if (sourceType == typeof(string))
{
return true;
}
return base.CanConvertFrom(context, sourceType);
}
public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
{
if (value is string)
{
return IPAddress.Parse((string)value);
}
return base.ConvertFrom(context, culture, value);
}
} 2复合节点Services 可以认为是一个复合节点,因为他包含了一个子节点集合 <Services ServicesPort="808" >
<Service address="127.0.0.1" Port="805"/>
<Service Address="127.0.0.2" Port="804"/>
</Services> 1配置文件的属性名称是区分大小写的,ConfigurationProperty的第一个参数必须要和属性名称相同 2需要继承自基类ConfigurationElementCollection,并根据属性的多少添加不同的方法
3由于是集合多了几个方法需要重写
ConfigurationElementCollection官网参考 对应的代码为
public class IPAddressCollection : ConfigurationElementCollection
{
protected override ConfigurationElement CreateNewElement()//创建一个写的子节点调用方法
{
return new IPEndPointElement();
}
[ConfigurationProperty("ServicesPort", IsRequired = true, DefaultValue = 80)]//需要与配置文件一致
[IntegerValidator(MinValue = 1, MaxValue = 65535)]//int 类型的验证
public int ServicesPort
{
get
{
return (int)this["ServicesPort"];
}
set
{
this["ServicesPort"] = value;
}
}
protected override object GetElementKey(ConfigurationElement element)//其他的都是集合相关的操作,只需要很少的改变
{
IPEndPointElement address = (IPEndPointElement)element;
return getKey(address);
}
}
3配置节Mail可以认为是一个配置节,因为它外边在没有自定义的东西了
<Mail LengTh="8">
</Mail>
1配置文件的属性名称是区分大小写的,ConfigurationProperty的第一个参数必须要和属性名称相同 2需要继承自基类ConfigurationSection,并根据属性的多少添加不同的方法 3根据包含的子元素写一些方法 4由于自己写的配置节,系统并不知道,所以需要在配置文件中注册。也就是在配置文件中添加如下代码, name是这一配置节的名称,type用逗号分成两部分,前一部分是配置节的类名称包含命名空间,后一部分是配置节类所在的程序集名称。 <configSections>
<section name="Mail" type="WindowsTestConfig.ClientConfiguration,WindowsTestConfig"/>
</configSections> ConfigurationSection官网参考 对应的代码为:
class ClientConfiguration : ConfigurationSection
{
public static readonly string SectionsName = "Mail";//配置节名称
public static void AddToConfigFile()
{
if (ConfigFile.Current.Sections[SectionsName] == null)//添加配置节
{
ConfigFile.Current.Sections.Add(SectionsName, new ClientConfiguration());
}
}
public static bool ConfigurationPresent
{
get
{
return (ConfigFile.Current.Sections[SectionsName] != null);
}
}
public static ClientConfiguration Current//获取配置节
{
get
{
ClientConfiguration current;
current = (ClientConfiguration)ConfigFile.Current.GetSection(SectionsName);
if (current == null)
{
throw new ConfigurationErrorsException("Mail configuration is missing");
}
return current;
}
}
[ConfigurationProperty("Services", IsDefaultCollection = false)]//Services需要与配置文件一致
[ConfigurationCollection(typeof(IPEndPointElement), AddItemName = "Service",
ClearItemsName = "ClearServer", RemoveItemName = "RemoveServer")]//对应集合的几个方法
public IPAddressCollection DnsServers
{
get
{
return (IPAddressCollection)this["Services"];
}
}
[ConfigurationProperty("LengTh", IsRequired = true)]//一个属性,名称需要与配置文件一致
public int LengTh
{
get
{
return (int)this["LengTh"];
}
set
{
this["LengTh"] = value;
}
}
}
4读取配置文件自己写的配置节系统并不知道,所以需要进行一定处理,配置节类需要用到这个类处理代码:
class ConfigFile
{
static ConfigFile()
{ string path= Assembly.GetExecutingAssembly().GetModules()[0].FullyQualifiedName+".config";//获取配置文件路径包含名称
current = OpenConfig(path);
}
private static Configuration current;
public static Configuration Current {//获取当前节
get {
return current;
}
set {
current = value;
}
}
public static Configuration OpenConfig(string configFilename) {
ExeConfigurationFileMap cfm = new ExeConfigurationFileMap();
cfm.ExeConfigFilename = configFilename;
return ConfigurationManager.OpenMappedExeConfiguration(cfm, ConfigurationUserLevel.None);
}
}
源代码下载
http://download.csdn.net/source/3493901
http://blog.csdn.net/xuexiaodong2009/article/details/6655818
配置文件也可以做成强类型,配置文件的强类型其实就是使配置文件也具有int,DateTime也可以是其他自定义的类型,而不是普通的String类型,至于强类型和一般类型的区别与好处,再次不在叙述,此处只讲解详细的制作步骤。由于使用了强类型,任何时候只要发现配置文件不满足条件就会抛异常,保存时不满足条件的数据也是不能通过系统保存的。当然你可以通过记事本修改在保存,但读取时会抛异常。 主要包括1单个节点2复合节点,也就是有子节点的节点3配置节4读取配置文件。 一下以一个配置文件为例详细讲解 配置文件
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="Mail" type="WindowsTestConfig.ClientConfiguration,WindowsTestConfig"/>
</configSections>
<Mail LengTh="8">
<Services ServicesPort="808" >
<Service Address="127.0.0.1" Port="805"/>
<Service Address="127.0.0.2" Port="804"/>
<Service Address="127.0.0.3" Port="803" />
<!--<Service Type="NMail.MetricsService.MetricsService, NMail.MetricsService" />-->
</Services>
</Mail>
</configuration> 1单个节点 Service可以认为是单个节点,应为里边没有包含子节点,只有属性。
view plain <Service Address="127.0.0.1" Port="805"/> 需要注意的是: 1配置文件的属性名称是区分大小写的,ConfigurationProperty的第一个参数必须要和属性名称相同 2需要继承自基类ConfigurationElement,并根据属性的多少添加不同的方法 3对于每一种常见的类型都有对应的验证方法,例如int是IntegerValidator,字符是StringValidator,还有其他的,功能更强大的正则表达式验证类型RegexStringValidator,但个人试了试不知道RegexStringValidator好像不好用。 4把string转化为其他类型,需要有一个继承自TypeConverter的子类的特性,可以看看 [TypeConverter(typeof(IPAddressTypeConverter))],而继承自TypeConverter也很简单,只需要重写两个方法而已。 ConfigurationElement官网参考对于此处代码为:
public class IPEndPointElement : ConfigurationElement
{
[ConfigurationProperty("Address", IsRequired = true)]//Address 需要与配置文件的属性名称相对应,是区分大小写的
[TypeConverter(typeof(IPAddressTypeConverter))]//告诉系统,怎么把一个string类型转化为需要的IPAddress 类型,也就是强类型
// [StringValidator(InvalidCharacters = " ~!@#$%^&*()[]{}/;'\"|\\",MinLength = 7, MaxLength = 15)]//字符串验证属性
// [RegexStringValidator(@"^(\d{1,3}\.){3}\d{1,3}{1}quot;)]//正则表达式验证属性
public IPAddress Address
{
get
{
return (IPAddress)this["Address"];
}
set
{
this["Address"] = value;
}
}
[ConfigurationProperty("Port", IsRequired = true, DefaultValue = 80)]///Port 需要与配置文件的属性名称相对应,是区分大小写的
[IntegerValidator(MinValue = 1, MaxValue = 65536)]//int 类型验证,设置区间
public int Port
{
get
{
return (int)this["Port"];
}
set
{
this["Port"] = value;
}
}
public IPEndPoint ToEndPoint()//返回强类型结果
{
return new IPEndPoint((IPAddress)this["Address"], (int)this["Port"]);
}
public override string ToString()
{
return this["Address"] + ":" + this["Port"];
}
}
public class IPAddressTypeConverter : TypeConverter//把一个string怎样转化为IPAddress,需要继承TypeConverter,并重写一下的两个方法就可以了
{
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
if (sourceType == typeof(string))
{
return true;
}
return base.CanConvertFrom(context, sourceType);
}
public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
{
if (value is string)
{
return IPAddress.Parse((string)value);
}
return base.ConvertFrom(context, culture, value);
}
} 2复合节点Services 可以认为是一个复合节点,因为他包含了一个子节点集合 <Services ServicesPort="808" >
<Service address="127.0.0.1" Port="805"/>
<Service Address="127.0.0.2" Port="804"/>
</Services> 1配置文件的属性名称是区分大小写的,ConfigurationProperty的第一个参数必须要和属性名称相同 2需要继承自基类ConfigurationElementCollection,并根据属性的多少添加不同的方法
3由于是集合多了几个方法需要重写
ConfigurationElementCollection官网参考 对应的代码为
public class IPAddressCollection : ConfigurationElementCollection
{
protected override ConfigurationElement CreateNewElement()//创建一个写的子节点调用方法
{
return new IPEndPointElement();
}
[ConfigurationProperty("ServicesPort", IsRequired = true, DefaultValue = 80)]//需要与配置文件一致
[IntegerValidator(MinValue = 1, MaxValue = 65535)]//int 类型的验证
public int ServicesPort
{
get
{
return (int)this["ServicesPort"];
}
set
{
this["ServicesPort"] = value;
}
}
protected override object GetElementKey(ConfigurationElement element)//其他的都是集合相关的操作,只需要很少的改变
{
IPEndPointElement address = (IPEndPointElement)element;
return getKey(address);
}
}
3配置节Mail可以认为是一个配置节,因为它外边在没有自定义的东西了
<Mail LengTh="8">
</Mail>
1配置文件的属性名称是区分大小写的,ConfigurationProperty的第一个参数必须要和属性名称相同 2需要继承自基类ConfigurationSection,并根据属性的多少添加不同的方法 3根据包含的子元素写一些方法 4由于自己写的配置节,系统并不知道,所以需要在配置文件中注册。也就是在配置文件中添加如下代码, name是这一配置节的名称,type用逗号分成两部分,前一部分是配置节的类名称包含命名空间,后一部分是配置节类所在的程序集名称。 <configSections>
<section name="Mail" type="WindowsTestConfig.ClientConfiguration,WindowsTestConfig"/>
</configSections> ConfigurationSection官网参考 对应的代码为:
class ClientConfiguration : ConfigurationSection
{
public static readonly string SectionsName = "Mail";//配置节名称
public static void AddToConfigFile()
{
if (ConfigFile.Current.Sections[SectionsName] == null)//添加配置节
{
ConfigFile.Current.Sections.Add(SectionsName, new ClientConfiguration());
}
}
public static bool ConfigurationPresent
{
get
{
return (ConfigFile.Current.Sections[SectionsName] != null);
}
}
public static ClientConfiguration Current//获取配置节
{
get
{
ClientConfiguration current;
current = (ClientConfiguration)ConfigFile.Current.GetSection(SectionsName);
if (current == null)
{
throw new ConfigurationErrorsException("Mail configuration is missing");
}
return current;
}
}
[ConfigurationProperty("Services", IsDefaultCollection = false)]//Services需要与配置文件一致
[ConfigurationCollection(typeof(IPEndPointElement), AddItemName = "Service",
ClearItemsName = "ClearServer", RemoveItemName = "RemoveServer")]//对应集合的几个方法
public IPAddressCollection DnsServers
{
get
{
return (IPAddressCollection)this["Services"];
}
}
[ConfigurationProperty("LengTh", IsRequired = true)]//一个属性,名称需要与配置文件一致
public int LengTh
{
get
{
return (int)this["LengTh"];
}
set
{
this["LengTh"] = value;
}
}
}
4读取配置文件自己写的配置节系统并不知道,所以需要进行一定处理,配置节类需要用到这个类处理代码:
class ConfigFile
{
static ConfigFile()
{ string path= Assembly.GetExecutingAssembly().GetModules()[0].FullyQualifiedName+".config";//获取配置文件路径包含名称
current = OpenConfig(path);
}
private static Configuration current;
public static Configuration Current {//获取当前节
get {
return current;
}
set {
current = value;
}
}
public static Configuration OpenConfig(string configFilename) {
ExeConfigurationFileMap cfm = new ExeConfigurationFileMap();
cfm.ExeConfigFilename = configFilename;
return ConfigurationManager.OpenMappedExeConfiguration(cfm, ConfigurationUserLevel.None);
}
}
源代码下载
http://download.csdn.net/source/3493901
解决方案 »
免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货