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"
}
}
}
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.