【.net 深呼吸】自定义应用程序配置节

实际上,应用程序配置文件 App.config,是由各个节(Configuration Section)组成的,通常,配置节是按功能划分的,比如我们很熟悉的 appSettings、connectionStrings、startup、system.ServiceModel……

在实际开发中,我们的应用程序也应该需要一个咱们程序专且功能的配置节,这样也方便我们在代码中通过相关的API来读取,而不是用普通的XML文件读取方法。

其实,实现自定义配置节并不难,只是,有几个问题要注意。

老周一边给大伙伴们演示一边讲解,这样会比较有情调。

要自定义应用配置节,必须从 ConfigurationSection 类派生,该类是个抽象类,所以我们必须以其作为基类来定义自己的配置节。虽然它是一个抽象类,但是,功能很完善,多数情况下,我们是不需要重写它的成员(特殊需求的话,可以按需重写),给大家演示一下,看看我这个类。

    public class MyDemoSection : ConfigurationSection
    {
            ……
    }

那么,我们在这个类中要干啥呢?我们要给它添加我们需要的属性。比如,我需要两个属性——一个 User,字符串类型;另一个Age,类型为int。

    public class MyDemoSection : ConfigurationSection
    {
        public string User
        {
            get {……}
            set { ……}
        }

        public int Age
        {
            get { ……}
            set { …… }
        }
    }

这时候,你一定会想到一个问题:那配置文件API在保存到配置文件时,是如何识别的呢。其实这个 ConfigurationSection 类的基类是 ConfigurationElement。ConfigurationElement 是所有配置文件元素的共同基类。配置节实则就是一种特殊的配置元素,它与普通的配置元素的区别在于,配置节通常作为一类功能的主节点。而配置节的子元素就是普通的配置元素;配置节在使用前必须在 configSections 节点下进行声明,声明后才能在配置文件中使用。这个咱们后面再谈。

ConfigurationElement 类公开了以下两个版本的索引器:

protected internal object this[string propertyName] { get; set; }

protected internal object this[ConfigurationProperty prop] { get; set; }

我们一般用的是带string参数的版本,这个索引器只能在派生类中访问,不对外部公开。而 ConfigurationSection 类是从 ConfigurationElement 类派生的,自然会继承这个索引器。

所以,我们在自定义配置节的属性包装中,可以通过这个索引器来存取内容,其操作方法类似于字典。

    public class MyDemoSection : ConfigurationSection
    {
        public string User
        {
            get { return (string)this["user"]; }
            set { this["user"] = value; }
        }

        public int Age
        {
            get { return (int)this["age"]; }
            set { this["age"] = value; }
        }
    }

代码写到这里,貌似是完成了,其实未然。这时候,如果你想用代码把这个自定义节点写入配置文件,就会收到以下异常。

因为我们的自定义配置节类还没有完工,还差一个 Attribute 没有应用。应该这样写。

        [ConfigurationProperty("user")]
        public string User
        {
            get { return (string)this["user"]; }
            set { this["user"] = value; }
        }

        [ConfigurationProperty("age")]
        public int Age
        {
            get { return (int)this["age"]; }
            set { this["age"] = value; }
        }

注意,严重要注意!!应用的ConfigurationPropertyAttribute 中指定的name一定要和索引器(this["....."])中使用的名字相同,比如上面的代码,age要一致,如果改为这样,就会报错。

        [ConfigurationProperty("number")]
        public int Age
        {
            get { return (int)this["age"]; }
            set { this["age"] = value; }
        }

因为 number 和 age 不匹配,不过,类型的属性名不要求,比如,Age属性可以改为 Num。

        [ConfigurationProperty("age")]
        public int Num
        {
            get { return (int)this["age"]; }
            set { this["age"] = value; }
        }

把属性名改为 Num 是不会报错的。只要 ConfigurationPropertyAttribute 中的 name 参数与索引器中的名字一致即可

下面,我们试试这个自定义配置节,我们通过代码来配置,然后保存到 App.Config 中。

            Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
            MyDemoSection sect = new MyDemoSection();
            config.Sections.Add("myInfo", sect);
            //sect.SectionInformation.ForceSave = false;
            sect.User = "Ben Dan";
            sect.Age = 25;
            // 保存
            config.Save(ConfigurationSaveMode.Modified);

