【问题标题】:.net core Worker Service (BackgroundService) cannot load user secrets.net core Worker Service (BackgroundService) 无法加载用户机密
【发布时间】:2021-01-22 22:30:47
【问题描述】:

拥有.net core 3.1.8 版和asp.net core 3.1.8 版的.net core worker 服务我在从worker 服务加载用户密码时遇到问题,但是在asp.net core 项目中同样有效。

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

public static string GetFioApiKey(this IConfiguration configuration)
            => configuration["PaymentServiceSecrets:FioApiKey"];

worker服务的csproj

<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>

worker服务的startup.cs

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>();
                });
    }

发现这个link 到 github 问题,尝试应用解决方法但仍然不起作用

【问题讨论】:

标签: c# asp.net-core .net-core


【解决方案1】:

这里没有提到的一个“陷阱”是要求,在 WorkerServices 中,环境变量“DOTNET_ENVIRONMENT”必须设置为“开发”,否则用户机密甚至不会尝试加载。这与 ASP.Net 项目中使用的“ASPNETCORE_ENVIRONMENT”环境变量形成对比。

即在Properties/launchSettings.json中

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

通常,新的项目模板会为您准备好这个,但在我的情况下,当将 ASP.Net 项目(不需要 Web 服务器功能)转换为 Worker Services 时,launchSettings.json 配置文件会设置“ASPNETCORE_ENVIRONMENT ” 到“开发”,这在 WorkerServices 中实际上是无用的。

【讨论】:

    【解决方案2】:

    对于 .net core 3.1 及更高版本,您需要手动添加对 nuget 包的引用

    Microsoft.Extensions.Configuration.UserSecrets

    然后用户机密将自动加载到您可以通过依赖注入获得的 IConfiguration 实例中。

    这可以直接从新项目模板中使用,不需要任何其他代码来配置它。

    更多细节可以在这个 github 问题上找到:https://github.com/dotnet/extensions/issues/2743

    【讨论】:

      【解决方案3】:

      你应该试试这个

      public static YourConfigObject GetFioApiKey(this IConfiguration configuration)
                  => configuration.GetSection("PaymentServiceSecrets").Get<YourConfigObject>();
      

      【讨论】:

      • 为什么configuration["PaymentServiceSecrets:FioApiKey"]; 可以在asp.net core web api 项目中工作而不是在worker 项目中?您的代码只会强输入PaymentServiceSecrets,否则相同
      【解决方案4】:

      通过在Program.cs 中添加以下行,我能够从用户密码中获取值

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

      【讨论】:

        【解决方案5】:

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

        但是在像工作服务这样的自托管环境中,(由于没有 IOptions,您需要显式绑定)您需要通过 hostContext 引用它或创建强类型配置对象的实例,然后使用它作为 Singleton 服务,然后通过构造函数 DI 在应用项目中的任何位置请求实例。

        仅限伪代码

        Program.cs

        MyConfig config = new MyConfig()
        hostContext.Configuration.Bind(configParams)
        services.AddSingleton(config)
        

        Worker.cs

        myworker(MyConfig config) {
             connStr = config.Connection
             ... 
        }
        

        【讨论】:

          【解决方案6】:

          这个issue好像是fixed in .NET 6,所以不用再直接引用Microsoft.Extensions.Configuration.UserSecrets了。

          但是,如果您出于某种原因在.csproj 文件中设置了&lt;GenerateAssemblyInfo&gt;false&lt;/GenerateAssemblyInfo&gt;,则不会使用&lt;UserSecretsId&gt; 值。即,由于项目遗留的原因,我不得不这样做。

          要让您的辅助服务项目识别secrets.json 文件,您应该将全局属性[assembly: UserSecretsId] 添加到您的自定义AssemblyInfo.cs 文件或项目中的任何其他.cs 文件中。即:

          [assembly: UserSecretsId("dotnet-Worker-12345678-1234-ABCD-5678-1234567890ABCDEF")]
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多