ASP.NET基础知识汇总之WebConfig自定义节点详细介绍
之前介绍过Webconfig的具体知识ASP.NET基础知识汇总之WebConfig各节点介绍。今天准备封装一个ConfigHelper类,涉及到了自定义节点的东东,平时虽然一直用,但也没有系统的总结过,网上有很多关于自定义节点的精彩介绍。
一、为什么需要自定义节点?
大部分情况下,我们都是在<appsetting>中定义自己需要的参数,简单方便。如果配置的参数比较多,比较复杂的话就会显得杂乱无章,而且这种方式不支持复杂的层次节点也不支持强类型,所以有时候我们需要自定义节点。下面我们以配置redis参数和lognet参数为例,介绍自定义节点。
二、通过配置redis参数介绍自定义节点
先附上完整的配置信息如下
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="RedisConfig" type="MyRedisConfigurationHelper.MyRedisConfigurationSection,MyRedisConfigurationHelper" />
<section name="MyLog4net" type="MyLogConfigHelper.MyLog4netClass,MyLogConfigHelper"/>
</configSections>
<RedisConfig autoStart="true" dbIndex="" password="redispass123" allowAdmin="true" abortConnect="false">
<ReadWriteHost>
<add host="127.0.0.1:6379" />
</ReadWriteHost>
<ReadOnlyHost>
<add host="192.168.4.110:6379" />
</ReadOnlyHost>
<MaxWritePoolSize size="" />
<MaxReadPoolSize size="" />
<SocketSendTimeout second="" />
<SocketReceiveTimeout second="" />
<ConnectTimeout second="" />
</RedisConfig>
<MyLog4net>
<add key="LogName" value="Test" />
<add key="LogLevel" value="" />
</MyLog4net>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
</startup>
<appSettings>
<add key="CACHE_REDIS" value="true" />
</appSettings>
<system.web>
<membership defaultProvider="ClientAuthenticationMembershipProvider">
<providers>
<add name="ClientAuthenticationMembershipProvider" type="System.Web.ClientServices.Providers.ClientFormsAuthenticationMembershipProvider, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" serviceUri="" connectionStringName="DefaultConnection" credentialsProvider="" />
</providers>
</membership>
<roleManager defaultProvider="ClientRoleProvider" enabled="true">
<providers>
<add name="ClientRoleProvider" type="System.Web.ClientServices.Providers.ClientRoleProvider, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" serviceUri="" cacheTimeout="" connectionStringName="DefaultConnection" />
</providers>
</roleManager>
</system.web>
<connectionStrings>
<add name="DefaultConnection" connectionString="Data Source = |SQL/CE|" />
</connectionStrings>
</configuration>
上边使用颜色标记的信息就是自定义的配置节点。自定义配置节点需要注意的事项如下:
1、自定义节点必须在configSections节点中。
2、section节点属性:name:必选的 String 属性,指定与 type 属性中指定的配置节处理程序关联的配置节或元素的名称。这是该元素在配置文件的节设置区域中使用的名称。type:必选的 String 属性,指定用来执行如下操作的配置节处理程序类的名称:处理在 name 属性中指定的节或元素中的配置设置。
3、section 元素将配置节处理程序与配置元素或节关联。每个 section 元素均标识一个配置节或元素。可以在 sectionGroup 元素中对 section 元素进行逻辑分组,以对 section 元素进行组织并避免命名冲突。section 和 sectionGroup 元素包含在 configSections 元素中。我们在这里没有介绍sectionGroup,毕竟在项目中自定义节点也不多,name不重复即可。
4、具体的一些特性和元素解释可以参考官网https://docs.microsoft.com/zh-cn/previous-versions/ms228245(v=vs.110)
5、
三、对自定义节点分块剖析
上边使用颜色标记的信息就是自定义的配置节点。蓝色标记的是Redis相关的自定义配置节点。绿色的是lognet相关的自定义配置信息。
1、log4net相关的自定义配置信息解析
<section name="MyLog4net" type="MyLog4netDemo.MyLog4netClass,MyLog4netDemo"/>
(1)其中name是配置文件中自定义节点设置区域使用的名称,就是标识设置具体自定义节点所使用的名称。比如:
<MyLog4net>
<add key="LogName" value="Test" />
<add key="LogLevel" value="" />
</MyLog4net>
(2)其中type中的MyLog4netClass就是自定义节点所需要的方法实现。针对于该自定义节点,实现方法如下:
using System;
using System.Configuration; namespace MyLogConfigHelper
{
/// <summary>
/// 读取自定义配置文件信息
/// </summary>
public class MyLog4netClass : ConfigurationSection
{
private static readonly ConfigurationProperty property
= new ConfigurationProperty(string.Empty, typeof(MyLog4netClassElementCollection), null,
ConfigurationPropertyOptions.IsDefaultCollection); [ConfigurationProperty("", Options = ConfigurationPropertyOptions.IsDefaultCollection)]
public MyLog4netClassElementCollection KeyValues
{
get
{
return (MyLog4netClassElementCollection)base[property];
}
} #region 读取自定义配置文件信息
private static MyLog4netClass _myLog4netClassProperty = null;
public static MyLog4netClass MyLog4netClassProperty
{
get { return _myLog4netClassProperty; }
set
{
_myLog4netClassProperty = value;
}
}
static MyLog4netClass()
{
const string SETTINGS = "MyLog4net";
object section = null;
if (System.Web.Hosting.HostingEnvironment.IsHosted)
{
//web.config
section = ConfigurationManager.GetSection(SETTINGS);
}
else
{
//App.config
section = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None).Sections[SETTINGS];
}
if (section is MyLog4netClass)
{
_myLog4netClassProperty = section as MyLog4netClass;
}
if (_myLog4netClassProperty == null)
{
throw new Exception("请在Config文件中配置<configSections> < section name =\"MyLog4net\" type=\"MyLog4netDemo.MyLog4netClass,MyLog4netDemo\"/></configSections>"); }
}
#endregion
} /// <summary>
/// 元素集合
/// </summary>
[ConfigurationCollection(typeof(MyLog4netClassElement))]
public class MyLog4netClassElementCollection : ConfigurationElementCollection
{
public MyLog4netClassElement this[int index]
{
get
{
return (MyLog4netClassElement)base.BaseGet(index);
}
set
{
if (base.BaseGet(index) != null)
{
base.BaseRemoveAt(index);
}
this.BaseAdd(index, value);
}
}
/// <summary>
/// 重写ConfigurationElementCollection中的方法
/// <summary>
/// <returns></returns>
protected override ConfigurationElement CreateNewElement()
{
return new MyLog4netClassElement();
}
/// <summary>
/// 重写ConfigurationElementCollection中的方法
/// </summary>
/// <param name="element"></param>
/// <returns></returns>
protected override object GetElementKey(ConfigurationElement element)
{
return ((MyLog4netClassElement)element).Key;
}
}
/// <summary>
/// 集合中的每一个元素 实现MyLog4net集合中每一个元素的key value
/// </summary>
public class MyLog4netClassElement : ConfigurationElement
{
public MyLog4netClassElement()
{
}
public MyLog4netClassElement(string key,string value)
{
this.Key = key;
this.Value = value;
}
[ConfigurationProperty("key", IsRequired = true)]
public string Key
{
get
{
return (string)base["key"];
}
set
{
base["key"] = value;
}
}
[ConfigurationProperty("value",IsRequired =true)]
public string Value
{
get
{
return (string)base["value"];
}
set
{
base["value"] = value;
}
}
}
}
函数入口:
using System; namespace MyLogConfigHelper
{
class Program
{
static void Main(string[] args)
{
MyLog4netClass myLog4netClass = MyLog4netClass.MyLog4netClassProperty;
foreach (MyLog4netClassElement item in myLog4netClass.KeyValues)
{
Console.WriteLine("key:{0}", item.Key);
Console.WriteLine("Value:{0}", item.Value);
}
Console.ReadKey();
}
}
}
2、RedisConfig相关的自定义节点剖析
(1)针对RedisConfig的实现代码如下:
using System;
using System.Configuration; namespace MyRedisConfigurationHelper
{
#region Section 配置文件中 自定义RedisConfig节点的信息Model
public class MyRedisConfigurationSection : ConfigurationSection
{
#region RedisConfig Model信息
[ConfigurationProperty("ReadOnlyHost", IsDefaultCollection = false)]
[ConfigurationCollection(typeof(MyRedisConfigurationElement), CollectionType = ConfigurationElementCollectionType.AddRemoveClearMap, RemoveItemName = "remove")]
public MyRedisConfigurationElementCollection ReadOnlyHost
{
get
{
return (MyRedisConfigurationElementCollection)base["ReadOnlyHost"];
}
} [ConfigurationProperty("ReadWriteHost", IsDefaultCollection = false)]
[ConfigurationCollection(typeof(MyRedisConfigurationElement), CollectionType = ConfigurationElementCollectionType.AddRemoveClearMap, RemoveItemName = "remove")]
public MyRedisConfigurationElementCollection ReadWriteHost
{
get
{
return (MyRedisConfigurationElementCollection)base["ReadWriteHost"];
}
} [ConfigurationProperty("MaxWritePoolSize", IsDefaultCollection = false)]
public MaxWritePoolSizeConfigurationElement MaxWritePoolSize
{
get
{
return (MaxWritePoolSizeConfigurationElement)base["MaxWritePoolSize"];
}
} [ConfigurationProperty("MaxReadPoolSize", IsDefaultCollection = false)]
public MaxWritePoolSizeConfigurationElement MaxReadPoolSize
{
get
{
return (MaxWritePoolSizeConfigurationElement)base["MaxReadPoolSize"];
}
} [ConfigurationProperty("SocketSendTimeout", IsDefaultCollection = false)]
public SocketSendTimeoutConfigurationElement SocketSendTimeout
{
get
{
return (SocketSendTimeoutConfigurationElement)base["SocketSendTimeout"];
}
} [ConfigurationProperty("SocketReceiveTimeout", IsDefaultCollection = false)]
public SocketReceiveTimeoutConfigurationElement SocketReceiveTimeout
{
get
{
return (SocketReceiveTimeoutConfigurationElement)base["SocketReceiveTimeout"];
}
} [ConfigurationProperty("ConnectTimeout", IsDefaultCollection = false)]
public ConnectTimeoutConfigurationElement ConnectTimeout
{
get
{
return (ConnectTimeoutConfigurationElement)base["ConnectTimeout"];
}
} [ConfigurationProperty("autoStart", IsDefaultCollection = false, DefaultValue = true)]
public bool AutoStart
{
get
{
return (bool)base["autoStart"];
}
} [ConfigurationProperty("abortConnect", IsDefaultCollection = false, DefaultValue = true)]
public bool AbortConnect
{
get
{
return (bool)base["abortConnect"];
}
} [ConfigurationProperty("dbIndex", IsDefaultCollection = false, DefaultValue = )]
public int DbIndex
{
get
{
return (int)base["dbIndex"];
}
} [ConfigurationProperty("password", IsDefaultCollection = false, DefaultValue = "")]
public string Password
{
get
{
return (string)base["password"];
}
} [ConfigurationProperty("allowAdmin", IsDefaultCollection = false, DefaultValue = false)]
public bool AllowAdmin
{
get
{
return (bool)base["allowAdmin"];
}
}
#endregion #region 用来获取配置文件中的 自定义RedisConfig节点信息
private static MyRedisConfigurationSection _myRedisConfigurationSectionProperty = null;
public static MyRedisConfigurationSection MyRedisConfigurationSectionProperty
{
get { return _myRedisConfigurationSectionProperty; }
set
{
_myRedisConfigurationSectionProperty = value;
}
} static MyRedisConfigurationSection()
{
const string SETTINGS = "RedisConfig";
object section = null;
if (System.Web.Hosting.HostingEnvironment.IsHosted)
{
//web.config
section = ConfigurationManager.GetSection(SETTINGS);
}
else
{
//App.config
section = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None).Sections[SETTINGS];
}
if (section is MyRedisConfigurationSection)
{
_myRedisConfigurationSectionProperty = section as MyRedisConfigurationSection;
}
if (_myRedisConfigurationSectionProperty == null)
{
throw new Exception("请在Config文件中配置<configSections> < section name =\"RedisConfig\" type=\"MyRedisConfigurationHelper.GetSectionClass,MyRedisConfigurationHelper\"/></configSections>"); }
}
#endregion
}
#endregion #region ElementCollection 用于接收 自定义RedisConfig多层元素节点
public class MyRedisConfigurationElementCollection: ConfigurationElementCollection
{
public MyRedisConfigurationElement this[int index]
{
get
{
return (MyRedisConfigurationElement)base.BaseGet(index);
}
set
{
if (base.BaseGet(index) != null)
{
base.BaseRemoveAt(index);
}
this.BaseAdd(index, value);
}
}
protected override ConfigurationElement CreateNewElement()
{
return new MyRedisConfigurationElement();
}
protected override object GetElementKey(ConfigurationElement element)
{
return ((MyRedisConfigurationElement)element).Host;
}
}
#endregion #region Element 集合中的每一个元素 声明RedisConfig集合中每一个元素
/// <summary>
/// host ip地址
/// </summary>
public class MyRedisConfigurationElement:ConfigurationElement
{
public MyRedisConfigurationElement()
{
}
public MyRedisConfigurationElement(string host)
{
this.Host = host;
}
[ConfigurationProperty("host", IsRequired = true)]
public string Host
{
get
{
return (string)base["host"];
}
set
{
base["host"] = value;
}
}
} /// <summary>
/// Socket发送超时的配置信息
/// </summary>
public class SocketSendTimeoutConfigurationElement : TimeoutConfigurationElement
{
}
/// <summary>
/// Socket接收超时的配置信息
/// </summary>
public class SocketReceiveTimeoutConfigurationElement : TimeoutConfigurationElement
{
}
/// <summary>
/// Socket连接超时配置信息
/// </summary>
public class ConnectTimeoutConfigurationElement : TimeoutConfigurationElement
{
} /// <summary>
/// 写入连接池大小的配置信息
/// </summary>
public class MaxWritePoolSizeConfigurationElement : SizeConfigurationElement
{
} /// <summary>
/// 连接池大小的配置信息
/// </summary>
public abstract class SizeConfigurationElement : ConfigurationElement
{
[ConfigurationProperty("size", IsRequired = true, IsKey = true, DefaultValue = )]
public int Size
{
get
{
return (int)base["size"];
}
set
{
base["size"] = value;
}
}
}
/// <summary>
/// Socket超时的配置信息
/// </summary>
public abstract class TimeoutConfigurationElement : ConfigurationElement
{
[ConfigurationProperty("second", IsRequired = true, IsKey = true, DefaultValue = )]
public int Second
{
get
{
return (int)base["second"];
}
set
{
base["second"] = value;
}
}
}
#endregion
}
(2)函数入口:
using System; namespace MyRedisConfigurationHelper
{
class Program
{
static void Main(string[] args)
{
MyRedisConfigurationSection myRedisConfig = MyRedisConfigurationSection.MyRedisConfigurationSectionProperty;
Console.WriteLine(myRedisConfig.ReadOnlyHost);
Console.ReadKey();
}
}
}
四、代码下载
其实就是对Element、ElementCollection、Section的操作
ASP.NET基础知识汇总之WebConfig自定义节点详细介绍的更多相关文章
- ASP.NET基础知识汇总之WebConfig各节点介绍
web.config虽然一直用,接触最多的也就是节点appSettings和connectionSettings,今天系统的梳理一下,了解一下webconfig各个节点的含义,先简单的浏览一下具体的w ...
- WebConfig 自定义节点configSections配置信息
WebConfig 自定义节点configSections配置信息 示例: <configuration> <configSections> <!-- For ...
- 十四个关于ASP.NET基础知识问答(C#版)
这是一些ASP.NET很基础的东西,希望对ASP.NET爱好者特别是刚刚入门的朋友有所帮助虽然示例代码是C#.NET,但是不影响VB.NET朋友的参考.好,继续往下看吧! 1.ASP.NET能在那些系 ...
- python基础知识8——模块1——自定义模块和第三方开源模块
模块的认识 模块,用一砣代码实现了某个功能的代码集合. 类似于函数式编程和面向过程编程,函数式编程则完成一个功能,其他代码用来调用即可,提供了代码的重用性和代码间的耦合.而对于一个复杂的功能来,可能需 ...
- asp.net 基础知识
1. DropDownList 的赋值 Response.Write(DropDownList1.Items.FindByText("潍坊").Value); Response.W ...
- ASP.NET-EF基础知识
定义 asp.net Entity Framework是微软以ADO.NET为基础发展出来的对象关系对应(OR Mapping)解决方案. 三种EF工作模式(自己理解的) 从数据库表创建类 从类创 ...
- asp.netMVC4(基础知识----传值问题分析)
(1)一般在数据交互的时候,都会涉及到前后台间的相互传值,一般的情况下,方法也有多种,下面就后台定义变量往前台传值: 以下是后台代码: /// <summary> /// 展示举报信息 / ...
- Asp.net基础知识
1.[项目结构] 1.1文件后缀: .cs 源文件(程序代码) .csproj 项目文件(管理文件项) .sln 解决方案文件(管理项目) .config ...
- WebConfig自定义节点并读取
最近是遇到了一个需求,需要自定义WebConfig节点,然后进行读取,网上有很多博客,写的非常好,但是笔者在实现的过程中还是遇到了点问题,现在写一篇文章来总结下. 首先推荐大家看http://www. ...
随机推荐
- navicate for mysql之-Can't connect to MySQL server on 'localhost'(10038)
1. 卸载navicate for mysql 会留下很多坑,主要是卸载不干净,卸载之后重新安装会出现之前的库内容和库链接还存在的问题,这种情况的出现是卸载残余. 解决办法,清理注册表(网上很多教程但 ...
- python3 字符编码与转码的理解
额...上通识课讲到了NLP12条,感觉讲的挺好的,照着抄一条先... 1,没有两个人是一样的 没有两个人的人生经验会完全一样,所以没有两个人的信念,价值和规条系统会是一样. 因此没有两个人对同一件事 ...
- 【Teradata】TD Unicode编码格式下varchar定义测试
如下测试表,每个字段字符编码格式均为Unicode. 1.varchar(1)可以存储1个汉字,也只能存储1个ASCII字符. --创建表nc_test,每个字段编码格式均设定为Unicode[使用S ...
- MySQL 数据库死锁
数据库死锁 死锁的解决办法(1) 执行下面SQL,先查看哪些表被锁住了: select b.owner,b.object_name,a.session_id,a.locked_mode from v$ ...
- python从学渣到学沫的半月天
今天又要引进一个新的知识点了,就是模块,可以直接引用的一个东西,从实用性来说很强大,不过还是需要记住模块的类型啊,如何应用还是需要学习和了解的.其中模块是分三种的,一种内置模块python内部提供的功 ...
- Netty1:初识Netty
为什么使用Netty Netty是业界最流行的NIO框架之一,它的健壮性.功能.性能.可定制性.可扩展性在同类框架中都是首屈一指的,它已经得到了成百上千的商用项目的证明.对于为什么使用Netty这个话 ...
- 音视频 学习&开发&测试 资源
一.FFmpeg 学习 1. 官方API文档 FFmpeg Documentation:http://www.ffmpeg.org/doxygen/trunk/index.html 2. 优秀开源项目 ...
- Go基础(3)
demo1: package main import "fmt" func print() { for i := 1; i < 10; i++ { for j := 1; j ...
- Postman:传递的参数是List类型时 传参格式的写法
Postman传递的参数是List类型 实体类中引用了一个List,泛型为其他实体类 参数是List集合时,Postman中参数格式如下图所示: 有不明白的地方,欢迎留言
- MySQL学习(一)日志与索引 --- 2019年1月
1.MySQL的架构 1).连接器 先根据Ip和端口号,用户名和密码,连接MySQL数据库,连接后如果没有下一步动作,连接就处于空闲状态,此时有一个连接超时时间的设置 wait_timeout默认8小 ...