通过....Sections.Add 方法就可以把自定义的配置节添加配置文件中,其中,有一个name 参数,它用来指定在使用该配置时的XML元素名称。这个你如果不理解,不急,你先记住我们代码中写的名字叫 myInfo。

然后执行一下上面的代码,再打开与应用程序相关的App.config文件,注意不是项目中的config文件,是bin\\ 目录下的。打开后你会看到这样的内容。

<configuration>
    <configSections>
        <section name="myInfo" type="CustConfigs.MyDemoSection, CaiDemo, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
    </configSections>    <myInfo user="Ben Dan" age="25" />    ……
</configuration>

怎么样,你现在看明白了没,知道那个 myInfo 怎么用了吧。

首先,要在 configSections 节中用 section 元素来配置一下自定义配置节的类型,type指定的就是我们刚刚定义的那个 MyDemoSection 类,其实只需要写上类型名和程序集名即可。name 指定一个名称,就是你随后在配置文件使用时的XML元素名,如本例中的 myInfo。

在上面的代码中,可能你注意到有一行代码被注释了,

sect.SectionInformation.ForceSave = false;

MSDN 上说,这个属性指示是否要强制保存配置节的内容,哪怕它没有被修改过,这里我用不上,就注释掉了,因为MSDN上的示例有这一行,我故意加上来装逼一下的。

刚才,我们通过代码应用我自定义配置节,内容已写入 app.config 文件,此时我们如果再次运行上面的代码,你会发现报错了。

原来配置节是不能重复 Add 的,所以我们改改代码,先进行判断。

            Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
            MyDemoSection sect = config.Sections["myInfo"] as MyDemoSection;
            if(sect == null)
            {
                sect = new MyDemoSection();
                config.Sections.Add("myInfo", sect);
            }
            sect.User = "Ben Dan";
            sect.Age = 25;
            // 保存
            config.Save(ConfigurationSaveMode.Modified);

好了,这样可避免报错了。

接下来,老周再给各位举一例,这一次我们不用代码来写配置文件,而是直接编辑配置文件,然后在代码中读出配置信息。这种做法应该最常用。

还是那样,我们自定义一个配置节类型。

    public class DBSection : ConfigurationSection
    {
        [ConfigurationProperty("dbName", DefaultValue = "db.mdf")]
        public string DBName
        {
            get { return (string)this["dbName"]; }
            set { this["dbName"] = value; }
        }

        [ConfigurationProperty("loginName", DefaultValue = "sa")]
        public string LoginName
        {
            get { return (string)this["loginName"]; }
            set { this["loginName"] = value; }
        }
    }

假设,DBName 表示数据库文件的名字,LoginName表示登入 MSSQL 的名称(默认是 sa)。

然后,我们打开\bin\debug 下面的app.config,注意,不是项目中的配置文件。先为自定义配置节进行声明。

  <configSections>
    <section name="db" type="CustConfigs.DBSection, CaiDemo"/>
  </configSections>

这时候,要配置的话,XML元素名为db。

 <db dbName ="app.mdf" loginName="admin" />

注意这里设置的属性名不是类上的属性名,而是 ConfigurationPropertyAttribute 所指定的名称。

现在,我们在代码中读出这些配置参数。

            Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
            DBSection sect = config.Sections["db"] as DBSection;
            if (sect != null)
            {
                string s = $"数据库:{sect.DBName},登录名:{sect.LoginName}。";
                Console.WriteLine(s);
            }

注意刚刚我们在配置文件中声明时,给自定义节的元素命名为 db 。

 <section name="db" type="CustConfigs.DBSection, CaiDemo"/>

所以,我们读的时候,也要用 db 作为名字取出配置节实例,然后再读属性的值。

最后,输出结果如下:

好了,今天的内容就扯到这里吧,这个玩意儿,大家学会之后,还是很有实战价值的,而且也不难。

时间: 2024-10-11 00:48:57

【.net 深呼吸】自定义应用程序配置节的相关文章

.Net 自定义应用程序配置

引言 几乎所有的应用程序都离不开配置,有时候我们会将配置信息存在数据库中(例如大家可能常会见到名为Config这样的表):更多时候,我们会将配置写在Web.config或者App.Config中.通过将参数写在配置文件(表)中,我们的程序将变得更加灵活,只要对参数进行修改,再由程序中的某段代码去读取相应的值就可以了.而如果直接将配置值写在程序中,当配置需要改变时,则只能通过修改代码来完成,此时往往需要重新编译程序集. 本文不是讲述.Net Framework中诸多的内置结点如何设置,比如http

