Search code examples
c#asp.net-coreconfigurationasp.net-core-webapiasp.net-core-mvc-2.0

asp.net Core 2 Web API appsetting.json values aren't being read when deployed as windows service


I am running an asp.net core 2 web api as a windows service. When I debug through IIS I am able to read my configuration values no problem.

However, once I run it as a service I am not getting any values back.

appsettings.json

{
  "Database": {
    "DatabaseName": "testdb",
    "DatabaseServer": "localhost",
    "DatabaseUserName": "admin",
    "DatabasePassword": "admin"
  }
}

 public string GetConnectionString()
    {
        var databaseName = Configuration["Database:DatabaseName"];
        var databaseServer = Configuration["Database:DatabaseServer"];
        var username = Configuration["Database:DatabaseUserName"];
        var password = Configuration["Database:DatabasePassword"];


        return $"Data Source={databaseServer};Initial Catalog={databaseName};Persist Security Info=True;User ID={username};Password={password};MultipleActiveResultSets=True";
    }

Not sure why I can't read those values once I publish the application. In the published appsettings.json file the values are there.

Here is my startup.cs. I was under the impression that I didn't have to reference teh appSettings.json file in the new asp.net core 2. Thanks for the help.

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc();
        AutoMapper.Mapper.Initialize(cfg =>
        {
            cfg.CreateMap<InventoryTransaction, Models.InventoryTransactionModel>();
            cfg.CreateMap<ReasonCode, Models.ReasonCodeModel>();
            cfg.CreateMap<InventoryTransaction, Models.InventoryTransactionForCreationModel>();
            cfg.CreateMap<InventoryTransactionForCreationModel, InventoryTransaction>();
        });
        services.AddScoped<IInventoryTransactionRepository, InventoryTransactionRepository>();
        services.AddSingleton<IConfiguration>(Configuration);
        services.AddDbContext<VPSInventoryContext>(options => options.UseSqlServer(GetConnectionString()));

    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
        loggerFactory.AddConsole();
        loggerFactory.AddDebug();
        loggerFactory.AddNLog();

        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        app.UseMvc();

    }

    public string GetConnectionString()
    {
        var databaseName = Configuration["Database:DatabaseName"];
        var databaseServer = Configuration["Database:DatabaseServer"];
        var username = Configuration["Database:DatabaseUserName"];
        var password = Configuration["Database:DatabasePassword"];


        return $"Data Source={databaseServer};Initial Catalog={databaseName};Persist Security Info=True;User ID={username};Password={password};MultipleActiveResultSets=True";
    }
}

Here is my Program.cs where I run it as a windows service.

public class Program
{
    public static void Main(string[] args)
    {
        if (Debugger.IsAttached || args.Contains("--debug"))
        {
            BuildWebHost(args).Run();
        }
        else
        {
            BuildWebHost(args).RunAsService();
        }
    }

    public static IWebHost BuildWebHost(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .UseStartup<Startup>()
            .Build();
}

Solution

  • When you launch your application as a service, the working directory is set to a system directory, like C:\Windows\System32\. Configuration file is looked in the same directory. As far as it's missing there, you get empty configuration loaded.

    To fix it, just set working directory to the one where your application is located:

    public static void Main(string[] args)
    {
        if (Debugger.IsAttached || args.Contains("--debug"))
        {
            BuildWebHost(args).Run();
        }
        else
        {
            var path = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
            Directory.SetCurrentDirectory(path);
            BuildWebHost(args).RunAsService();
        }
    }