.Net 控制台应用程序中的用户机密问题
Problems with user secrets in .Net console apps
我已经创建了一个 .Net 6 控制台应用程序。我添加了用户机密,但我只获得了 appsettings.json 文件中定义的值。我用的是 Visual Studio Professional 2022 版本 17.0.4.
初始步骤
- 从 Visual Studio 2022 的项目模板创建一个新的 .Net 6 控制台应用程序。
- 安装 Microsoft.Extensions.Hosting nuget 包(版本 6.0.0)。
- 安装 Microsoft.Extensions.Configuration.UserSecrets nuget 包(版本 6.0.0)。
- 添加 appsettings.json 文件并将复制到输出目录设置为始终复制。
- 右键单击项目并select管理用户机密。
代码
Program.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();
Worker.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;
}
}
GlobalSettings.cs:
public class GlobalSettings
{
public string Foo { get; set; }
public string Bar { get; set; }
}
.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>
appsettings.json:
{
"GlobalSettings": {
"Foo": "Normal Foo",
"Bar": "Normal Bar"
}
}
secrets.json:
{
"GlobalSettings": {
"Foo": "Secret Foo",
"Bar": "Secret Bar"
}
}
我试过的
- 检查 csproj 中的用户密码 ID 是否与文件夹匹配,它确实匹配了:C:\Users\Dennis\AppData\Roaming\Microsoft\UserSecrets\deedd476-f5d6-47f4-982e-1645c89789c7
- 重建项目。
- 已关闭 Visual Studio 2022 并再次以管理员身份 运行。
- 从头开始创建了一个新项目。
- 将代码与我同事的一个项目进行了比较。我找不到任何区别,但是当我 运行 它时他的代码有效。
- 将 IOptionsSnapshot 更改为 IOptions 和 IOptionsMonitor。
- 将 AddT运行sient 更改为 AddSingleton。
- 执行相同的步骤,但使用的是 .Net 5 项目。
谢谢。
我误解了 Host.CreateDefaultBuilder 方法的工作方式。根据文档(docs):
load app IConfiguration from User Secrets when EnvironmentName is 'Development' using the entry assembly
我的环境是生产环境(可能是回退值)。它在我同事的项目中有效,因为它包含一个 launchSettings.json 文件,其中 DOTNET_ENVIRONMENT 环境变量设置为 Development。
我已经创建了一个 .Net 6 控制台应用程序。我添加了用户机密,但我只获得了 appsettings.json 文件中定义的值。我用的是 Visual Studio Professional 2022 版本 17.0.4.
初始步骤
- 从 Visual Studio 2022 的项目模板创建一个新的 .Net 6 控制台应用程序。
- 安装 Microsoft.Extensions.Hosting nuget 包(版本 6.0.0)。
- 安装 Microsoft.Extensions.Configuration.UserSecrets nuget 包(版本 6.0.0)。
- 添加 appsettings.json 文件并将复制到输出目录设置为始终复制。
- 右键单击项目并select管理用户机密。
代码
Program.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();
Worker.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;
}
}
GlobalSettings.cs:
public class GlobalSettings
{
public string Foo { get; set; }
public string Bar { get; set; }
}
.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>
appsettings.json:
{
"GlobalSettings": {
"Foo": "Normal Foo",
"Bar": "Normal Bar"
}
}
secrets.json:
{
"GlobalSettings": {
"Foo": "Secret Foo",
"Bar": "Secret Bar"
}
}
我试过的
- 检查 csproj 中的用户密码 ID 是否与文件夹匹配,它确实匹配了:C:\Users\Dennis\AppData\Roaming\Microsoft\UserSecrets\deedd476-f5d6-47f4-982e-1645c89789c7
- 重建项目。
- 已关闭 Visual Studio 2022 并再次以管理员身份 运行。
- 从头开始创建了一个新项目。
- 将代码与我同事的一个项目进行了比较。我找不到任何区别,但是当我 运行 它时他的代码有效。
- 将 IOptionsSnapshot 更改为 IOptions 和 IOptionsMonitor。
- 将 AddT运行sient 更改为 AddSingleton。
- 执行相同的步骤,但使用的是 .Net 5 项目。
谢谢。
我误解了 Host.CreateDefaultBuilder 方法的工作方式。根据文档(docs):
load app IConfiguration from User Secrets when EnvironmentName is 'Development' using the entry assembly
我的环境是生产环境(可能是回退值)。它在我同事的项目中有效,因为它包含一个 launchSettings.json 文件,其中 DOTNET_ENVIRONMENT 环境变量设置为 Development。