C#如何使用和开发自定义配置节

在日常的程序设计中,如何灵活和巧妙地运用配置信息是一个成功的设计师的首要选择.这不仅是为了程序设计得更灵活性和可扩展性,也是为了让你的代码给人以清新的感觉.程序中的配置信息一般放在应用程序的app.config或web.config文件中,当然也可以自定义自己的配置文件.这些配置文件是以XML格式进行存储和读取的.微软也封装一些对这些配置文件操作的类,这些类存在于名字空间System.Configuration下,这个命名空间包含提供用于处理配置数据的编程模型的类型,当然为了使用还添加Syste

只有在配置文件或 Page 指令中将 enableSessionState 设置为 true 时,才能使用会话状态。还请确保在应用程序配置的 // 节中包括 System.Web.SessionSta

首先搞清楚我们的目的,我的目的是验证用户是否登录,也就是Session["userName"]!=null 就ok了 开始的时候我是这么写的,结果报错,提示如上面标题的错误,查了半天资料都没搞清楚什么问题 public class BasePage:System.Web.UI.Page { public BasePage() { this.IsLogin(); } public void IsLogin() { if (Session["DateTime"] ==

自定义配置节与配置节的读取

一.引子 你是否也遇到过这样的问题:项目很多配置都写到了App.Config或Web.Config的AppSettings内,每个人都加了几条,到最后囤积了大量的配置,分不清哪个是有用的.哪个是没用的了.(即便加了相关注释,也是乱的可以) 1   <appSettings>  2     <!--是否抛出异常-->  3     <add key="HasException" value="true" />  4     <

ierp应用程序中的服务器错误无法识别的配置节connectionStrings

错误环境: Windows Server 2003 Enterprise Edition IIS 6.0 错误信息: "/ierp"应用程序中的服务器错误. -------------------------------------------------------------------------------- 配置错误 说明: 在处理向该请求提供服务所需的配置文件时出错.请检查下面的特定错误详细信息并适当地修改配置文件. 分析器错误信息: 无法识别的配置节"conne

ASP.NET添加和读取Web.Config自定义配置节

自定义节 1.首先在<configSections>中定义自定义配置节(例如Index.testSection)和对应的自定义配置节处理程序(例如NameValueSectionHandler) 2.然后添加节的内容 <configuration> <configSections> <sectionGroup name="Rewrite.NET"> <section name="Index" type="

asp.net web.config配置节说明

web.config 文件查找规则:      (1)如果在当前页面所在目录下存在web.config文件,查看是否存在所要查找的结点名称,如果存在返回结果并停止查找.      (2)如果当前页面所在目录下不存在web.config文件或者web.config文件中不存在该结点名,则查找它的上级目录,直到网站的根目录.      (3)如果网站根目录下不存在web.config文件或者web.config文件中不存在该节点名则在%windir%"Microsoft.NET"Frame

WPF实践系列1 of n 自定义WPF程序的Main函数

关于开篇 由于业务需要参与到一个Window下的WPF项目中.因为之前的工作环境一直在Linux下,C和C++作为主力开发语言, 因此加入新项目对自己来说是变化,同时也是挑战:学点新东西拓宽下视野. 关于WPF实践系列 项目是个中型的Windows客户端,需要通过网络和SQL服务器交互.由于有多版本兼容需求(xp-win10)和高分屏需求,选了WPF方案,在Visual Studio 2017下进行开发. 博主目前对WPF和 .Net这些知识仅是略知一二.取名实践系列,意指在过程中边做边学.主要

配置错误 不能在此路径中使用此配置节。如果在父级别上锁定了该节,便会出现这种情况

在全新安装的IIS7下搭建网站,访问页面时出现错误信息如下: 配置错误 不能在此路径中使用此配置节.如果在父级别上锁定了该节,便会出现这种情况.锁定是默认设置的(overrideModeDefault="Deny"),或者是通过包含 overrideMode="Deny" 或旧有的 allowOverride="false" 的位置标记明确设置的.  配置文件 \\?\X(盘符):\目录名\目录名\web.config <system.we