8.1 基础

1.传统Web.config配置的缺点,无法完成配置集群的管理
2.为了兼容传统的.NET Framework,仍然可以使用Web.config和ConfigurationManager类,但不推荐了
3..NET中的配置系统支持丰富的配置源,包括文件(json\xml\ini等)、注册表、环境变量、命令行、Azure Key Vault等,还可以配置自定义配置源。可以跟踪配置的改变,可以按照优先级覆盖

8.1.1 Json文件配置

image.png
注意下面代码中optional false表示json文件存在就读取,不存在就不读 true表示不存在就报错
reloadOnChange:配置文件更改后是否重新加载。
image.png
Microsoft.Extensions.Configuration的使用
JSON文件:

  1. {
  2. "AppConfig": {
  3. "DbConnection": "Server=;port=;database=",
  4. "EnableTrace": false,
  5. "IpWhiteList": [
  6. "127.0.0.1",
  7. "1.1.2.1",
  8. "2.3.1.5"
  9. ],
  10. "Port": 123,
  11. "ServiceName": "myapi"
  12. },
  13. "Student": [
  14. {
  15. "name": "yzk",
  16. "age": 18
  17. },
  18. {
  19. "name": "albert",
  20. "age": 18
  21. }
  22. ],
  23. "Teacher": [
  24. {
  25. "name": "albertzhao",
  26. "age": 25
  27. },
  28. {
  29. "name": "yangzhongke",
  30. "age": 40
  31. }
  32. ]
  33. }

代码:

  1. using Microsoft.Extensions.Configuration;
  2. using System;
  3. using System.Collections;
  4. using System.Collections.Generic;
  5. using System.Linq;
  6. namespace _210722_Demon01_JsonConfigure {
  7. class Program {
  8. static void Main(string[] args) {
  9. ConfigurationBuilder configurationBuilder = new ConfigurationBuilder();
  10. configurationBuilder.AddJsonFile("webconfig.json", true, true);
  11. IConfigurationRoot configurationRoot = configurationBuilder.Build();
  12. AppConfig appConfig = new AppConfig();
  13. //取子范围的一个元素值
  14. appConfig.DbConnection = configurationRoot["AppConfig:DbConnection"];
  15. //取子范围元素值的第二种写法,先获得一个域,域下面的["DbConnection"]
  16. appConfig.EnableTrace = configurationRoot.GetSection("AppConfig")["EnableTrace"];
  17. //取数组的写法 取AppConfig:IpWhiteList的全部子元素,选取子元素中的value
  18. appConfig.IpWhiteList = (IEnumerable<string>)configurationRoot.GetSection("AppConfig:IpWhiteList").GetChildren().Select(x=>x.Value);
  19. foreach (var item in appConfig.IpWhiteList) {
  20. Console.WriteLine(item);
  21. }
  22. Console.ReadLine();
  23. }
  24. }
  25. class AppConfig {
  26. public string DbConnection { get; set; }
  27. public string EnableTrace { get; set; }
  28. public IEnumerable<string> IpWhiteList { get; set; }
  29. }
  30. }

8.1.2 Json序列化

https://www.json.cn/json/json2csharp.html Json转换为实体类

8.1.3 Json绑定读取配置(*)

