C# .net核心工作程序服务(BackgroundService)无法加载用户机密

C# .net核心工作程序服务(BackgroundService)无法加载用户机密,c#,asp.net-core,.net-core,C#,Asp.net Core,.net Core,拥有一个.net core worker服务,其.net core版本为3.1.8,asp.net core版本为3.1.8,我在从worker服务加载用户机密时遇到了一个问题,但是在asp.net core项目中同样适用 从asp.net core和.net core辅助服务调用的通用方法 public static string GetFioApiKey(this IConfiguration configuration) => configuration[&q

拥有一个.net core worker服务,其.net core版本为3.1.8,asp.net core版本为3.1.8,我在从worker服务加载用户机密时遇到了一个问题,但是在asp.net core项目中同样适用

从asp.net core和.net core辅助服务调用的通用方法

public static string GetFioApiKey(this IConfiguration configuration)
            => configuration["PaymentServiceSecrets:FioApiKey"];
<Project Sdk="Microsoft.NET.Sdk.Worker">

  <PropertyGroup>
    <TargetFramework>netcoreapp3.1</TargetFramework>
    <UserSecretsId>8d19c97d-a2fb-4a51-a694-9635b9c0c42c</UserSecretsId>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.Extensions.Hosting" Version="3.1.8" />
    <PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="3.1.8" />
  </ItemGroup>
</Project>
public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureAppConfiguration(config => config.AddUserSecrets(Assembly.GetExecutingAssembly()))
                .ConfigureServices((hostContext, services) =>
                {
                    // simplified
                    

                    services.AddSingleton<IApplicationSettings>(applicationSettings =>
                    {
                        var appSettings = new ApplicationSettings
                        {
                            FioApiKey = config.GetFioApiKey()
                        };

                        
                        return appSettings;
                    });

                    services.AddHostedService<Worker>();
                });
    }
csproj工人服务部

public static string GetFioApiKey(this IConfiguration configuration)
            => configuration["PaymentServiceSecrets:FioApiKey"];
<Project Sdk="Microsoft.NET.Sdk.Worker">

  <PropertyGroup>
    <TargetFramework>netcoreapp3.1</TargetFramework>
    <UserSecretsId>8d19c97d-a2fb-4a51-a694-9635b9c0c42c</UserSecretsId>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.Extensions.Hosting" Version="3.1.8" />
    <PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="3.1.8" />
  </ItemGroup>
</Project>
public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureAppConfiguration(config => config.AddUserSecrets(Assembly.GetExecutingAssembly()))
                .ConfigureServices((hostContext, services) =>
                {
                    // simplified
                    

                    services.AddSingleton<IApplicationSettings>(applicationSettings =>
                    {
                        var appSettings = new ApplicationSettings
                        {
                            FioApiKey = config.GetFioApiKey()
                        };

                        
                        return appSettings;
                    });

                    services.AddHostedService<Worker>();
                });
    }

netcoreapp3.1
8d19c97d-a2fb-4a51-a694-9635b9c0c42c
工人服务的startup.cs

public static string GetFioApiKey(this IConfiguration configuration)
            => configuration["PaymentServiceSecrets:FioApiKey"];
<Project Sdk="Microsoft.NET.Sdk.Worker">

  <PropertyGroup>
    <TargetFramework>netcoreapp3.1</TargetFramework>
    <UserSecretsId>8d19c97d-a2fb-4a51-a694-9635b9c0c42c</UserSecretsId>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.Extensions.Hosting" Version="3.1.8" />
    <PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="3.1.8" />
  </ItemGroup>
</Project>
public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureAppConfiguration(config => config.AddUserSecrets(Assembly.GetExecutingAssembly()))
                .ConfigureServices((hostContext, services) =>
                {
                    // simplified
                    

                    services.AddSingleton<IApplicationSettings>(applicationSettings =>
                    {
                        var appSettings = new ApplicationSettings
                        {
                            FioApiKey = config.GetFioApiKey()
                        };

                        
                        return appSettings;
                    });

                    services.AddHostedService<Worker>();
                });
    }
公共静态IHostBuilder CreateHostBuilder(字符串[]args)=>
Host.CreateDefaultBuilder(args)
.ConfigureAppConfiguration(config=>config.AddUserSecrets(Assembly.getExecutionGassembly()))
.ConfigureServices((主机上下文,服务)=>
{
//简化
services.AddSingleton(应用程序设置=>
{
var appSettings=新应用程序设置
{
FioApiKey=config.GetFioApiKey()
};
返回appSettings;
});
services.AddHostedService();
});
}
发现github存在此问题,尝试应用解决方法,但仍然无效

