【问题标题】:.Net Core Worker Service appsettings.json not being read.Net Core Worker Service appsettings.json 未被读取
【发布时间】:2022-01-10 23:56:18
【问题描述】:

我创建了一个 .net 核心工作服务,将 IConfiguration 注入其中,因此我可以从 appsettings.json 读取属性,但每次运行该文件时,该属性都会显示为空。但是,如果我强制 IConfiguration 通过 ConfigurationBuilder 添加一个 json 文件,它就可以工作。如何使用默认设置允许 .net core worker 服务从 appsettings 中读取?

public class ImageFileWatcher : IHostedService, IDisposable
{

    private readonly ILogger _logger;
    private readonly IConfiguration _configuration;
    FileSystemWatcher _watcher;

    public ImageFileWatcher(ILogger<ImageFileWatcher> logger, IConfiguration configuration)
    {
        _logger = logger;
        _configuration = configuration;
        // IConfigurationBuilder builder = new ConfigurationBuilder()
        // .AddJsonFile("appsettings.json")
        // .AddEnvironmentVariables();
        // this._configuration = builder.Build();
    }

    public Task StartAsync(CancellationToken cancellationToken)
    {

        var watcherConfig = _configuration["WatcherConfig:filePath"];//this is where it comes up as null.
        _logger.LogInformation($"Image File watcher started on path{watcherConfig}");
        _watcher = new FileSystemWatcher(watcherConfig);
        _watcher.Created += OnNewImage;
        _watcher.EnableRaisingEvents = true;
        return Task.CompletedTask;
    }

这里是 appsettings.json 文件

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "WatcherConfig":{

    "filePath":"/Users/###/Documents/Development/ImageDrop"
  }
  
}

这是 Program.cs 文件

public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureAppConfiguration((hostContext, configBuilder) =>
                {


                    configBuilder
                    .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
                    .AddJsonFile("appsettings.Production.json", optional: true, reloadOnChange: true)
                    .AddEnvironmentVariables(prefix: "ImageService_")
                    .Build();

                })
                .ConfigureServices((hostContext, services) =>
                {

                    services.AddHostedService<ImageFileWatcher>();

                });
    }

这是 Program 类的第二次尝试:

public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)

                .ConfigureServices((hostContext, services) =>
                {
                    IConfiguration builder = new ConfigurationBuilder()
                     .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
                    .AddJsonFile("appsettings.Production.json", optional: true, reloadOnChange: true)
                    .AddEnvironmentVariables(prefix: "ImageService_")
                    .Build();

                    hostContext.Configuration = builder;
                    services.AddHostedService<ImageFileWatcher>();

                });
    }

【问题讨论】:

    标签: c# .net-core appsettings worker-service


    【解决方案1】:

    鉴于您使用默认的appsettings.json 设置,使用CreateDefaultBuilder() 应该意味着您无需进行任何额外配置。

    有几点可能会有所帮助:

    • 删除任何不需要的自定义配置设置(因为CreateDefaultBuilder)

    • 确保将appsettings.json 文件复制到构建输出。如果没有,在 Visual Studio 中,您可以右键单击该文件并将“复制到输出目录”设置为“如果较新则复制”。

    或者,如果您想手动配置,请注意:

    • 在配置主机时,添加你的配置提供者,你不需要调用Build()方法。

    • 在Program 的第二个示例中,配置是在ConfigureServices 中设置的,而不是应该在的位置。我想这就是为什么必须使用不应该需要的hostContext.Configuration = builder 行的原因。

    【讨论】:

    • 通过删除所有额外的配置,我简单地使用了命令“dotnet clean”和“dotnet build”,现在它可以工作了。可悲的是,我现在无法重现该错误。
    • 好消息,它现在正在为您工作,虽然当这种情况发生时很烦人! :) 当您添加任何自定义提供程序时,确保它们在 ConfigureAppConfiguration() 方法中(并且没有调用 Build()),您应该会成功。
    【解决方案2】:

    在构建主机服务时,您必须阅读 Program.cs 中的应用设置。查看 Host.CreateDefaultBuilder 做了什么,如果您决定不使用默认构建器,您可能需要加载隐式设置。

    如果您还有其他问题,请附上 Program.cs 文件,因为 IConfiguration 取决于其初始化而不是服务中的使用。

    【讨论】:

    • 我已经编辑了帖子并添加了程序类,因此您可以看到两种方法仍然具有计数为 0 的配置数据字典。就好像它没有找到文件
    • 您在配置服务时创建您的配置,而受让人将配置构建到主机中。我相信这可能会在 DI 容器中注册 IConfiguration 后调用。这意味着您有两个不同的 IConfiguration 实例(一个分配给主机,另一个在 DI 中注册)。自定义配置的地方是 ConfigureAppConfiguration() 方法。
    • 是的,但是由于这个项目已经带来了 appsettings.json 和 Microsoft.Extensions.Hosting nuget,所以我不需要任何进一步的配置。奇怪的是,在执行“dotnet clean”和“dotnet build”命令后,项目现在似乎可以工作了。
    【解决方案3】:

    我也遇到过类似的问题。

    很高兴“dotnet clean”和“dotnet build”为您工作。

    下面,只是想贡献一个不同的解决方案。

    • appsettings.json 上的右键 > 属性 > 复制到输出目录 > 始终复制

    • 程序

    
         static class Program
            {
                public static IConfigurationRoot Configuration { get; private set; }
        
                static async Task Main(string[] args)
                {
                    using IHost host = CreateHostBuilder(args).Build();
        
                }
        
                static IHostBuilder CreateHostBuilder(string[] args) =>
                  Host.CreateDefaultBuilder(args)
                   .ConfigureAppConfiguration((hostingContext, configuration) =>
                    {
                        configuration.Sources.Clear();
        
                        configuration
                                .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);
        
                        IConfigurationRoot configurationRoot = configuration.Build();
        
                        Configuration = configurationRoot;
                    }).ConfigureServices((services) =>
                    {
                        services.RegisterServices();
                    });
            }
    
    
    • 创建了一个名为 AppSettings 的类和另一个名为 EndPoint 的类来与 appsettings.json 数据交互
    
        public class EndPoint
            {
                public string UrlWebApi { get; set; }
             }
        
            public class AppSettings
            {
                public EndPoint EndPoints { get; set; }
        
                public string Application { get; set; }
               
                public AppSettings()
                {
                    IConfigurationBuilder builder = new ConfigurationBuilder();
        
                    builder.AddJsonFile(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "appsettings.json"));
        
                    var root = builder.Build();
        
                    root.Bind(this);
                }
            }
    
    
    • 从 appsettings.json 获取 URL 的 Appsettings 类的使用示例
    
        public class MyAppService : IMyAppService
            {
                private readonly AppSettings _appSettings;
                private readonly ILogger<MyAppService> _logger;
        
                public MyAppService(AppSettings appSettings, ILogger<MyAppService> logger)
                {
                    _appSettings = appSettings;
                    _logger = logger;
                }
        
                public async Task<string> ShowAppSettingsUse()
                {
                        _logger.LogInformation("Getting endpoint URL from AppSettings...");
        
                        var urlFromAppSettings = _appSettings.EndPoints.UrlWebApi;
        
                        return urlFromAppSettings;
                }
            }
        }
    

    【讨论】:

    • 感谢您的贡献,我忘了提到我正在使用 Mac 上的 VsCode,因此复制到输出目录的步骤有点不同。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-15
    • 1970-01-01
    • 1970-01-01
    • 2018-05-05
    • 1970-01-01
    • 2020-10-09
    相关资源
    最近更新 更多