.Net Core appsettings.json 最佳实践 - 覆盖开发设置(或反之亦然)?

2024-05-10

寻找一种关于在 .Net Core 中构造 appsettings.json 文件的合理方法。

是否应该将基本“appsettings.json”文件配置为在开发环境中运行,然后基于环境的覆盖(例如 appsettings.Production.json)覆盖生产的特定密钥?

或者 appsettings.json 应该只包含在所有环境中共享的配置,然后使用特定的 appsettings.development/staging.json 文件来显式设置这些环境的密钥?

我担心的是 - 假设应用程序部署到实时服务器,但存储在环境变量中的密钥(例如覆盖连接字符串)丢失或拼写错误等。在这种情况下,应用程序将回退到基本 appsettings.json连接字符串对于实时环境来说是不正确的数据库。这样的场景听起来相当灾难性,特别是因为这很容易被忽视?

因此,问题实际上归结为 - 基础 appsettings.json 文件的内容是否应该为默认值(例如开发数据库、沙箱 API),并被生产数据覆盖,或者反之亦然?


更新:我想补充一点,我不再使用 Azure 应用程序配置,仅使用 KeyVault。我很失望的是,定价允许每个订阅 1 个免费 AppConfig,然后似乎对第一个之后的每个订阅每天收取超过 1.20 美元的 CDN。对我来说,这意味着每月要额外支付 36 美元来购买每天只使用一次的东西(假设我让网络应用程序在晚上关闭)。价格点根本没有任何意义。我会尽快使用多个 KeyVault,因为它们的成本看起来纯粹基于使用情况,并且每数千笔交易的成本微薄。我不明白 AppConfig 的预期用例是什么来证明其价格点的合理性。


我已经养成了将配置存储在 Azure 中的 AzureAppConfig 和/或 AzureKeyVault 下的习惯。它为我提供了一个集中位置来管理我的开发、登台/测试、生产设置,并且不需要我通过操作 appsettings 文件或将它们存储在某种部署存储库中来使部署复杂化。它实际上只在应用程序启动时从 azure 读取(我不需要在应用程序运行时刷新它们)。话虽如此,这使得本地开发故事变得有点有趣,因为我个人希望操作顺序是appsettings.json, appsettings.{environment}.json, AzureAppConfig, KeyVault,那么最后secrets.json。这样,无论如何,我都可以使用本地机密文件覆盖 azure 中的设置(即使我覆盖的设置在技术上不是秘密)。

我基本上最终编写了一些自定义代码program.cs处理从 Azure 加载配置源,然后完成查找JsonConfigurationSource那个有一个Path of "secrets.json",然后将其作为我的最后一项IConfigurationBuilder.Sources.

对我来说,我的文件的使用方式如下

  • appsettings.json- 需要为任何环境设置的通用设置,并且将likely永远不会因环境而改变。appsettings.{environment}.json- 大部分只是空的 JSON 文件,基本上只是命名AzureAppConfig & AzuerKeyVault要连接的资源名称
  • AzureAppConfig- 基本上对于生产、登台/测试或本地开发之间的任何不同,AND 不是敏感信息。 API 端点地址、IP 地址、各种 URL、错误日志信息等等。
  • AzureKeyVault- 任何敏感的事情。用户名、密码、外部 API 密钥(身份验证、许可证密钥、连接字符串等)。

问题是,即使你设置了appsettings.json,这并不意味着你不能用appsettings.{enviroment}.json或者别的地方。我经常将设置放在根设置文件中,其值为NULL,只是为了提醒我这是应用程序中使用的设置。所以一个更好的问题可能是,您是否希望能够运行您的应用程序(没有错误),除了基础之外什么都没有appsettings.json and secrets.json?或者内容来自appsettings.{enviroment}.json总是需要成功启动?

