个人网站设计公司,建购物网站如何运营,wordpress轻社区模板,做网站1万多块钱点击蓝字关注我在ASP.NET Core中#xff0c;如果修改了appsettings.json中的设置#xff0c;那么默认情况下就得重启网站才能生效。有没有办法在修改设置后自动刷新并应用呢#xff1f;背景首先#xff0c;我们看看默认模板建出来的 ASP.NET Core 网站#xff0c;配置文件… 点击蓝字关注我在ASP.NET Core中如果修改了appsettings.json中的设置那么默认情况下就得重启网站才能生效。有没有办法在修改设置后自动刷新并应用呢背景首先我们看看默认模板建出来的 ASP.NET Core 网站配置文件有两个appsettings.jsonappsettings.Development.json前者用于生产环境后者用于开发环境在Debug模式下会优先使用 appsettings.Development.json 的设置。在不显示指定的情况下Program.cs 中的CreateWebHostBuilder() 方法会读取这两个设置文件。为了便于维护大家通常会创建一个对应的class用来强类型匹配设置项。比如这样services.ConfigureAppSettings(Configuration.GetSection(nameof(AppSettings)));使用的时候用IOptions接口注入public Ctor(IOptionsAppSettings settings)如果你还不了解这种方法可以参见我之前写的文章https://edi.wang/post/2016/10/9/read-appsettings-aspnet-core 微信可能屏蔽了我的域名复制到浏览器能打开问题这种方法确实可以读取配置文件并使用强类型约束和使用。但个缺点就是在网站运行时如果修改了 appsettings.json 中的配置项是不会当场生效的必须重启网站才能应用。比如我博客的网页标题是来源于配置文件里的 SiteTitle如果我在网站运行时登录服务器后台改成 Edi.Wang Test是不会生效的必须得等下次网站重启。解决办法还是刚才我博客的例子我给标题赋值用的方法是在Razor页面里注入IOptions接口inject IOptionsAppSettings Settings然后赋值Settings.Value.SiteTitle解决办法非常简单换个接口用IOptionsSnapshot就行啦在C#类的构造函数里注入的话也是一样的改法inject IOptionsSnapshotAppSettings Settings对比一下这两个接口IOptions// Summary:// Used to retrieve configured TOptions instances.//// Type parameters:// TOptions:// The type of options being requested.public interface IOptionsout TOptions where TOptions : class, new()IOptionsSnapshot// Summary:// Used to access the value of TOptions for the lifetime of a request.//// Type parameters:// TOptions:public interface IOptionsSnapshotout TOptions : IOptionsTOptionswhere TOptions : class, new()会发现 IOptionsSnapshot 会针对每个单独的请求去重新读取一次配置而 IOptions 则是第一次读取完以后就将对象保存在内存里了。听说你想这样做网上搜索到的方法通常让你这样做修改Program.cs在CreateWebHostBuilder() 方法里加入这么一段...WebHost.CreateDefaultBuilder(args).ConfigureAppConfiguration((hostingContext, config) { config.SetBasePath(Directory.GetCurrentDirectory()); config.AddJsonFile(appsettings.json, optional: false, reloadOnChange: true); config.AddJsonFile(appsettings.Development.json, optional: false, reloadOnChange: true); config.AddEnvironmentVariables();})...这段代码的作用是让我们自己指定应用启动时加载哪些配置源在这个案例里我们依旧加载 appsettings.json 以及appsettings.Development.json。对于Json文件有一个参数是reloadOnChange表示是否在文件修改后重新读取并加载到内存里设为true。这段代码其实是没有必要的这样改完代码还是得重启网站才能让设置生效原因在强类型约束的时候使用的IOptions接口。关于为什么显示指定reloadOnChange: true是没有必要的可以做个简单测试我在appsettings.json里定义一个MySettings{ Logging: { LogLevel: { Default: Warning } }, MySettings: { Message: .NET Core Rocks! }, AllowedHosts: *}建立对应的classpublic class MySettings{ public string Message { get; set; }}注册服务public void ConfigureServices(IServiceCollection services){//... services.ConfigureMySettings(Configuration.GetSection(nameof(MySettings)));}依赖注入并输出结果public class HomeController : Controller{ protected IConfiguration Configuration; protected MySettings MySettings { get; set; } public HomeController( IOptionsMySettings settings null, IConfiguration configuration null) { if (settings ! null) MySettings settings.Value; Configuration configuration; } public IActionResult Index() { var m1 MySettings.Message; var m2 Configuration.GetSection(MySettings)[Message]; return Content($m1:{m1}, m2:{m2}); }}这时候我并没有写 reloadOnChange: true看看运行结果结果当然两者是一样的。然后我们在运行时热修改配置值刷新网页发现只有m2有变化。而这并不要求我显式指定reloadOnChange: true要想让两者都取到最新的配置使用上一节的方法把m1的注入改成IOptionsSnapshotMySettings现在再做热修改两者都能立即生效破解谜团刚才我们不指定reloadOnChange竟然也能做热修改令人懵逼我猜想这个reloadOnChange在最新版本的ASP.NET Core2.2中可能是默认启用的。关于这一点我竟然没有找到官方的资料不能确定这个参数的具体作用。但是ASP.NET Core是开源的不妨来看看源代码代码位置https://github.com/aspnet/Extensions最终发现原来CreateDefaultBuilder()方法里真的默认设置为reloadOnChange为true:大家可以亲眼看看https://github.com/aspnet/Extensions/blob/master/src/Hosting/Hosting/src/Host.cs好奇注孤生的程序员终于在折腾开源代码后得到了满足……结论ASP.NET Core 2.2 中如果要在运行时修改强类型配置无需设置reloadOnChange true只需要使用IOptionsSnapshot接口即可大功告成