image.png
https://www.json.cn/json/json2csharp.html进行json转C#类,直接new实例,根节点的大类直接root.Get() 其余小类则可通过GetSection(“小类名”).Get<小类类型>()来new出来

  1. using System;
  2. using System.Collections.Generic;
  3. using Microsoft.Extensions.Configuration;
  4. using Microsoft.Extensions.Configuration.Json;
  5. namespace _210723_Demon01_JsonTransferClass {
  6. class Program {
  7. static void Main(string[] args) {
  8. ConfigurationBuilder configurationBuilder = new ConfigurationBuilder();
  9. configurationBuilder.AddJsonFile("webconfig.json", false, true);
  10. var configurationRoot = configurationBuilder.Build();
  11. //绑定一个对象来进行转换
  12. Root root = configurationRoot.Get<Root>();
  13. AppConfig appConfig = configurationRoot.GetSection("AppConfig").Get<AppConfig>();
  14. Console.WriteLine(appConfig.DbConnection);
  15. Console.ReadLine();
  16. }
  17. }
  18. public class AppConfig {
  19. /// <summary>
  20. ///
  21. /// </summary>
  22. public string DbConnection { get; set; }
  23. /// <summary>
  24. ///
  25. /// </summary>
  26. public string EnableTrace { get; set; }
  27. /// <summary>
  28. ///
  29. /// </summary>
  30. public List<string> IpWhiteList { get; set; }
  31. /// <summary>
  32. ///
  33. /// </summary>
  34. public int Port { get; set; }
  35. /// <summary>
  36. ///
  37. /// </summary>
  38. public string ServiceName { get; set; }
  39. }
  40. public class StudentItem {
  41. /// <summary>
  42. ///
  43. /// </summary>
  44. public string name { get; set; }
  45. /// <summary>
  46. ///
  47. /// </summary>
  48. public int age { get; set; }
  49. }
  50. public class TeacherItem {
  51. /// <summary>
  52. ///
  53. /// </summary>
  54. public string name { get; set; }
  55. /// <summary>
  56. ///
  57. /// </summary>
  58. public int age { get; set; }
  59. }
  60. public class Root {
  61. /// <summary>
  62. ///
  63. /// </summary>
  64. public AppConfig AppConfig { get; set; }
  65. /// <summary>
  66. ///
  67. /// </summary>
  68. public List<StudentItem> Student { get; set; }
  69. /// <summary>
  70. ///
  71. /// </summary>
  72. public List<TeacherItem> Teacher { get; set; }
  73. }
  74. }

8.2 IOptionsSnapshot 选项配置

image.png
image.png
目录结构:image.png
webconfig内容:

  1. {
  2. "AppConfig": {
  3. "DbConnection": "Server=;port=;database=",
  4. "EnableTrace": false,
  5. "IpWhiteList": [
  6. "127.0.0.1",
  7. "1.1.2.1",
  8. "2.3.1.5"
  9. ],
  10. "Port": 55155,
  11. "ServiceName": "albertservice"
  12. },
  13. "Student": [
  14. {
  15. "name": "yzk",
  16. "age": 18
  17. },
  18. {
  19. "name": "albert",
  20. "age": 18
  21. }
  22. ],
  23. "Teacher": [
  24. {
  25. "name": "albertzhao",
  26. "age": 25
  27. },
  28. {
  29. "name": "yangzhongke",
  30. "age": 40
  31. }
  32. ]
  33. }

Root类:

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. namespace _210723_Demon02_JsonDIIOptionsSnapshot {
  7. public class Root {
  8. /// <summary>
  9. ///
  10. /// </summary>
  11. public AppConfig AppConfig { get; set; }
  12. /// <summary>
  13. ///
  14. /// </summary>
  15. public List<StudentItem> Student { get; set; }
  16. /// <summary>
  17. ///
  18. /// </summary>
  19. public List<TeacherItem> Teacher { get; set; }
  20. }
  21. public class AppConfig {
  22. /// <summary>
  23. ///
  24. /// </summary>
  25. public string DbConnection { get; set; }
  26. /// <summary>
  27. ///
  28. /// </summary>
  29. public string EnableTrace { get; set; }
  30. /// <summary>
  31. ///
  32. /// </summary>
  33. public List<string> IpWhiteList { get; set; }
  34. /// <summary>
  35. ///
  36. /// </summary>
  37. public int Port { get; set; }
  38. /// <summary>
  39. ///
  40. /// </summary>
  41. public string ServiceName { get; set; }
  42. }
  43. public class StudentItem {
  44. /// <summary>
  45. ///
  46. /// </summary>
  47. public string name { get; set; }
  48. /// <summary>
  49. ///
  50. /// </summary>
  51. public int age { get; set; }
  52. }
  53. public class TeacherItem {
  54. /// <summary>
  55. ///
  56. /// </summary>
  57. public string name { get; set; }
  58. /// <summary>
  59. ///
  60. /// </summary>
  61. public int age { get; set; }
  62. }
  63. }

