前言

说道配置文件,基本大多数软件为了扩展性、灵活性都会涉及到配置文件,比如之前常见的app.config和web.config。然后再说.NET Core,很多都发生了变化。总体的来说技术在进步,新的方式更加轻量级,具有更好的扩展性,数据源更加多样性。

ASP.NET Core 应用可用的配置提供程序

提供程序 一下对象提供配置
Azure Key Vault 配置提供程序 Azure Key Vault
Azure 应用配置提供程序 Azure 应用程序配置
命令行配置提供程序 命令行参数
自定义配置提供程序 自定义源
环境变量配置提供程序 环境变量
文件配置提供程序 INI、JSON 和 XML 文件
Key-per-file 配置提供程序 目录文件
内存配置提供程序 内存中集合
用户机密 用户配置文件目录中的文件

配置提供程序的典型顺序为:

1.appsettings.json

2.appsettings.Environment.json

3.用户机密

4.使用环境变量配置提供程序通过环境变量提供。

5.使用命令行配置提供程序通过命令行参数提供。

注意: 通常的做法是将命令行配置提供程序添加到一系列提供程序的末尾,使命令行参数能够替代由其他提供程序设置的配置。

配置模型三要素

.NET Core的配置系统由三个核心对象构成,分别是IConfiguration、IConfigurationBuilder、IConfigurationSource。

  • IConfiguration:读取出来的配置信息最终会转换成一个IConfiguration对象供应用程序使用。
  • IConfigurationBuilder:IConfigurationBuilder是IConfiguration对象的构建者。
  • IConfigurationSource:则代表配置数据最原始的来源。

文件配置

读取INI文件配置

首先创建一个ASP .NET Core Web API项目,在主目录下添加MyIniConfig.ini文件。

ID=1
Title="INIConfig title"
Name="INIConfig name" [Logging:LogLevel]
Default=Information

在Program类中读取配置文件

    public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
} 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); config.AddEnvironmentVariables(); if (args != null)
{
config.AddCommandLine(args);
}
})
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}

新建一个名为SettingsController的控制器,读取配置文件。

    [Route("api/[controller]/[action]")]
[ApiController]
public class SettingsController : ControllerBase
{
private readonly IConfiguration Configuration;
public SettingsController(IConfiguration configuration)
{
Configuration = configuration;
}
public ContentResult INISetting()
{
int id = Configuration.GetValue<int>("ID");
var title = Configuration["Title"];
var defaultLogLevel = Configuration["Logging:LogLevel:Default"];
return Content($"ID:{id}\n" +$"Title:{title}\n"+
$"Default Log Level: {defaultLogLevel}");
}
}

利用PostMan可以看到已经读取到刚刚设置的INI文件。

读取Json配置文件。

新建ASP.NET Core Web API项目,在主目录下添加MyJsonConfig.json文件。

{
"ID": "1",
"Title": "My JsonConfig",
"Logging": {
"LogLevel": {
"Default": "Information"
}
}
}

在Program类中读取配置文件

    public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
} public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((hostingContext, config) =>
{
config.Sources.Clear(); var env = hostingContext.HostingEnvironment;
config.AddJsonFile("MyJsonConfig.json", optional: true, reloadOnChange: true);
config.AddEnvironmentVariables(); if (args != null)
{
config.AddCommandLine(args);
}
})
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}

新建一个名为SettingsController的控制器,读取配置文件。

    [Route("api/[controller]/[action]")]
[ApiController]
public class SettingsController : ControllerBase
{
private readonly IConfiguration Configuration;
public SettingsController(IConfiguration configuration)
{
Configuration = configuration;
}
public ContentResult JsonSetting()
{
int id = Configuration.GetValue<int>("ID");
var title = Configuration["Title"];
var defaultLogLevel = Configuration["Logging:LogLevel:Default"]; return Content($"ID:{id}\n" + $"Title:{title}\n" +
$"Default Log Level: {defaultLogLevel}");
}
}

利用PostMan可以看到已经读取到刚刚设置的Json文件。

读取XML文件

新建ASP.NET Core Web API项目,在主目录下添加MyXMLConfig.xml文件。

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<ID>1</ID>
<Title>MyXMLConfig Title</Title>
<Name>MyXMLConfig Name</Name>
<Logging>
<LogLevel>
<Default>Information</Default>
</LogLevel>
</Logging>
</configuration>