根据您的问题要查看的另一件事是对您的配置的验证。以后的版本Microsoft.Extensions.Options提供各种方法来验证您的选项,以便您可以尝试捕获某些内容为空/未定义的实例。我通常用数据注释属性来装饰 POCO Options 类,然后使用ValidateDataAnnotations()验证它们的设置是否正确。

例如

services.AddOptions<MailOptions>().Bind(configuration.GetSection("MailSettings")).ValidateDataAnnotations();

值得注意的是,仅当您尝试请求类似以下内容时,此验证才会运行MailOptions我使用上面的例子,来自 DI(所以不是在启动时) 为此,我也创建了你自己的IStartupFilter在应用程序启动时抢先向服务提供商请求一个或多个选项类,以便在应用程序开始接受请求之前强制运行相同的验证。

public class EagerOptionsValidationStartupFilter : IStartupFilter
{
    public readonly ICollection<Type> EagerValidateTypes = new List<Type>();
    private readonly IServiceProvider serviceProvider;

    public EagerOptionsValidationStartupFilter(IServiceProvider serviceProvider)
    {
        this.serviceProvider = serviceProvider;
    }

    public Action<IApplicationBuilder> Configure(Action<IApplicationBuilder> next)
    {
        foreach (var eagerType in EagerValidateTypes)
        {
            dynamic test = serviceProvider.GetService(typeof(IOptions<>).MakeGenericType(eagerType));
            _ = test.Value;
        }

        return next;
    }
}

startup.cs