IController接口和实现类以及扩展类TestControllerExtensions

  1. interface IController {
  2. void ReadAppConfig();
  3. }
  4. using Microsoft.Extensions.Options;
  5. using System;
  6. using System.Collections.Generic;
  7. using System.Linq;
  8. using System.Text;
  9. using System.Threading.Tasks;
  10. namespace _210723_Demon02_JsonDIIOptionsSnapshot {
  11. class TestController : IController {
  12. public readonly IOptionsSnapshot<Root> optionsSnapshot;
  13. public TestController(IOptionsSnapshot<Root> optionsSnapshot) {
  14. this.optionsSnapshot = optionsSnapshot;
  15. }
  16. public void ReadAppConfig() {
  17. //此处注意IOptionsSanpshot.Value才是实例
  18. Console.WriteLine(optionsSnapshot.Value.AppConfig.Port);
  19. Console.WriteLine(optionsSnapshot.Value.AppConfig.ServiceName);
  20. }
  21. }
  22. }
  23. public static class TestControllerExtensions {
  24. public static void AddTestController(this IServiceCollection service) {
  25. service.AddScoped<IController, TestController>();
  26. }
  27. }

AppConfig类以及AppConfigExtensions类:

  1. public class AppConfigController {
  2. public readonly IOptionsSnapshot<AppConfig> optionsSnapshot;
  3. public AppConfigController(IOptionsSnapshot<AppConfig> optionsSnapshot) {
  4. this.optionsSnapshot = optionsSnapshot;
  5. }
  6. public void ShowAppConfigPort() {
  7. Console.WriteLine(this.optionsSnapshot.Value.Port);
  8. }
  9. }
  10. public static class AppConfigControllerExtensions {
  11. public static void AddAppConfig(this IServiceCollection services) {
  12. services.AddScoped<AppConfigController>();
  13. }
  14. }

主程序:
new ServiceCollection—services.AddTestController()—new ConfigurationBuilder—configuretionBuilder.AddJson(xxx)—var rootConfig = configuretionBuilder.Build()—
services.AddOptions().Configure(e => rootConfig.Bind(e))—BuildServiceProvider
此处必须将reloadOnChange设置为true,每次改变都要加载

  1. using Microsoft.Extensions.Configuration;
  2. using Microsoft.Extensions.DependencyInjection;
  3. using System;
  4. namespace _210723_Demon02_JsonDIIOptionsSnapshot {
  5. class Program {
  6. static void Main(string[] args) {
  7. var services = new ServiceCollection();
  8. //依赖注入,注入TestController对象和AppConfigController对象
  9. services.AddTestController();
  10. services.AddAppConfig();
  11. //services.AddScoped<IController, TestController>();
  12. //services.AddScoped<AppConfigController>();
  13. ConfigurationBuilder configurationBuilder = new ConfigurationBuilder();
  14. //此处必须将reloadOnChange设置为true,每次改变都要加载
  15. configurationBuilder.AddJsonFile("webconfig.json", false, true);
  16. var rootConfig = configurationBuilder.Build();
  17. //这边将rootConfig根节点绑定到Root对象上
  18. //将rootConfig的子域对象绑定到AppConfig对象
  19. services.AddOptions()
  20. .Configure<Root>(e => rootConfig.Bind(e))
  21. .Configure<AppConfig>(e=>rootConfig.GetSection("AppConfig").Bind(e));
  22. using (var sp = services.BuildServiceProvider()) {
  23. //上面必须进行根节点对象绑定到Root上,不然无法将IOptionsSnapshot<Root>对象通过构造函数注入
  24. while (true) {
  25. //如果此处不进行sp.CreateScope(),即使修改了本地的webconfig.json的内容也无效
  26. using (var scope = sp.CreateScope()) {
  27. scope.ServiceProvider.GetRequiredService<IController>().ReadAppConfig();
  28. scope.ServiceProvider.GetService<AppConfigController>().ShowAppConfigPort();
  29. }
  30. Console.WriteLine("请按任意键继续");
  31. Console.ReadKey();
  32. }
  33. }
  34. //Console.ReadLine();
  35. }
  36. }
  37. }

8.3 其他配置提供者

8.3.1 命令行方式配置

·配置框架还支持命令行参数、环境变量等地方读取
·NuGet安装 Microsoft.Extension.Configuration.CommandLine
·configBuilder.AddCommandLine(args)
·参数支持多种格式,比如:server=127.0.0.1、—server=127.0.0.1(注意在键值之间加空格)、/server=127.0.0.1、/server 127.0.0.1(注意在键值之间加空格)。格式不能混用。
·调试的时候,VS中简化命令行传参数的方法。
代码在Gitee中necore项目210907——Demo01_OterConfigProvider项目
扁平化配置
如果是多级结构,通过:来分开 proxy:address=szdxzhy@outlook.com(这样来赋值)
如果是数组,则需要:0 :1 :2来配置
image.png

