Home > database >  Read appsettings.{env}.json objects in .NET 6 API - Values coming as NULL
Read appsettings.{env}.json objects in .NET 6 API - Values coming as NULL

Time:04-27

I am using .NET 6 to create APIs. I have environment-based appsettings.json files.

I have created apt profiles in launchSettings.json as well.

I am trying to use Options pattern to read the key/values inside one of the controllers.

I get the values as NULL every single time.

When I debug the Program.cs file, I am able to see the proper values via the below line of code.

builder.Configuration.GetSection(key: "Config").Get<Config>();

Please help. Code used is as below:

Program.cs:

var builder = WebApplication.CreateBuilder(args);
var configuration = builder.Configuration;

var env = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");

configuration
    .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
    .AddJsonFile($"appsettings.{env}.json", true, true);

builder.Configuration.GetSection(key: "Config").Get<Config>();

builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddScoped<IProductRepository, ProductRepository>();
builder.Services.AddSingleton<Config>();

Config.cs:

public class Config
    {
        public string Environment { get; set; }
        public string Type { get; set; }
    }

ProductsController.cs

    [Route("api/[controller]")]
    [ApiController]
    public class ProductsController : ControllerBase
    {
        private readonly IProductRepository _repository;
        private readonly Config _config;

        public ProductsController(IProductRepository repository,
            IOptions<Config> config)
        {
            _repository = repository;
            _config = config.Value;
        }

        [HttpGet]
        [Route("/configs")]
        public IActionResult GetConfigs()
        {
            var model = new { type = _config.Type, env = _config.Environment };
            return Ok(model);
        }

appsettings.json:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "Config": {
    "Environment": "local",
    "Type": "local Server"
  }
}

appsettings.Development.json:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "Config": {
    "Environment": "Development",
    "Type": "Development Server"
  }
}

appsettings.Staging.json:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "Config": {
    "Environment": "Staging",
    "Type": "Staging Server"
  }
}

launchSettings.json:

 "profiles": {
    "API - Development": {
      "commandName": "Project",
      "dotnetRunMessages": true,
      "launchBrowser": true,
      "launchUrl": "swagger",
      "applicationUrl": "https://localhost:7082;http://localhost:5082",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    },
    "API - Staging": {
      "commandName": "Project",
      "dotnetRunMessages": true,
      "launchBrowser": true,
      "applicationUrl": "https://localhost:5001;http://localhost:5000",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Staging"
      }
    }
}

Output: enter image description here

CodePudding user response:

I think you might need to use configuration.GetSection in Services.Configure which means registering Config object from Config section of appsettings.json.

builder.Services.Configure<Config>(configuration.GetSection("Config"));

CodePudding user response:

I think your issue is within:

configuration
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{env}.json", true, true);

builder.Configuration.GetSection(key: "Config").Get<Config>();

builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddScoped<IProductRepository, ProductRepository>();
builder.Services.AddSingleton<Config>();

You're currently getting a section Config and then calling Get<> on it but never applying that to anything (injecting). It would seem like the final line would do that, but there is no parameter to this function to provide something to inject.

You could:

builder.Services.Configure<Config>(builder.Configuration.GetSection("Config"));

CodePudding user response:

services.AddOptions<Config>()
    .Bind(configuration.GetSection("Config"))
    .ValidateDataAnnotations(); // optionally validate annotations

Try using AddOptions, this should then bind.

  • Related