public void ConfigureServices(IServiceCollection services)
{

    services.AddTransient<IStartupFilter>(x =>
        new EagerOptionsValidationStartupFilter(x)
        {
            EagerValidateTypes = {
                typeof(MailOptions),
                typeof(OtherOptions),
                typeof(MoreImportantOptions)
            }
        });
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

.Net Core appsettings.json 最佳实践 - 覆盖开发设置(或反之亦然)? 的相关文章

随机推荐

  • 在 EmberJS 中获取父路由

    我正在制作一个可重用 有点多态 的评论小部件 我想要一个按钮 使我能够返回到父路由 例如 如果我位于 blog posts 1 comments 我希望该按钮将我带回 blog posts 1 我目前正在使用transitionToRout
  • 如何使用 JQuery 隐藏和显示 HTML 元素?

    如何使用 JQuery 隐藏和显示 HTML 元素而不产生任何特殊效果 使用hide http docs jquery com Effects hide and show http docs jquery com Effects show方
  • 如何自定义JProgressBar?

    我正在制作一个启动器 我想要一个自定义的进度栏 我已经做了一些研究 并且可以使用 JavaFX 从未用它做过任何事情 并且可以通过替换 UI 来实现 我正在寻找一个具有圆形边缘和圆形填充的酒吧 像这样的事情 package gui impo
  • EXC_BAD_INSTRUCTION 的 CoreData 错误(代码=EXC_I386_INVOP,子代码=0x0)

    当我打开并发调试开关 com apple CoreData ConcurrencyDebug 1 来跟踪 CoreData 的所有并发问题时 在调用 insertingNewObjectForEntityForName 时不断发生崩溃 Xc
  • Google Apps 脚本:在电子邮件中发送 PDF 而不是 .zip 文件

    我有这段代码 可以从 Google 电子表格生成 PDF 文件并将其作为电子邮件附件发送 问题是它压缩文件const zipBlob Utilities zip blobs setName ss getName zip 我想更改它 以便附加
  • 在 JavaScript 中引用 C# 变量

    我已经阅读了很多线程 但我不明白为什么这不起作用 我正在创建一个将用作导航栏的 SharePoint Web 部件 一切都很顺利 直到我尝试在 JS 代码中引用 C 变量 这是来自 VisualWebPart1UserControl asc
  • 使用 PHP 比较两个字符串的相似度

    嘿伙计们 我想寻求一些解决方案 现在我有字典了单词 txt 这里有一些例子 happy laugh sad 我有俚语字符串 hppy 我想要搜索和匹配那个俚语字符串我的字典这意味着它将返回 happy 因为这些字符串参考 快乐 in 字典
  • 如何解决创建 SwiftData #Predicate 的编译器错误?

    我一直在尝试很多方法来解决这个问题 我正在尝试使用谓词获取 SwiftData 记录 但我尝试的一切都会导致两个错误 初始化程序 init 要求 Item 符合 Encodable 初始化程序 init 要求 Item 符合 Decodab
  • 从源安全导出

    有没有办法从 Source Safe 导出文件 文件夹 即删除所有 scc 文件 就像 SVN 导出一样 只需进行常规获取 然后运行类似的操作 ATTRIB R scc S DEL F S Q scc 第一个命令从这些文件中删除只读标志 第
  • 使用 Python 抓取维基百科数据

    我正在尝试从以下内容中检索 3 列 NFL 球队 球员姓名 大学球队 维基百科页面 http en wikipedia org wiki 2008 NFL draft 我是 python 新手 一直在尝试使用 beautifulsoup 来
  • pandas 两个数据框交叉连接[重复]

    这个问题在这里已经有答案了 我找不到有关交叉联接的任何内容 包括合并 联接或其他一些内容 我需要使用 my function 作为 myfunc 处理两个数据帧 相当于 for itemA in df1 iterrows for itemB
  • 使用 Jasmine 模拟 jQuery ajax 调用

    我正在使用 Jasmine 2 5 2 为使用 jQuery 3 1 1 执行 Ajax 请求的代码编写单元测试 我想模拟 Ajax 调用 提供我自己的响应状态和文本 我正在使用 Jasmine ajax 插件 https github c
  • 如何从 silverlight 中的视图模型从一个视图导航到另一个视图?

    我有一个 ViewModel 和两个 View 如何从 ViewModel 导航到 View2 我在某处读到我们需要使用 PRISM 在 Silverlight 中从 ViewModel 打开多个视图 PRISM 有什么替代方案吗 理想情况
  • 访问特征矩阵的行向量时复制或引用

    我正在使用的代码Eigen http eigen tuxfamily org index php title Main Page矩阵库 我注意到在整个代码中 有如下访问器 RowVector3f V size t vertex index
  • 使用 C#.net 中的私有存储库的身份验证读取 BitBucket API

    我已经尝试了几天让 BitBucket API 为我工作 但是当涉及到让它为具有身份验证的私有存储库工作时 将问题设置为私有 当它们设置为公开 无需身份验证 一切正常 代码示例如下 static void Main string args
  • gcc 不太可能使用宏

    我正在编写一段关键代码 其逻辑大致如下 if expression is true do something with extremely low latency before the nuke blows up This branch i
  • 在python中调用subprocess.Popen时“系统找不到指定的文件”

    我正在尝试使用svnmerge py合并一些文件 它在底层使用 python 当我使用它时 我收到一个错误 系统找不到指定的文件 工作中的同事正在运行相同版本的svnmerge py 以及 python 2 5 2 特别是 r252 609
  • Caliburn micro 处于无应用程序对象模式,就像在 AutoCAD dll 插件中一样

    我正在使用 Caliburn Micro 开发 WPF 应用程序 该应用程序的一些视图需要加载到 AutoCAD 环境中 AutoCAD 编程环境允许开发 AutoCAD 插件 dll 类型 并将其加载到 AutoCAD 环境中 由于 Au
  • ajax 调用成功后点击链接 href

    我有一个正常的链接 a href http www google com class continue Continue a 我已将点击绑定到一个事件来发布 ajax 请求 如下所示 continue click function ajax
  • .Net Core appsettings.json 最佳实践 - 覆盖开发设置(或反之亦然)?

    寻找一种关于在 Net Core 中构造 appsettings json 文件的合理方法 是否应该将基本 appsettings json 文件配置为在开发环境中运行 然后基于环境的覆盖 例如 appsettings Production