• ASP.NETCore中的配置文件读取


    创建一个asp.net core 3.1的项目(我这里创建的是mvc

    配置文件准备

    MyIniConfig.ini

    MyKey="MyIniConfig.ini Value"
    [Position]
    Title="My INI Config title"
    Name="My INI Config name"
    [Position:JiaRen]
    f="zxcf"
    m="zxcm"
    [Logging:LogLevel]
    Default=Information
    Microsoft=Warning

    MyConfig.json

    {
      "Logging": {
        "LogLevel": {
          "Default": " MyConfig.json Information",
          "Microsoft": "MyConfig.json Warning",
          "Microsoft_Hosting_Lifetime": "MyConfig.json Information"
        }
      },
      "AllowedHosts": "*",
      "Position": {
        "Title": "MyConfig.json 编辑器1",
        "Name": "MyConfig.json Joe Smith",
        "JiaRen": {
          "f": "MyConfig.json zxcf",
          "m": "MyConfig.json zxcm"
        }
      },
      "MyKey": "MyConfig.json"
    }

    appsettings.json

    {
      "Logging": {
        "LogLevel": {
          "Default": "Information",
          "Microsoft": "Warning",
          "Microsoft_Hosting_Lifetime": "Information"
        }
      },
      "AllowedHosts": "*",
      "Position": {
        "Title": "编辑器",
        "Name": "Joe Smith",
        "JiaRen": {
          "f": "zxcf",
          "m": "zxcm"
        }
      },
      "MyKey": "My appsettings.json Value"
    } 

    出现中文乱码的情况 :解决方案 将json 文件改成utf-8格式  

    使用索引器的方式读取配置文件中的信息

      在Startup文件中有如下的几行代码:

       有了这几行代码我们才能去读取配置文件(在startup构造函数中进行依赖注入),切换到home控制器下,首先需要将 IConfiguration 依赖注入到home

    控制器下

     //定义一个字段存储注入的类型
    private readonly IConfiguration _configuration;
    //在构造函数中进行依赖注入
    public HomeController(IConfiguration configuration)
    {
    this._configuration = configuration; }

         找到Index方法,写入以下代码

      
    //通过索引器来获取相应的值
    var myKey = this._configuration["MyKey"];

    //以:进行分层查找
    var myKey1 = this._configuration["Position:Title"];

    //打印
    Console.WriteLine(myKey);
    Console.WriteLine(myKey1);

    控制台打印结果:

    前面是通过索引器的方式读取配置文件,下面我们将配置文件绑定到对象进行配置文件的读取(也是msdn官方推荐的方式:选项模式) 下面查看appsettings.json中的这一段配置,我们以这一段进行一个绑定,进行读取配置信息。

    首先在ConfigModel 文件夹中建类 PositionOptions  和 JiarenOptions (我为了图方便建立在一个类文件中) 如下

    下面将配置文件和类进行绑定

     绑定方法① 通过实例化一个对象将相应节点下的配置文件绑定到对象上

     //实例化一个存储配置的类
     var positionOptions = new ConfigModel.PositionOptions();
    //获取到类中定义的const 字段中存储的节点信息 将节点下的信息保存在上面实例化的类中
      _configuration.GetSection(ConfigModel.PositionOptions.Position).Bind(positionOptions);

    绑定方法② 通过Get<type>方法进行绑定,并返回一个对象

     //简化上面的语句 获取类中定义的const 字段通过get<type>方法 编译并返回对应类型类型
    var postitionOptions = this._configuration.GetSection(ConfigModel.PositionOptions.Position).Get<ConfigModel.PositionOptions>();

    绑定方法③通过依赖注入进行绑定

    在Startup.ConfigureServices 方法中添加下面的代码

    //使用选项模式时的替代方法是绑定 Position 部分并将它添加到依赖项注入服务容器
    services.Configure<PositionOptions>(Configuration.GetSection(PositionOptions.Position));

    在home控制器中进行依赖注入

    private readonly IConfiguration _configuration;
    private readonly PositionOptions _positionOptions;
    
    public HomeController(
                IConfiguration configuration,
                IOptionsSnapshot<PositionOptions> options,
                )
            {
                this._configuration = configuration;
              
                this._positionOptions = options.Value;
               
            }

    在index 中就可以通过对象进行读取

    ViewBag.name = _positionOptions.Title;
    var f = _positionOptions.JiaRen.f;
    Console.WriteLine(ViewBag.name);
    Console.WriteLine(f);

    控制台结果:

     现在思考一个问题,如果我的配置项有很多怎么办?是不是都要以上面的方法进行配置?当然不是,我们最好把这些放入同一个文件中(合并服务集合)

    创建一个类将所有的配置服务封装到同一个文件中以扩展方法进行注册

    在Startup.ConfigureServices()方法中调用

      //封装一个扩展方法 加载所有的配置项(合并服务集合)
       services.AddConfig(Configuration);

     下面我们可以进行一些扩展 读取其他配置文件中的内容

    首先注释appsettings.json 中的配置以免影响

    下面我们看一下MyIniConfig.ini 这个文件,我们下面将操作这个文件

     打开Program文件替换 CreateHostBuilder 方法

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureAppConfiguration((hostingContext, config) =>
                {
                    config.Sources.Clear();
    
                    var env = hostingContext.HostingEnvironment;
    
                    config.AddIniFile("MyIniConfig.ini", optional: true, reloadOnChange: true)
                          .AddIniFile($"MyIniConfig.{env.EnvironmentName}.ini",
                                         optional: true, reloadOnChange: true);
    
                    config.AddEnvironmentVariables();
    
                    if (args != null)
                    {
                        config.AddCommandLine(args);
                    }
                })
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                });

    因为这个配置文件和appsetting中的key 是一样的 所以不用更改任何代码就可以直接获取到值

    //通过索引器来获取相应的值
    var myKey = this._configuration["MyKey"];

    //以:进行分层查找
    var myKey1 = this._configuration["Position:Title"];

    //打印
    Console.WriteLine(myKey);
    Console.WriteLine(myKey1);

     ini同样也会绑定到对应的对象中

    ViewBag.name = _positionOptions.Title;
    var f = _positionOptions.JiaRen.f;
    Console.WriteLine(ViewBag.name);
    Console.WriteLine(f);

     下面我们看一下MyConfig.json 这个文件,我们下面将操作这个文件

     我们只需要将Program文件 CreateHostBuilder 方法 替换成如下文件就可以了

            public static IHostBuilder CreateHostBuilder(string[] args) =>
           Host.CreateDefaultBuilder(args)
               .ConfigureAppConfiguration((hostingContext, config) =>
               {
                   config.AddJsonFile("MyConfig.json",
                       optional: true,
                       reloadOnChange: true);
               })
               .ConfigureWebHostDefaults(webBuilder =>
               {
                   webBuilder.UseStartup<Startup>();
               });

    介绍过几种文件配置文件的操作方式,我们再来看一种内存操作方式,将Program文件 CreateHostBuilder 方法 替换成如下文件

      public static IHostBuilder CreateHostBuilder(string[] args)
            {
                var Dict = new Dictionary<string, string>
            {
               {"MyKey", "Dictionary  MyKey Value"},
               {"Position:Title", "Dictionary_Title"},
               {"Position:Name", "Dictionary_Name" },
               {"Position:JiaRen:f", "Dictionary_f" },
               {"Position:JiaRen:m", "Dictionary_m" },
               {"Logging:LogLevel:Default", "Warning"}
            };
    
                return Host.CreateDefaultBuilder(args)
                    .ConfigureAppConfiguration((hostingContext, config) =>
                    {
                        config.AddInMemoryCollection(Dict);
                    })
                    .ConfigureWebHostDefaults(webBuilder =>
                    {
                        webBuilder.UseStartup<Startup>();
                    });
            }

    我们直接运行看结果

    //通过索引器来获取相应的值
    var myKey = this._configuration["MyKey"];
    
    //以:进行分层查找
    var myKey1 = this._configuration["Position:Title"];
    
    //打印
    Console.WriteLine(myKey);
    Console.WriteLine(myKey1);

     

    ViewBag.name = _positionOptions.Title;
    var f = _positionOptions.JiaRen.f;
    Console.WriteLine(ViewBag.name);
    Console.WriteLine(f);

    补充

     当然还有xml类型 

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
      <MyKey>MyXMLFile Value</MyKey>
      <Position>
        <Title>Title from  MyXMLFile</Title>
        <Name>Name from MyXMLFile</Name>
      </Position>
      <Logging>
        <LogLevel>
          <Default>Information</Default>
          <Microsoft>Warning</Microsoft>
        </LogLevel>
      </Logging>
    </configuration>

    将Program文件 CreateHostBuilder 方法 替换成如下文件

     public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureAppConfiguration((hostingContext, config) =>
                {
                    config.Sources.Clear();
    
                    var env = hostingContext.HostingEnvironment;
    
                    config.AddXmlFile("MyXMLFile.xml", optional: true, reloadOnChange: true)
                          .AddXmlFile($"MyXMLFile.{env.EnvironmentName}.xml",
                                         optional: true, reloadOnChange: true);
    
                    config.AddEnvironmentVariables();
    
                    if (args != null)
                    {
                        config.AddCommandLine(args);
                    }
                })
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                });

    在home控制器中进行测试

    var myKeyValue = Configuration["MyKey"];
    var title = Configuration["Position:Title"];
    var name = Configuration["Position:Name"];
    var defaultLogLevel = Configuration["Logging:LogLevel:Default"];

    如果使用 name 属性来区分元素,则使用相同元素名称的重复元素可以正常工作

    <?xml version="1.0" encoding="UTF-8"?>
    <configuration>
      <section name="section0">
        <key name="key0">value 00</key>
        <key name="key1">value 01</key>
      </section>
      <section name="section1">
        <key name="key0">value 10</key>
        <key name="key1">value 11</key>
      </section>
    </configuration>

    在home 控制器中index方法进行测试

            var key00 = "section:section0:key:key0";
            var key01 = "section:section0:key:key1";
            var key10 = "section:section1:key:key0";
            var key11 = "section:section1:key:key1";
    
            var val00 = Configuration[key00];
            var val01 = Configuration[key01];
            var val10 = Configuration[key10];
            var val11 = Configuration[key11];

    上面讲了使用索引器获取值下面讲另一种

    GetValue

     //使用getvalue根据指定的key 获取数据
       var mykey = this._configuration.GetValue<string>("Position:title", "null");

    GetSection(获取节点)、GetChildren(获取子节点集合) 和 Exists(判断节点是否存在)

                //获取节点,value属性获取节点的值
                IConfigurationSection key = _configuration.GetSection("Position:title");
                var val = key.Value;
                //获取节点下的子节点,返回一个集合 
                IEnumerable<IConfigurationSection> getChildren = _configuration.GetSection("Position").GetChildren();
    
                //遍历节点获取值
                foreach (var item in getChildren)
                {
                    if (item.GetChildren().Count() > 0)
                    {
                        foreach (var i in item.GetChildren())
                            Console.WriteLine(i.Value);
                    }
                    else
                        Console.WriteLine(item.Value);
                }

     Exists判断节点是否存在

                var selection = _configuration.GetSection("section2");
                if (!selection.Exists())
                {
                    throw new System.Exception("section2 does not exist.");
                }

    绑定数组

    //将节点下的数据绑定到节点下
      string [] _array = _configuration.GetSection("Logging:LogLevel").Get<string []>();
    
      foreach (var item in _array)
      {
         Console.WriteLine(item);
      }

     对应我们节点下的appsettings.json文件

     通过实例化ConfigurationBuilder()也可以创建IConfigurationRoot进行文件读取

    
    
    var builder = new ConfigurationBuilder()
                 //.SetBasePath("./")
                 .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);
                //.AddEnvironmentVariables();
    
                var configurationRoot = builder.Build();
    
                this.Configuration = configurationRoot;
  • 相关阅读:
    写给大家看的设计书(第3版)
    C#总结2012
    python 网络编程学习 1
    深入 聚集索引与非聚集索引(一)
    深研TCP/IP详解卷1开篇
    在实际项目中如何应用门面模式(Facade)
    MVC系列_权限管理之权限控制
    gae上部署了一个定时往手机发送天气预报的小python程序
    ASP.NET开发工具整理第二季
    python 实现文件的递归拷贝
  • 原文地址:https://www.cnblogs.com/xianchengzhang/p/14081098.html
Copyright © 2020-2023  润新知