IOptions在作为docker容器部署时不返回appsettings的设置



我们有一个。net 7应用程序,它使用autofac IOC,需要从appsetting文件中提取RegionInfo,这个类库是我们解决方案的一部分。当在Visual Studio本地运行时,或者通过使用Bridge to Kubernetes,类库中的IOptions被填充,功能按预期工作。当作为docker容器部署到我们的集群时,虽然这些选项不会返回到类,但会导致api失败。

我花了几个小时在这个问题上尝试了各种各样的建议,但没有解决方案,我希望有人能给我指出正确的方向来解决这个问题。下面是代码…

StartUp.cs

services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "IntegrationService", Version = "v1" });
});
services.Configure<RegionInformation>(Configuration.GetSection("RegionInfo"));
services.AddOptions();
var container = new ContainerBuilder();

GlobalDateManager.cs

private readonly ILogger<GlobalDateManager> _logger;
private readonly RegionInformation _regionInformation;

public GlobalDateManager(IOptions<RegionInformation> regionInformation, ILogger<GlobalDateManager> logging)
{
_regionInformation = regionInformation.Value;
_logger = logging;

}

我使用你的部分代码创建了一个简单的webapi。它像你的代码一样使用IOptions模式,并输出配置。

通过简单的命令dotnet new webapi -o abcde

创建这里是我修改或创建的整个文件:

Program.cs(改变)

using Microsoft.OpenApi.Models;
using Autofac;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
var services = builder.Services;
services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
services.AddEndpointsApiExplorer();
// start of your snippet code
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "IntegrationService", Version = "v1" });
});
services.Configure<RegionInformation>(builder.Configuration.GetSection("RegionInfo"));
services.AddOptions();
var container = new  ContainerBuilder(); // added this line of your code: anyway i did not used it in the app
// end of your snippet code
var app = builder.Build();
// Configure the HTTP request pipeline.
app.UseSwagger();
app.UseSwaggerUI();

app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();

RegionInformation.cs(创建)

public class RegionInformation{
public const string RegionInfo = "RegionInfo";
public string Name {get;set;} = string.Empty;
}

控制器/GetConfigAndOptionsController.cs(创建)

using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
namespace abcde.Controllers;
[ApiController]
[Route("[controller]")]
public class GetConfigAndOptionsController : ControllerBase
{   
private readonly ILogger<GetConfigAndOptionsController> _logger;
private readonly IConfiguration _configuration;
private readonly  IOptions<RegionInformation> _regionInformation;
public GetConfigAndOptionsController(ILogger<GetConfigAndOptionsController> logger, IConfiguration configuration, IOptions<RegionInformation> regionInformation )
{
_logger = logger;
_configuration = configuration;
_regionInformation = regionInformation;
}
[HttpGet(Name = "GetGetConfigAndOptions")]
public string Get()
{
var sb = new System.IO.StringWriter();
sb.WriteLine("Listing all providers (appsettings.json should be present in the list))n");

// listing all providers
foreach (var provider in ((IConfigurationRoot)_configuration).Providers.ToList())
{
sb.WriteLine(provider.ToString());
}    
// getting the Name using the configuration object
sb.WriteLine($"nFrom config: {_configuration["RegionInfo:Name"]}");
// or getting the value using IOption like your code does
sb.WriteLine($"nFrom IOptions: {_regionInformation.Value.Name}");
return sb.ToString();
}
}

appsettings。json(改变)

{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*",

"RegionInfo":{
"Name":"kiggyttass"
}
}
最后我创建了一个简单的Dockerfile
FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build-env
WORKDIR /App
# Copy everything
COPY . ./
# Restore as distinct layers
RUN dotnet restore
# Build and publish a release
RUN dotnet publish -c Release -o out
# Build runtime image
FROM mcr.microsoft.com/dotnet/aspnet:7.0
WORKDIR /App
COPY --from=build-env /App/out .
ENTRYPOINT ["dotnet", "abcde.dll"]

,

# build your docker image
docker build -t abcde .  
# run it
docker run --name=abcde --rm  -p 9234:80  abcde

在Swagger UI中调用相应的GET方法,或者cUrl到http://localhost:9234/GetConfigAndOptions

,你应该得到这样的东西:

Listing all providers (appsettings.json should be present in the list))
MemoryConfigurationProvider
EnvironmentVariablesConfigurationProvider Prefix: 'ASPNETCORE_'
MemoryConfigurationProvider
EnvironmentVariablesConfigurationProvider Prefix: 'DOTNET_'
JsonConfigurationProvider for 'appsettings.json' (Optional)
JsonConfigurationProvider for 'appsettings.Production.json' (Optional)
EnvironmentVariablesConfigurationProvider Prefix: ''
Microsoft.Extensions.Configuration.ChainedConfigurationProvider
From config: kiggyttass
From IOptions: kiggyttass

尝试创建这个dockerized应用程序,并检查是否得到类似的输出。您应该使用IConfiguration或IOptions获取您的值。

希望有帮助。

最新更新