您应该尝试此方法

public static YourConfigObject GetFioApiKey(this IConfiguration configuration)
            => configuration.GetSection("PaymentServiceSecrets").Get<YourConfigObject>();
public静态YourConfigObject GetFioApiKey(此IConfiguration配置)
=>configuration.GetSection(“PaymentServiceSecrets”).Get();
您应该试试这个

public static YourConfigObject GetFioApiKey(this IConfiguration configuration)
            => configuration.GetSection("PaymentServiceSecrets").Get<YourConfigObject>();
public静态YourConfigObject GetFioApiKey(此IConfiguration配置)
=>configuration.GetSection(“PaymentServiceSecrets”).Get();

通过将
程序.cs中的行放在下面,我能够从用户机密中获取值

hostContext.Configuration.GetSection("PaymentServiceSecrets:FioApiKey").Value

通过在
Program.cs
的下面一行输入,我能够从用户机密中获取值

hostContext.Configuration.GetSection("PaymentServiceSecrets:FioApiKey").Value
这里没有提到的一个“问题”是,在WorkerServices中,环境变量“DOTNET_environment”必须设置为“Development”,否则用户机密甚至不会尝试加载。这与ASP.Net项目中使用的“ASPNETCORE_环境”环境变量不同

Ie,在Properties/launchSettings.json中

{
  // .. Ommitted
  "profiles": {
    "MyWorkerService": {
      "commandName": "Project",
      "environmentVariables": {
        "DOTNET_ENVIRONMENT": "Development"
      }
    }
  }
}

通常,新的项目模板为您准备好了这一点,但在我的例子中,当将ASP.Net项目(不需要web服务器功能)转换为Worker服务时,launchSettings.json配置文件将“ASPNETCORE_环境”设置为“开发”,这在Worker服务中实际上是无用的。

One“明白了”这里没有提到的要求是,在WorkerServices中,环境变量“DOTNET_environment”必须设置为“Development”,否则用户机密甚至不会尝试加载。这与ASP.Net项目中使用的“ASPNETCORE_环境”环境变量不同

Ie,在Properties/launchSettings.json中

{
  // .. Ommitted
  "profiles": {
    "MyWorkerService": {
      "commandName": "Project",
      "environmentVariables": {
        "DOTNET_ENVIRONMENT": "Development"
      }
    }
  }
}


通常,新的项目模板会为您准备好这些,但在我的例子中,当将ASP.Net项目(不需要web服务器功能)转换为辅助服务时,launchSettings.json配置文件会将“ASPNETCORE_环境”设置为“开发”这在WorkerServices中实际上是无用的。

实现在webapi项目中工作的原因是,在webapi中,配置对象被DI到APIController类中,因此在您的代码中随处可见。这是通过IOptions及其同级实现的,因此您需要将配置称为IOptions

但在自托管环境(如worker service)中(由于缺少IOOptions,您需要显式绑定),您需要通过hostContext引用它或创建强类型配置对象的实例,并将其作为单例服务使用,然后通过构造函数DI在应用程序项目中的任何位置请求一个实例

仅伪代码

Program.cs

工薪阶层


实现在webapi项目中工作的原因是,在webapi中,配置对象被DI到APIController类中,因此在代码中的任何地方都可用。这是通过IOptions及其同级实现的,因此您需要将配置称为IOptions

但在自托管环境(如worker service)中(由于缺少IOOptions,您需要显式绑定),您需要通过hostContext引用它或创建强类型配置对象的实例,并将其作为单例服务使用,然后通过构造函数DI在应用程序项目中的任何位置请求一个实例

仅伪代码

Program.cs

工薪阶层


注意用户机密应该只在开发过程中使用()注意用户机密应该只在开发过程中使用()为什么
configuration[“PaymentServiceSecrets:FioApiKey”]将在asp.net核心web api项目中工作,而不在worker项目中工作?您的代码只需强键入
PaymentServiceSecrets
,否则它与为什么
配置[“PaymentServiceSecrets:FioApiKey]”相同将在asp.net核心web api项目中工作,而不在worker项目中工作?您的代码只需强键入
PaymentServiceSecrets
,否则将是相同的