在Program类中读取配置文件

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

新建一个名为SettingsController的控制器,读取配置文件。

    [Route("api/[controller]/[action]")]
[ApiController]
public class SettingsController : ControllerBase
{
private readonly IConfiguration Configuration;
public SettingsController(IConfiguration configuration)
{
Configuration = configuration;
}
public ContentResult XmlSetting()
{
int id = Configuration.GetValue<int>("ID");
var title = Configuration["Title"];
var defaultLogLevel = Configuration["Logging:LogLevel:Default"]; return Content($"ID:{id}\n" + $"Title:{title}\n" +
$"Default Log Level: {defaultLogLevel}");
}
}

利用PostMan可以看到已经读取到XML文件的配置。

读取配置项的方法

说几个在读取配置项中比较常用的方法,大家可以根据上面例子,自己试一下,这里就不详细讲解了。

GetValue

ConfigurationBinder.GetValue 从配置中提取一个具有指定键的值,并将它转换为指定的类型。在上面的中int id = Configuration.GetValue("ID");就是利用这个方法获取指定类型。

GetSection

IConfiguration.GetSection 会返回具有指定子节键的配置子节。

GetChildren

IConfiguration.GetChildren 方法获取直接后代配置子节。

Exists

ConfigurationExtensions.Exists(IConfigurationSection)确定该部分是否具有 Value 或子级。

将配置绑定到对象

新建ASP.NET Core Web API项目,在主目录下添加MyArray.json文件。

{
"array": {
"entries": {
"0": "value0",
"1": "value1",
"2": "value2",
"3": "value3"
}
}
}

创建一个model。

    public class Model
{
public string[] Entries { get; set; }
}

在Program类中读取配置文件

    public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
} public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((hostingContext, config) =>
{
config.Sources.Clear();
var env = hostingContext.HostingEnvironment;
config.AddJsonFile("MyArray.json",optional: true,reloadOnChange: true);
config.AddEnvironmentVariables(); if (args != null)
{
config.AddCommandLine(args);
}
})
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}

新建一个名为SettingsController的控制器,读取配置文件。

    [Route("api/[controller]/[action]")]
[ApiController]
public class SettingsController : ControllerBase
{
private readonly IConfiguration Configuration;
public SettingsController(IConfiguration configuration)
{
Configuration = configuration;
}
public ContentResult ToModel()
{
array = Configuration.GetSection("array").Get<Model>();
string modelStr = null;
for (int j = 0; j < array.Entries.Length; j++)
{
modelStr += $"Index: {j} Value: {array.Entries[j]} \n";
} return Content(modelStr);
}
}

利用PostMan可以看到已经读取到绑定到Model的配置。

自定义配置

如果上面的方式还不能满足项目要求的话,还可以从数据库中读取配置信息。接下来我们通过实体框架(EF)读取数据库中配置信息(埋个伏笔,后续做个相关教程)。便于操作,这次使用内存数据库做配置源。

首先做一个创建一个实体。

    public class EFModel
{
public int ID { get; set; }
public string Name { get; set; }
public string Value { get; set; }
}

添加 EFConfigContext 以存储和访问配置的值。

    public class EFConfigContext:DbContext
{
public EFConfigContext(DbContextOptions options) : base(options)
{
} public DbSet<EFModel> Values { get; set; }
}

创建用于实现 IConfigurationSource 的类。

    public class EFConfigurationSource : IConfigurationSource
{
private readonly Action<DbContextOptionsBuilder> _optionsAction; public EFConfigurationSource(Action<DbContextOptionsBuilder> optionsAction)
{
_optionsAction = optionsAction;
} public IConfigurationProvider Build(IConfigurationBuilder builder)
{
return new EFConfigurationProvider(_optionsAction);
}
}