8.3.2 环境变量方式配置

下面图片写错了,包的名字为Microsoft.Extensions.Configuration.EnvironmentVariables
如果使用带参数的,如configBuilder.AddEnvironmentVariables(“Albert_”),则需要在环境变量中添加前缀,防止修改全局的环境变量。
image.png
image.png

8.3.4 其他配置源

image.png

8.3.5 多配置源

image.png

8.3.6 User-secrets机制

user-secrets的配置不放到源代码中,Nuget安装Microsoft.Extensions.Configuration.UserSecrets。
在VS项目上右键【管理用户机密】,编辑配置文件,configurationBuilder.AddUserSecrets()
image.png
下图中usrsecrets放在普通配置文件之前:
image.png

  1. //依赖注入的容器Collection
  2. var serviceCollection = new ServiceCollection();
  3. //注入Config和Log
  4. serviceCollection.AddConfigService();
  5. serviceCollection.AddLogService();
  6. serviceCollection.AddMailService();
  7. //设置Option
  8. ConfigurationBuilder configurationBuilder = new ConfigurationBuilder();
  9. //[多配置源问题--后面的配置覆盖前面的配置]
  10. //通过数据库来获取中心配置,先写死进行测试
  11. //SqlConnection需要安装Nuget:System.Data.SqlClient
  12. //AddDbConfiguration来自Zack.AnyDBConfigProvider
  13. string strConfigFromSqlserver = "Server=192.168.0.238;Database=AlbertXDataBase;Trusted_Connection=True;";
  14. configurationBuilder.AddDbConfiguration(() => new SqlConnection(strConfigFromSqlserver),
  15. reloadOnChange: true,
  16. reloadInterval: TimeSpan.FromSeconds(2),
  17. tableName: "T_Configs");
  18. //从不泄密文件中读取账号密码:Secrets.Json
  19. configurationBuilder.AddUserSecrets<Program>();
  20. //如果要启用本地Json文件读取,则启用下面的代码,通过AddJsonFile来加载相关扁平化配置信息。
  21. configurationBuilder.AddJsonFile("AlbertConfig/mailconfig.json", false, true);
  22. //控制台
  23. configurationBuilder.AddCommandLine(args);
  24. //环境变量
  25. configurationBuilder.AddEnvironmentVariables("Albert_");
  26. //从mailconfig读取回来的根节点
  27. var rootConfig = configurationBuilder.Build();
  28. //绑定根节点到MailKitRoot实体对象上
  29. //这边的GetSection里面的字段是Json字符串的字段,一定要注意这名字和实体类的属性名
  30. //一定要相同,不然无法绑定成功
  31. //ToDo:NetCore下的AddOption原理剖析。
  32. serviceCollection.AddOptions().Configure<MailKitRoot>(e => rootConfig.Bind(e))
  33. .Configure<MailBodyEntity>(e => rootConfig.GetSection("MailBodyEntity").Bind(e))
  34. .Configure<SendServerConfigurationEntity>(e => rootConfig.GetSection("SendServerConfigurationEntity").Bind(e));
  35. //使用DI,Build一个服务提供者
  36. using (var sp = serviceCollection.BuildServiceProvider())
  37. {
  38. var sendMailResult = sp.GetRequiredService<IMailService>().SendMail();
  39. Console.WriteLine(sendMailResult.ResultInformation);
  40. Console.WriteLine(sendMailResult.ResultStatus);
  41. }
  42. }

8.4 配置优先级

读取配置默认顺序,后者会覆盖前者:
现有的IConfiguration(一般不需要在这个前面加)
项目根目录下appsettings.json
项目根目录下appsettings.{Environment}.json
用户机密
环境变量
命令行参数

读取appsetting.json中的keyvalue,通常数据库连接字符串放在这边

  1. {
  2. "Logging": {
  3. "LogLevel": {
  4. "Default": "Information",
  5. "Microsoft": "Warning",
  6. "Microsoft.Hosting.Lifetime": "Information"
  7. }
  8. },
  9. "AllowedHosts": "*",
  10. "MyKey": "我是嘻嘻嘻"
  11. }

Startup.cs类想获取,想要注入IConfiguration

  1. public Startup(IConfiguration configuration) {
  2. Configuration = configuration;
  3. }
  4. public IConfiguration Configuration { get; }

