zoukankan      html  css  js  c++  java
  • 第十节:Asp.Net Core 配置详解和选项模式

    一. 各种文件的读取

    1.说明

      在.Net Core中,各种配置文件的读取都需要依赖【Microsoft.Extensions.Configuration】程序集,当然在Asp.Net Core中已经内置了,然后通过依赖注入IConfiguration configuration对象进行配置文件的相关操作。

    比如在控制器注入该对象:

    相关约定:

    ①:配置键不区分大小写,例如,ConnectionString 和 connectionstring 被视为等效键。

    ②:在配置API中,冒号分隔符(:)适用于所有平台。

    ③:配置值是字符串

    ④:NULL值不能存储在配置中或绑定到对象。

     注:

      在Core MVC中,默认识别appsettings.json 文件,如果要添加其它类型的文件,需要通过AddJson、AddXml、AddIniFile、AddInMemoryCollection等方法手动添加进入, 方便起见通过 config.SetBasePath(Directory.GetCurrentDirectory());将当前目录设置为基础目录。

       这些AddXX方法,可以配置后面两个参数均为true,eg:config.AddJsonFile("Config/ypf1.json", optional: true, reloadOnChange: true);这样的话当配置文件发生变化的时候,会自动更新加载,而不必重启整个项目。

    项目结构:手动新增的配置文件都在Config文件夹下(如下图),然后都在Program类中进行加载进来(代码如下)

     1  public class Program
     2     {
     3         public static readonly Dictionary<string, string> _dict = new Dictionary<string, string>
     4         {
     5             {"MKey1", "value1"},
     6             {"MKey2", "value2"}
     7         };
     8 
     9         public static void Main(string[] args)
    10         {
    11             CreateWebHostBuilder(args).Build().Run();
    12         }
    13 
    14         public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
    15             WebHost.CreateDefaultBuilder(args)
    16                 //配置相关
    17                 .ConfigureAppConfiguration((hostingContext, config) =>
    18                 {
    19                     //1. 设置当前目录为基础目录(后面则可以用相对路径)
    20                     config.SetBasePath(Directory.GetCurrentDirectory());
    21                     //2. 加载json文件 (配置后面两个参数为true,当配置文件发生变化的时候,会自动更新加载,而不必重启整个项目)
    22                     config.AddJsonFile("Config/ypf1.json", optional: true, reloadOnChange: true);
    23                     //3. 加载xml文件
    24                     config.AddXmlFile("Config/ypf2.xml");
    25                     config.AddXmlFile("Config/ypf3.xml");
    26                     //4. 加载ini文件
    27                     config.AddIniFile("Config/ypf4.ini");
    28                     //5. 加载内存文件
    29                     config.AddInMemoryCollection(_dict);
    30                 })
    31                 .UseStartup<Startup>();
    32     }

    2. Json文件的读取

    (1).读取规则:

    A:普通对象直接通过键名来读取; B:对象中套对象通过多个键名(中间通过:连接)来读取;C: 数组对象则可以 键名:0(或1 或2)的方式来读取。

    (2).实战演练:

    ① 项目默认的appsettings.json的读取,

     1 {
     2   "Logging": {
     3     "LogLevel": {
     4       "Default": "Warning"
     5     }
     6   },
     7   "AllowedHosts": "*",
     8   //下面自定义一些值,用于测试配置文件的读取
     9   "MyFullName": "Maru Li",
    10   "User": {
    11     "userName": "ypf",
    12     "userAge": 15,
    13     "Child": {
    14       "childName": "ydb",
    15       "age": 12
    16     }
    17   },
    18   "StudentList": [
    19     {
    20       "sName": "qdkjdx"
    21     },
    22     {
    23       "sName": "bjdx"
    24     }
    25   ],
    26   //测试绑定类
    27   "starship": {
    28     "name": "USS Enterprise",
    29     "registry": "NCC-1701",
    30     "class": "Constitution",
    31     "length": 304.8,
    32     "commissioned": false
    33   },
    34   //测试绑定数组
    35   "myArray": ["001","002","003"],
    36   "json_array": {
    37     "key": "valueA",
    38     "subsection": [
    39       "valueB",
    40       "valueC",
    41       "valueD"
    42     ]
    43   }
    44 
    45 
    46 
    47 }
    View Code
    1  {
    2      var f0 = Configuration["MyFullName"];
    3      var f1 = Configuration["User:userName"];
    4      var f2 = Configuration["User:Child:childName"];
    5      var f3 = Configuration["StudentList:0:sName"];
    6      var f4 = Configuration["StudentList:1:sName"];
    7 }

    注:这里有一种特殊情况,比如数据库连接字符,通常是放在ConnectionStrings节点下的某个节点,所以可以通过 Configuration.GetConnectionString("xxx");来读取, 等价于:Configuration["ConnectionStrings:xxx"];

    1 {
    2   "ConnectionStrings": {
    3     "conn1": "sqlServer",
    4     "conn2": "mySql"
    5   }
    6 }
    1 {
    2    //数据库连接字符串读取
    3    var c1 = Configuration["ConnectionStrings:conn1"];
    4    var c2 = Configuration["ConnectionStrings:conn2"];
    5    //等价于上面的
    6    var c3 = Configuration.GetConnectionString("conn1");
    7    var c4 = Configuration.GetConnectionString("conn2");
    8 }

    ② 在Config文件夹中新增ypf1.json的读取:需要在Program类中通过代码 config.AddJsonFile("Config/ypf1.json"); 加载进来该json文件

    1 {
    2   "FullName": "ypf"
    3 }
    View Code
    1 {
    2      var f0 = Configuration["FullName"];
    3 }

    3. xml文件的读取

    ① 不存在重复节点,如:ypf2.xml 两个节点分别为section0 和 section1,可以明显的区分。

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <configuration>
     3   <section0>
     4     <key0>value001</key0>
     5     <key1>value002</key1>
     6   </section0>
     7   <section1>
     8     <key0>value003</key0>
     9     <key1>value004</key1>
    10   </section1>
    11 </configuration>
    View Code
    1  {
    2        var f0 = Configuration["section0:key0"];
    3        var f1 = Configuration["section0:key1"];
    4        var f2 = Configuration["section1:key0"];
    5        var f3 = Configuration["section1:key1"];
    6 }

    ② 存在重复节点,如:ypf3.xml,两个相同section节点,则需要通过name属性来区分,section下两个相同的key节点,也需要通过name来区分

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <configuration>
     3   <section name="section0">
     4     <key name="key0">value101</key>
     5     <key name="key1">value102</key>
     6   </section>
     7   <section name="section1">
     8     <key name="key0">value103</key>
     9     <key name="key1">value104</key>
    10   </section>
    11 </configuration>
    View Code
    1 {
    2      var f0 = Configuration["section:section0:key:key0"];
    3      var f1 = Configuration["section:section0:key:key1"];
    4      var f2 = Configuration["section:section1:key:key0"];
    5      var f3 = Configuration["section:section1:key:key1"];
    6  }

    4. INI 配置文件的读取

    结合[]类似特性的标记进行读取,如ypf4.ini。

     1 [section0]
     2 key0=value201
     3 key1=value202
     4 
     5 [section1]
     6 subsection:key=value203
     7 
     8 [section2:subsection0]
     9 key=value204
    10 
    11 [section2:subsection1]
    12 key=value205
    View Code
    1 {
    2     var f0 = Configuration["section0:key0"];
    3     var f1 = Configuration["section0:key1"];
    4     var f2 = Configuration["section1:subsection:key"];
    5     var f3 = Configuration["section2:subsection0:key"];
    6     var f4 = Configuration["section2:subsection1:key"];
    7 }

    5. 内存集合的读取

    通过AddInMemoryCollection添加内存集合,如_dic。

     

    1   {
    2       var f0 = Configuration["MKey1"];
    3       var f1 = Configuration["MKey2"];
    4   }

     另外:还有环境变量、命令行的读取均不常用,这里不详细介绍了。

    6. 单独封装帮助类

     首先要下载一系列程序集,如下图:

    注:如果在控制台使用的话,需要将被读取的文件属性改为"始终复制"。

     分享封装代码:

     1     /// <summary>
     2     /// 读取配置文件
     3     /// </summary>
     4     public static class ConfigHelp
     5     {
     6         /// <summary>
     7         /// 读取Json类型的配置文件
     8         /// </summary>
     9         /// <param name="key">键名</param>
    10         /// <param name="FilePath">文件路径,默认为:appsettings.json</param>
    11         /// <returns></returns>
    12         public static string GetString(string key, string FilePath = "appsettings.json")
    13         {
    14             var configurationBuilder = new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory()).AddJsonFile(FilePath, optional: true, reloadOnChange: true);
    15             var configuration = configurationBuilder.Build();
    16             return configuration[key];
    17         }
    18         /// <summary>
    19         /// 读取Xml类型的配置文件
    20         /// </summary>
    21         /// <param name="key">键名</param>
    22         /// <param name="FilePath">文件路径,默认为:myXml.json</param>
    23         /// <returns></returns>
    24         public static string GetXmlString(string key, string FilePath = "myXml.json")
    25         {
    26             var configurationBuilder = new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory()).AddXmlFile(FilePath, optional: true, reloadOnChange: true);
    27             var configuration = configurationBuilder.Build();
    28             return configuration[key];
    29         }
    30 
    31     }

    二. 方法和绑定

    1. 常用方法

    ① GetValue<T>:从具有指定键的配置中提取一个值,并将其转换为指定类型。 如果未找到该键,则过载允许你提供默认值。

    ② GetSection:使用指定的子节键提取配置子节,永远不会返回 null。 如果找不到匹配的节,则返回空 IConfigurationSection。如果有值,则在后面通过.Value来获取。

    ③ GetChildren:获得 IEnumerable<IConfigurationSection>

    ④ Exits:判断配置节是否存在

     代码分享:

     1 {
     2   "Logging": {
     3     "LogLevel": {
     4       "Default": "Warning"
     5     }
     6   },
     7   "AllowedHosts": "*",
     8   //下面自定义一些值,用于测试配置文件的读取
     9   "MyFullName": "Maru Li",
    10   "User": {
    11     "userName": "ypf",
    12     "userAge": 15,
    13     "Child": {
    14       "childName": "ydb",
    15       "age": 12
    16     }
    17   },
    18   "StudentList": [
    19     {
    20       "sName": "qdkjdx"
    21     },
    22     {
    23       "sName": "bjdx"
    24     }
    25   ],
    26   //测试绑定类
    27   "starship": {
    28     "name": "USS Enterprise",
    29     "registry": "NCC-1701",
    30     "class": "Constitution",
    31     "length": 304.8,
    32     "commissioned": false
    33   },
    34   //测试绑定数组
    35   "myArray": ["001","002","003"],
    36   "json_array": {
    37     "key": "valueA",
    38     "subsection": [
    39       "valueB",
    40       "valueC",
    41       "valueD"
    42     ]
    43   }
    44 
    45 }
    View Code
     1   {
     2                 //这里使用默认的appsettings.json来进行测试
     3                 //1. GetValue
     4                 var f0 = Configuration.GetValue<string>("MyFullName");
     5                 //如果没有该键,则赋值noValue
     6                 var f1 = Configuration.GetValue<string>("MyFullName111", "noValue");
     7                 var f2 = Configuration.GetValue<string>("User:userName");
     8                 //2. GetSection
     9                 var section0 = Configuration.GetSection("User");
    10                 var section1 = Configuration.GetSection("User1");
    11                 var section2 = Configuration.GetSection("User:userName");
    12                 var section2Value = section2.Value;
    13                 //3. GetChildren
    14                 var child0 = section0.GetChildren();
    15                 //4. Exist
    16                 var isExist0 = Configuration.GetSection("User:userName").Exists();
    17                 var isExist1 = Configuration.GetSection("User:userName1").Exists();
    18  }

    2. 绑定

     借助Bind方法,可以直接读取配置文件中的内容然后赋值给类或对象,如果配置文件是xml文件,不再需要像传统的.Net 那样,解析或者序列化了,可以直接赋值。

       这里还是用上面的appsetting.json这个文件进行测试。

    再次重复appsetting.json代码

     1 {
     2   "Logging": {
     3     "LogLevel": {
     4       "Default": "Warning"
     5     }
     6   },
     7   "AllowedHosts": "*",
     8   //下面自定义一些值,用于测试配置文件的读取
     9   "MyFullName": "Maru Li",
    10   "User": {
    11     "userName": "ypf",
    12     "userAge": 15,
    13     "Child": {
    14       "childName": "ydb",
    15       "age": 12
    16     }
    17   },
    18   "StudentList": [
    19     {
    20       "sName": "qdkjdx"
    21     },
    22     {
    23       "sName": "bjdx"
    24     }
    25   ],
    26   //测试绑定类
    27   "starship": {
    28     "name": "USS Enterprise",
    29     "registry": "NCC-1701",
    30     "class": "Constitution",
    31     "length": 304.8,
    32     "commissioned": false
    33   },
    34   //测试绑定数组
    35   "myArray": ["001","002","003"],
    36   "json_array": {
    37     "key": "valueA",
    38     "subsection": [
    39       "valueB",
    40       "valueC",
    41       "valueD"
    42     ]
    43   }
    44 
    45 
    46 
    47 }
    View Code

    类代码:

     1   public class Starship
     2     {
     3         public string Name { get; set; }
     4         public string Registry { get; set; }
     5         public string Class { get; set; }
     6         public decimal Length { get; set; }
     7         public bool Commissioned { get; set; }
     8     }
     9    public class User
    10     {
    11         public string userName { get; set; }
    12         public int userAge { get; set; }
    13         public Child child { get; set; }
    14     }
    15 
    16     public class Child
    17     {
    18         public string childName { get; set; }
    19         public int age { get; set; }
    20     }
    21     public class MyArrayExample
    22     {
    23         public string Key { get; set; }
    24         public string[] Subsection { get; set; }
    25     }

    绑定代码:

     1  {
     2                 //1. 绑定到普通类
     3                 Starship startShipModel = new Starship();
     4                 Configuration.GetSection("starship").Bind(startShipModel);
     5 
     6                 //2. 绑定到对象
     7                 User user = new User();
     8                 Configuration.GetSection("User").Bind(user);
     9 
    10                 //3. 绑定数组到类
    11                 MyArrayExample myExample = new MyArrayExample();
    12                 Configuration.GetSection("json_array").Bind(myExample);
    13 
    14 } 

    三. 选项模式

    1. 声明MyOptions类,与appsetting.json对应。

    1   public class MyOptions
    2     {
    3         public MyOptions()
    4         {
    5             Option1 = "value1_from_ctor";
    6         }
    7         public string Option1 { get; set; }
    8         public string Option2 { get; set; } = "555";
    9     }
    {
      /******************************************************下面是选项模式相关的***************************************************/
      "option1": "I am option1",
      "option2": "I am option2"
    }

    2. 然后在Startup类中ConfigureServices中进行选项的相关配置,

    3. 在HomeController中进行注入,然后使用即可。

     1        //下面是选项系统相关的属性或字段声明
     2         private readonly MyOptions _options;
     3         public HomeController(IOptions<MyOptions> optionsAccessor)
     4         {
     5             _options = optionsAccessor.Value;
     6         }
     7        public IActionResult Index2()
     8         {
     9             /*************************************** 三.各种配置文件的读取 **********************************************/
    10 
    11             ViewBag.MyOptions= $"option1 = {_options.Option1}, option2 = {_options.Option2}";
    12             return View();
    13         }

    页面展示:

     

    !

    • 作       者 : Yaopengfei(姚鹏飞)
    • 博客地址 : http://www.cnblogs.com/yaopengfei/
    • 声     明1 : 本人才疏学浅,用郭德纲的话说“我是一个小学生”,如有错误,欢迎讨论,请勿谩骂^_^。
    • 声     明2 : 原创博客请在转载时保留原文链接或在文章开头加上本人博客地址,否则保留追究法律责任的权利。
     
  • 相关阅读:
    C# GDI+图形程序设计看书笔记
    SQL2008转SQL2005
    vb6 调用 .Net Dll
    VS编译后的postevent
    Bind 和 ScaffoldColumn
    转: MarshalAs与StructLayout
    Microsoft .NET Compact Framework 开发常见问题解答
    .Net2.0 使用ConfigurationManager读写配置文件
    在.NET中使用命名管道完成进程间通信[转]
    C# 取电信公网IP并发送邮件
  • 原文地址:https://www.cnblogs.com/yaopengfei/p/10975759.html
Copyright © 2011-2022 走看看