通过从 ConfigurationProvider 继承来创建自定义配置提供程序。 当数据库为空时,配置提供程序将对其进行初始化。

    public class EFConfigurationProvider:ConfigurationProvider
{
Action<DbContextOptionsBuilder> OptionsAction { get; }
public EFConfigurationProvider(Action<DbContextOptionsBuilder> optionsAction)
{
OptionsAction = optionsAction;
} public override void Load()
{
var builder = new DbContextOptionsBuilder<EFConfigContext>(); OptionsAction(builder); using (var dbContext =new EFConfigContext(builder.Options))
{
dbContext.Database.EnsureCreated(); Data =!dbContext.Values.Any()?CreateAndSaveValues(dbContext) : dbContext.Values.ToDictionary(c => c.Name, c => c.Value);
} } private static IDictionary<string, string> CreateAndSaveValues(EFConfigContext dbContext)
{
var configValues = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
{
{"name1","value1" },
{"name2","value2" },
{"name3","value3" }
}; dbContext.Values.AddRange(configValues.Select(v => new EFModel
{
Name = v.Key,
Value = v.Value
}).ToArray()); dbContext.SaveChanges(); return configValues;
}
}

使用 AddEFConfiguration 扩展方法将配置源添加到 ConfigurationBuilder。

    public static class EFExtensions
{
public static IConfigurationBuilder AddEFConfiguration(this IConfigurationBuilder builder,Action<DbContextOptionsBuilder> optionsAction)
{
return builder.Add(new EFConfigurationSource(optionsAction));
}
}

在 Program.cs 中使用自定义的 EFConfigurationProvider:

    public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
} public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((hostingContext, config) =>
{
config.Sources.Clear(); var env = hostingContext.HostingEnvironment; config.AddEFConfiguration(
options => options.UseInMemoryDatabase("InMemoryDb")); config.AddEnvironmentVariables(); if (args != null)
{
config.AddCommandLine(args);
}
})
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}

在Startup中通过依赖注入添加据库上下文服务,向控制器提供服务。

    public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
} public IConfiguration Configuration { get; } public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<EFConfigContext>(opt => opt.UseInMemoryDatabase("InMemoryDb"));
services.AddControllers();
} public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
} app.UseRouting(); app.UseAuthorization(); app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}

在控制器中注入服务,读取内存数据库中的数据。

    [Route("api/[controller]/[action]")]
[ApiController]
public class SettingsController : ControllerBase
{ private readonly EFConfigContext _efDbContext; public SettingsController( EFConfigContext efDbContext)
{
_efDbContext = efDbContext;
} public ActionResult<IEnumerable<EFModel>> EFSetting()
{
List<EFModel> list = _efDbContext.Values.ToList(); return list;
}
}

利用PostMan可以看到已经读取到我们自定义的配置源。



加一张整体的项目结构,方便大家理解。



最近疫情有些反复,出门做好个人防护,玩耍时别忘记学习。最后祝大家周末愉快!