获取代码
乱码问题,需要将appsetting.json文件保存为UTF-8-无标签
VS设置“高级保存选项”:https://www.cnblogs.com/willingtolove/p/12121577.html

  1. .NET3.1
  2. public void Configure(IApplicationBuilder app, IWebHostEnvironment env) {
  3. if (env.IsDevelopment()) {
  4. app.UseDeveloperExceptionPage();
  5. }
  6. else {
  7. app.UseExceptionHandler("/Error");
  8. }
  9. app.Run(
  10. async context =>
  11. {
  12. //此处设置没啥用
  13. context.Response.ContentType = "text/plain;charset=utf-8";
  14. await context.Response.WriteAsync(Configuration["MyKey"]);
  15. }
  16. );
  17. app.UseStaticFiles();
  18. app.UseRouting();
  19. app.UseAuthorization();
  20. app.UseEndpoints(endpoints => {
  21. endpoints.MapRazorPages();
  22. });
  23. }
  24. .NET6-Program.cs
  25. var builder = WebApplication.CreateBuilder(args);
  26. //内存缓存
  27. builder.Services.AddMemoryCache();
  28. var app = builder.Build();
  29. // Configure the HTTP request pipeline.
  30. if (app.Environment.IsDevelopment())
  31. {
  32. app.UseSwagger();
  33. app.UseSwaggerUI();
  34. }
  35. //运行环境读取方法
  36. if (app.Environment.EnvironmentName == "AlbertTest")
  37. {
  38. Console.WriteLine(app.Environment.EnvironmentName);
  39. }

通过命令行来配置参数,到项目目录下,cmd
dotnet run MyKey=”我是命令行参数”
image.png

8.5 开发SelfProvider

Reinvent the wheel 重新造轮子=> 价值是是什么?对于程序员而言,一定要有自己造轮子的能力。

从学习这到创造者!

image.png

8.5.1 开发web.config提供者

  • FxConfigurationProvider
  1. 为项目添加Nuget包,Microsoft.Extensions.Configuration和Microsoft.Extensions.Configuration.FileExtensions
  2. 创建类FxConfigProvider,继承自FileConfigurationProvider抽象类
  3. 重写Load方法,其中Stream是文件流,从FileConfigurationSource中获取返回信息。image.png
  4. 在Load方法中将字符串拍平,通常的格式是“{第一级名称}:第二级名称”作为键,第二级名称作为值,对应起来,如下图:

image.png

  • FxConfigurationSource

image.png
同时在FxConfigurationProvider复写方法Load中,最后需要添加this.Data = data,将生成的字典赋值给它。

8.5.2 开发数据库配置提供者

中心化配置服务器
image.png

  1. 安装Sql Server:前往官网安装:https://www.microsoft.com/en-us/sql-server/sql-server-downloads

