配置文件'secrets.json'未找到且不可选 (.NET 6)

22

在 CI/CD 流水线中生成了“User Secrets”错误,但不应该期望找到 secrets.json 文件。

步骤:

  1. 创建 .NET 5 项目
  2. 添加用户机密。
  3. 代码在本地和 CI/CD 流水线中运行。
  4. 升级到 .NET 6 项目(并预览 NuGet 6.* 包)

代码在本地运行正常,但在 CI/CD 流水线中失败,并显示以下错误:

"The configuration file 'secrets.json' was not found and is not optional."

期望结果:

代码在没有 secrets.json 文件的情况下运行 配置 .NET 6, Microsoft.Extensions.Configuration.UserSecrets: 6.0.0-preview.1.21102.12

回归问题? 在 .NET 5 中可以正常工作,Microsoft.Extensions.Configuration.UserSecrets: 5.0.0.*

System.IO.FileNotFoundException: The configuration file 'secrets.json' was not found and is not optional. The physical path is '/home/runner/work/UserSecretsRegression/UserSecretsRegression/UserSecrets/UserSecrets.Tests/bin/Release/net6.0/secrets.json'.
  Stack Trace:
      at Microsoft.Extensions.Configuration.FileConfigurationProvider.HandleException(ExceptionDispatchInfo info)
   at Microsoft.Extensions.Configuration.FileConfigurationProvider.Load(Boolean reload)
   at Microsoft.Extensions.Configuration.FileConfigurationProvider.Load()
   at Microsoft.Extensions.Configuration.ConfigurationRoot..ctor(IList`1 providers)
   at Microsoft.Extensions.Configuration.ConfigurationBuilder.Build()
   at UserSecrets.Tests.UnitTest1.TestMethod1() in /home/runner/work/UserSecretsRegression/UserSecretsRegression/UserSecrets/UserSecrets.Tests/UnitTest1.cs:line 13

1
单元测试不应该依赖于机密信息(它们仅适用于开发机器)。您可以粘贴配置 ConfigurationBuilder 的单元测试的开始部分吗? - Neil
谢谢,是的我知道,那只是一个例子。 - Mehdi Daustany
您的堆栈跟踪显示了一条不是“secrets.json”路径的路径。用户机密存储在%UserProfile%\AppData\Roaming\Microsoft\UserSecrets\<projectSecretGuid>\secrets.json中。是否可能有人添加了对机密文件的直接引用,然后将该文件设置为“内容”/“复制到输出”? - Neil
3个回答

51

https://github.com/dotnet/runtime/issues/48485

基本上,.NET6 中的一个新功能是默认情况下 'secrets.json' 不再是可选项!

AddUserSecrets(this IConfigurationBuilder configuration, Assembly assembly, bool optional);

在你的代码中,应该将那个“可选”的参数设置为“true”。

 var configuration = new ConfigurationBuilder()
    .AddEnvironmentVariables()
    .AddCommandLine(args)
    .AddJsonFile("appsettings.json")
    .AddUserSecrets<Program>(true)
    .Build();

真的,true 帮了很多忙,而且 true 是一个改变游戏规则的东西,救了我的晚上。 - Maytham Fahmi
我正在添加准确的代码,但仍然无法从secrets.json获取usersecrets。即使将其从appdata文件夹放置在项目根目录中。关于程序集Program,它应该是什么?我对此感到困惑。 - coder9090
@coder9090 你是否将环境变量 DOTNET_ENVIRONMENT 设置为“Development”? - Neil
@Neil 是的。这是开发。 - coder9090
或者:.AddUserSecrets(Assembly.GetExecutingAssembly(), optional: true) - JohnB
显示剩余2条评论

5
与环境变量不同,用户密钥被放置在类似于appsettings.json的设置文件中。当您需要在文件之间复制键和值时,具有相似结构的项目外设置非常好,并且支持添加、删除和列出值,正如我稍后将在本帖子中展示的那样。
为了理解用户密钥,让我们从上一篇文章的示例中恢复。在那里,我有一个看起来像这样的appsettings.json文件:
{
  "AppSettings": {
    "ConnectionString": "http://localhost:9000"
  },
  ...
}

为了在单个计算机上覆盖 AppSettings:ConnectionString 设置,每个用户都需要添加一个相同名称的用户秘密。最简单的方法是右键单击项目并选择管理用户机密

enter image description here

这将创建并打开一个名为secrets.json的新空JSON文件。该文件位于C:\Users\<username>\AppData\Roaming\Microsoft\UserSecrets\<id>下,其中<username>与您的Windows用户匹配,是一个随机生成的GUID。这里要注意的重要事情是,该文件位于您的项目目录外。为了将secrets.json文件位置“绑定”到您的项目,Visual Studio向csproj文件添加了一些标记:
<PropertyGroup>
  <UserSecretsId>dda25df4-9a88-4a7e-8502-2134b74e4729</UserSecretsId>
</PropertyGroup>

如果您没有使用Visual Studio,您可以生成一个随机的GUID并手动添加<UserSecretsId>

如果您想覆盖AppSettings:ConnectionString设置,请在secrets.json文件中添加类似的结构:

{
  "AppSettings": {
    "ConnectionString": "http://localhost:9000?user=mehdidaustany&password=1234"
  }
}

你可以这样折叠设置:
{
  "AppSettings:ConnectionString": "http://localhost:9000?user=mehdidaustany&password=1234"
}

最后在您的项目根目录中添加创建好的 secrets.json


谢谢你的提示。对我来说,是在我将VS2022升级到最新版本17.2.5之后,它自动在项目属性中创建了一个条目(该项目已经在.Net 6.0中): <PropertyGroup> <UserSecretsId>dda25df4-9a88-4a7e-8502-2134b74e4729</UserSecretsId> </PropertyGroup>我卸载了项目,然后删除了该条目,问题得到了解决。我已经将所有机密存储在本地设置文件中,因此不需要更多的地方来存储不应该被检入Git仓库的机密。 - Stevey

4
在 .net 6.0 中,应用程序需要 secret.json 文件才能运行。如果你正在从 .net core 3.1 或 .net 5.0 迁移,以便在 .net 6.0 中运行应用程序,请按照以下步骤操作:
  1. 使用命令行工具在项目文件夹中运行 dotnet user-secrets init
  2. 确保在应用程序域的 ...\bin\Debug\net6.0 目录下有一个名为 secret.json 的文件。现在即使你的 secret.json 文件是空的也没关系。
按 F5 键并运行你的应用程序!

2
我对secrets.json的抱怨是该文件在VS2022中往往会完全消失,而在VS2019中并没有发生这种情况。我认为这是VS2022中的一个bug。 - MC9000
@MC9000,我在VS2019中遇到了同样的问题。这可能与我的同事提交他们的代码并将其拉下来有关。我的同事也会遇到同样的问题。这可能是项目文件中<UserSecretsId>属性被覆盖的原因。 - Lukas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接