ASP.NET Core 学习笔记 第四篇 ASP.NET Core 中的配置的更多相关文章

  1. ASP.NET Core 学习笔记 第五篇 ASP.NET Core 中的选项

    前言 还记得上一篇文章中所说的配置吗?本篇文章算是上一篇的延续吧.在 .NET Core 中读取配置文件大多数会为配置选项绑定一个POCO(Plain Old CLR Object)对象,并通过依赖注 ...

  2. VSTO学习笔记(四)从SharePoint 2010中下载文件

    原文:VSTO学习笔记(四)从SharePoint 2010中下载文件 上一次我们开发了一个简单的64位COM加载项,虽然功能很简单,但是包括了开发一个64位COM加载项的大部分过程.本次我们来给CO ...

  3. 路由其实也可以很简单-------Asp.net WebAPI学习笔记(一) ASP.NET WebApi技术从入门到实战演练 C#面向服务WebService从入门到精通 DataTable与List<T>相互转换

    路由其实也可以很简单-------Asp.net WebAPI学习笔记(一)   MVC也好,WebAPI也好,据我所知,有部分人是因为复杂的路由,而不想去学的.曾经见过一位程序猿,在他MVC程序中, ...

  4. ASP.NET MVC 学习笔记-7.自定义配置信息 ASP.NET MVC 学习笔记-6.异步控制器 ASP.NET MVC 学习笔记-5.Controller与View的数据传递 ASP.NET MVC 学习笔记-4.ASP.NET MVC中Ajax的应用 ASP.NET MVC 学习笔记-3.面向对象设计原则

    ASP.NET MVC 学习笔记-7.自定义配置信息   ASP.NET程序中的web.config文件中,在appSettings这个配置节中能够保存一些配置,比如, 1 <appSettin ...

  5. ASP.NET MVC 学习笔记-2.Razor语法 ASP.NET MVC 学习笔记-1.ASP.NET MVC 基础 反射的具体应用 策略模式的具体应用 责任链模式的具体应用 ServiceStack.Redis订阅发布服务的调用 C#读取XML文件的基类实现

    ASP.NET MVC 学习笔记-2.Razor语法   1.         表达式 表达式必须跟在“@”符号之后, 2.         代码块 代码块必须位于“@{}”中,并且每行代码必须以“: ...

  6. Asp.Net Core学习笔记:入门篇

    Asp.Net Core 学习 基于.Net Core 2.2版本的学习笔记. 常识 像Django那样自动检查代码更新,自动重载服务器(太方便了) dotnet watch run 托管设置 设置项 ...

  7. .net core学习笔记,组件篇:服务的注册与发现(Consul)初篇

    1.什么是服务注册中心? 在学习服务注册与发现时,我们要先搞明白到底什么是服务注册与发现. 在这里我举一个生活中非常普遍的例子——网购来简单说明,网购在我们日常生活中已经是非常普遍了,其实网购中的(商 ...

  8. Asp.net core Identity + identity server + angular 学习笔记 (第四篇)

    来说说 RBAC (role based access control) 这是目前全世界最通用的权限管理机制, 当然使用率高并不是说它最好. 它也有很多局限的. 我们来讲讲最简单的 role base ...

  9. ASP.NET Core 学习笔记 第三篇 依赖注入框架的使用

    前言 首先感谢小可爱门的支持,写了这个系列的第二篇后,得到了好多人的鼓励,也更加坚定我把这个系列写完的决心,也能更好的督促自己的学习,分享自己的学习成果.还记得上篇文章中最后提及到,假如服务越来越多怎 ...

随机推荐

  1. 聊一聊开闭原则(OCP).

    目录 简述 最早提出(梅耶开闭原则) 重新定义(多态开闭原则) 深入探讨 OCP的两个特点 对外扩展开放(Open for extension) 对内修改关闭 抽象 关闭修改.对外扩展? 简述 在面向 ...

  2. nmap使用命令(转载)原文地址https://www.jianshu.com/p/4030c99fcaee

  3. KMP算法解决字符串匹配问题

    要解决的问题 假设字符串str长度为N,字符串match长度为M,M <= N, 想确定str中是否有某个子串是等于match的.返回和match匹配的字符串的首字母在str的位置,如果不匹配, ...

  4. Shell系列(35)- for循环语法一简介及批量解压缩脚本

    for循环语法一 for 变量 in 值1 值2 值3 - do 程序 done 例子 需求:批量解压缩 脚本: #!/bin/bash cd /root/publicls *.tar.gz > ...

  5. sqlalchemy 查询结果转json个人解决方案

    参考了网上很多资料,自己搞了一个适合的 在model 内增加一个函数: class User(db.Model): __tablename__ = 'user' userid = db.Column( ...

  6. Phalcon多模块如何实现连接不同数据库 《Phalcon入坑指南系列 五》

    本系列目录 一.Phalcon在Windows上安装 <Phalcon入坑指南系列 一> 二.Phalcon入坑必须知道的功能<Phalcon入坑指南系列 二> 三.Phalc ...

  7. 全套Java教程_Java基础入门教程,零基础小白自学Java必备教程 #011 # 第十一单元 String&ArrayList #

    一.本单元知识点概述 (Ⅰ)知识点概述 二.本单元教学目标 (Ⅰ)重点知识目标 1.ArrayList集合的常用方法2.ArrayList存储数据和遍历数据3.String类的构造方法4.String ...

  8. JavaFx 监听剪切板实现(Kotlin)

    原文地址: JavaFx 监听剪切板实现(Kotlin) | Stars-One的杂货小窝 软件有个需求,想要实现监听剪切板的内容,若内容符合预期,则进行相关的操作,就可以免去用户手动粘贴的操作,提供 ...

  9. mysql创建库

    建库 GBK: create database test2 DEFAULT CHARACTER SET gbk COLLATE gbk_chinese_ci; UTF8: CREATE DATABAS ...

  10. 面试官:为什么需要Java内存模型?

    面试官:今天想跟你聊聊Java内存模型,这块你了解过吗? 候选者:嗯,我简单说下我的理解吧.那我就从为什么要有Java内存模型开始讲起吧 面试官:开始你的表演吧. 候选者:那我先说下背景吧 候选者:1 ...