.Net 控制台应用程序中的用户机密问题

Den*_*nis 6 .net c# configuration dependency-injection .net-6.0

我创建了一个 .Net 6 控制台应用程序。我添加了用户密码,但我只获取 appsettings.json 文件中定义的值。我使用 Visual Studio Professional 2022 版本 17.0.4。

初始步骤

  1. 从 Visual Studio 2022 的项目模板创建新的 .Net 6 控制台应用程序。
  2. 安装 Microsoft.Extensions.Hosting nuget 包(版本 6.0.0)。
  3. 安装 Microsoft.Extensions.Configuration.UserSecrets nuget 包(版本 6.0.0)。
  4. 添加 appsettings.json 文件并将“复制到输出目录”设置为“始终复制”。
  5. 右键单击该项目并选择管理用户机密。

代码

程序.cs

using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

var host = Host.CreateDefaultBuilder()
                .ConfigureServices((context, services) => 
                {
                    services.Configure<GlobalSettings>(context.Configuration.GetSection("GlobalSettings"));
                    services.AddTransient<Worker>();
                })
                .Build();

var work = host.Services.GetRequiredService<Worker>();
await work.ExecuteAsync();
Run Code Online (Sandbox Code Playgroud)

工人.cs

using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;

public class Worker
{
    private readonly ILogger<Worker> _logger;
    private readonly GlobalSettings _globalSettings;

    public Worker(ILogger<Worker> logger, IOptions<GlobalSettings> globalSettings)
    {
        _logger = logger;
        _globalSettings = globalSettings.Value;
    }

    public async Task ExecuteAsync()
    {
        _logger.LogInformation(_globalSettings.Foo);
        _logger.LogInformation(_globalSettings.Bar);
        await Task.CompletedTask;
    }
}
Run Code Online (Sandbox Code Playgroud)

全局设置.cs:

public class GlobalSettings
{
    public string Foo { get; set; }
    public string Bar { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

.csproj:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net6.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>disable</Nullable>
    <UserSecretsId>deedd476-f5d6-47f4-982e-1645c89789c7</UserSecretsId>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="6.0.0" />
    <PackageReference Include="Microsoft.Extensions.Hosting" Version="6.0.0" />
  </ItemGroup>
  <ItemGroup>
    <None Update="appsettings.json">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </None>
  </ItemGroup>
</Project>
Run Code Online (Sandbox Code Playgroud)

应用程序设置.json:

{
    "GlobalSettings": {
        "Foo": "Normal Foo",
        "Bar": "Normal Bar"
    }
}
Run Code Online (Sandbox Code Playgroud)

秘密.json:

{
    "GlobalSettings": {
        "Foo": "Secret Foo",
        "Bar": "Secret Bar"
    }
}
Run Code Online (Sandbox Code Playgroud)

我尝试过的

  • 检查 csproj 中的用户密钥 ID 是否与文件夹匹配,它确实如此:C:\Users\Dennis\AppData\Roaming\Microsoft\UserSecrets\deedd476-f5d6-47f4-982e-1645c89789c7
  • 重建了项目。
  • 关闭 Visual Studio 2022 并以管理员身份再次运行它。
  • 从头开始创建了一个新项目。
  • 将代码与我同事的一个项目进行了比较。我找不到任何区别,但他的代码在我运行时可以工作。
  • 将 IOptionsSnapshot 更改为 IOptions 和 IOptionsMonitor。
  • 将 AddTransient 更改为 AddSingleton。
  • 执行相同的步骤,但使用 .Net 5 项目。

谢谢。

Den*_*nis 9

我误解了 Host.CreateDefaultBuilder 方法的工作方式。根据文档(docs):

当环境名称为“开发”时,使用入口程序集从用户机密加载应用程序 IConfiguration

我的环境是生产环境(可能是后备值)。它在我同事的项目中起作用,因为它包含一个 launchSettings.json 文件,其中 DOTNET_ENVIRONMENT 环境变量设置为 Development。