安装Developer或者基于云的,本机安装SSMS(https://docs.microsoft.com/zh-cn/sql/ssms/download-sql-server-management-studio-ssms?view=sql-server-ver15)进行数据库管理。验证数据库是否可以进行IP登录,如果不能按照如下配置并尝试关闭防火墙:数据库无法以IP登录问题解决

  1. 配置数据库,登录进去后,建库建表,表三个字段:ID(自增主键),Name,Value。

ID设置:设置主键—是标识(双击即可)
image.png
image.png

  1. 将配置信息写入数据库中,Value支持Json格式

image.png

  1. 将Json映射成C#类

image.png

  1. 安装Nuget程序包:https://www.nuget.org/packages/Zack.AnyDBConfigProvider/

    1. Install-Package Zack.AnyDBConfigProvider -Version 1.1.3
    2. Install-Package System.Data.SqlClient -Version 4.8.2
  2. 代码中调用:

    1. string strConfigFromSqlserver = "Server=192.168.0.238;Database=AlbertXDataBase;Trusted_Connection=True;";
    2. configurationBuilder.AddDbConfiguration(() => new SqlConnection(strConfigFromSqlserver),
    3. reloadOnChange: true,
    4. reloadInterval: TimeSpan.FromSeconds(2));

    8.6 配置系统综合案例

    功能需求:

  3. 系统的主要配置放到配置专用的数据库中

  4. 连接配置数据库的连接字符串配置在用户机密中
  5. 把Smtp的配置显示到界面上
  6. 程序启动就连接Redis,并把Redis连接对象著恶策到依赖注入的系统中

操作:如何在Program.cs里面读取配置
在appsettings.json或者其他机密文件中添加数据库连接字符串

  1. "SqlServer": {
  2. "ConnectStr": "Server = .; Database = AlbertConfigDb; Trusted_Connection = True;MultipleActiveResultSets=true;Connect Timeout=500"
  3. }

安装Zack.AnyDBConfigProvider包-安装System.Data.SqlClient
在Program中添加如下代码:

  1. //Zack.AnyDBConfigProvider里面的GetConnectionString读取的字符串是配置文件中的
  2. //而不是数据库中的,连接上数据库后,AddDbConfiguration才是从数据库中读取Json
  3. //这里Host和WebHost一个是主机一个是通用主机
  4. //如果想要启用builder.Configuration.GetConnectionString("con");
  5. //则需要在appsettings.json中配置“ConnectionStrings:con":"xxx"
  6. builder.WebHost.ConfigureAppConfiguration((hostCtx, configBuilder) => {
  7. var env = hostCtx.HostingEnvironment;
  8. var connStr = builder.Configuration.GetValue<string>("SqlServer:ConnectStr");
  9. configBuilder.AddDbConfiguration(() =>
  10. new SqlConnection(connStr),
  11. reloadOnChange: true,
  12. reloadInterval: TimeSpan.FromSeconds(2),
  13. tableName: "ProduceToolConfig");
  14. //开发模式下,保存项目程序集到用户机密
  15. if (env.IsDevelopment() && !string.IsNullOrEmpty(env.ApplicationName))
  16. {
  17. var appAssembly = Assembly.Load(new AssemblyName(env.ApplicationName));
  18. if (appAssembly != null)
  19. {
  20. configBuilder.AddUserSecrets(appAssembly, optional: true);
  21. }
  22. }
  23. });

安装StackExchange.Redis包,这样就可以直接启动Redis了

  1. //AddDbConfiguration之后即可从数据库中拿取Json对了
  2. builder.Services.AddSingleton<IConnectionMultiplexer>(sp =>
  3. {
  4. //在Program.cs中读取配置的一种方法
  5. var connStr = builder.Configuration.GetValue<string>("RedisServer:Configuration");
  6. return ConnectionMultiplexer.Connect(connStr);
  7. });

读取数据库中配置信息,直接绑定到SmtpSettings类上

  1. public class SmtpSettings
  2. {
  3. public string ServerName { get; set; }
  4. public string UserName { get; set; }
  5. public string Password { get; set; }
  6. }
  7. //配置选项:Smtp 注意这里的根是appsettings.json
  8. builder.Services.AddOptions().Configure<SmtpSettings>(smtp => builder.Configuration.GetSection("SmtpSettings").Bind(smtp));
  9. //调用
  10. using AlbertZhao.cn.Models;
  11. using Microsoft.AspNetCore.Http;
  12. using Microsoft.AspNetCore.Mvc;
  13. using Microsoft.Extensions.Options;
  14. using StackExchange.Redis;
  15. namespace AlbertZhao.cn.Controllers
  16. {
  17. [Route("api/[controller]/[action]")]
  18. [ApiController]
  19. public class SmtpController : ControllerBase
  20. {
  21. private readonly ILogger<SmtpController> logger;//日志服务
  22. private readonly IOptionsSnapshot<SmtpSettings> options;//配置选项服务
  23. private readonly IConnectionMultiplexer connectionMultiplexer;//Redis服务
  24. public SmtpController(ILogger<SmtpController> logger, IOptionsSnapshot<SmtpSettings> options, IConnectionMultiplexer connectionMultiplexer)
  25. {
  26. this.logger = logger;
  27. this.options = options;
  28. this.connectionMultiplexer = connectionMultiplexer;
  29. }
  30. [HttpGet]
  31. public ActionResult<SmtpSettings?> GetSmtpInfo()
  32. {
  33. logger.LogInformation("开始获取数据");
  34. return new SmtpSettings() { ServerName = options.Value.ServerName ,
  35. UserName = options.Value.UserName ,
  36. Password = options.Value.Password
  37. };
  38. }
  39. [HttpGet]
  40. public ActionResult<string?> GetRedisInfo()
  41. {
  42. logger.LogInformation("开始测试Redis");
  43. var ping = connectionMultiplexer.GetDatabase(0).Ping();
  44. return ping.ToString();
  45. }
  46. }
  47. }