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. ...
随机推荐
- 【SQL Server】利用游标将学生表中的成绩转化为绩点
软件工程综合实践第一次作业 代码来源:班上同学的数据库大作业 alter table sc add GPA float; --加入绩点列 alter table sc ,);--将表按原始位置顺序编号 ...
- 【原】无脑操作:TypeScript环境搭建
概述:本文描述TypeScript环境搭建,以及基于VSCode的自动编译设置和调试设置.网络上很多相应文章的方式过时了或者无法试验成功. ------------------------------ ...
- Visual Studio Code-批量添加或删除注释行
小技巧一例,批量删除Visual Studio code或notepad++注解信息,便于读取有效代码或文本信息,具体操作如下: Visual Studio Code批量删除注解行信息: 在VS Co ...
- pytest之收集用例规则与运行指定用例
前言 上篇文章相信大家已经了解了pytest在cmd下结合各种命令行参数如何运行测试用例,并输出我们想要看到的信息.那么今天会讲解一下pytest是如何收集我们写好的用例?我们又有哪些方式来运行单个用 ...
- 使用whistle模拟cgi接口异常:错误码、502、慢网速、超时
绝大多数程序只考虑了接口正常工作的场景,而用户在使用我们的产品时遇到的各类异常,全都丢在看似 ok 的 try catch 中.如果没有做好异常的兼容和兜底处理,会极大的影响用户体验,严重的还会带来安 ...
- 使用 .NET Core 开发 BT Tracker 服务器
一.什么是 BT Tracker ? 在 BT 下载过程当中,我们如果拿到一个种子文件,在其内部会包含一组 BT Tracker 服务器信息.在开始进行下载的时候,BT 下载工具会根据种子内的唯一 H ...
- python:socket网络编程
Socket 网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket, 又称为“套接字”. 模块 import socket 创建套接字 socket.socket( ...
- springboot~jpa个性化数据操作接口
jap是个全能仓储 jap把很多数据库访问都封装了,并且提交了默认的一切数据方法签名的约定,大家按着约定走,可以不写SQL语句,而如果比较复杂的情况,也需要写SQL,这里我们介绍一下查询和修改的实例方 ...
- Java I/O不迷茫,一文为你导航!
前言:在之前的面试中,每每问到关于Java I/O 方面的东西都感觉自己吃了大亏..所以这里抢救一下..来深入的了解一下在Java之中的 I/O 到底是怎么回事..文章可能说明类的文字有点儿多,希望能 ...
- js事件循环机制辨析
对于新接触js语言的人来说,最令人困惑的大概就是事件循环机制了.最开始这也困惑了我好久,花了我几个月时间通过书本,打代码,查阅资料不停地渐进地理解他.接下来我想要和大家分享一下,虽然可能有些许错误的 ...