将我的设置注入控制器中可在调试中使用,但不能在发行版中使用

时间:2019-02-20 16:18:52

标签: c# asp.net-core

我对Asp.Net Core还是很陌生,所以我很确定自己做的事很愚蠢,但我不知道这是问题所在。所以我在appsetting.json中写了一些我需要在运行时检索的变量。在documentation之后,我在ConfigureService

中写了我的启动文章
services.AddOptions();
services.Configure<AppConfig>(Configuration.GetSection("AppConfig"));

其中AppConfig

是以下课程

public class AppConfig
{
    public bool NeedToCheckSession { get; set; }
    public string ConnectionString { get; set; }
}

我的控制器的构造函数如下:

public MyController(IOptions<AppConfig> config)
{
    this.config = config;
}

现在,当我在Visual Studio中通过IIS Express在调试中运行我的api时,当我向控制器发送请求时,我可以在构造函数内部命中断点,并且配置正确设置。如果然后我在“发布项目”中构建,执行webapi.exe并使用Visual Studio附加到该进程,则会看到当我发送相同的请求时,我直接命中了方法内部的断点,并跳过了构造函数中的断点,结果是未设置config变量。怎么了?

我添加了我正在使用的呼叫,以检查config变量是否正确设置

        [Route("start")]
        [HttpPost]
        public HttpResponseMessage MyMethod([FromBody]UserSessionModel userSession)
        {
            HttpResponseMessage resp;


            MyWorker newSession = new MyWorker (config.Value.ConnectionString)
            {
                SessionFolder = sessionFolder
            };


            if (config.Value.NeedToCheckSession == true)
            {
               // i can't enter inside this if, cause even if in the appsetting.json the value is set to true, config is not passed to the controller
            }

还添加了json文件

{
  "AppConfig": {
    "NeedToCheckSession": "true",
    "ConnectionString": "myconnstring;"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Warning"
    }
  },
  "AllowedHosts": "*"
}

编辑

要回答一些问题:

  • 不,我不使用无参数构造函数,我只有上面发布的那个

  • 我试图直接在IIS 2017托管的VS 2017中以发布模式运行api,但仍然,当我发送发布请求时,构造函数和config内没有断点变量未设置。如果我在调试中运行api,那么它将正常工作

  • 要创建exe,我只需在发布模式下构建api,然后尝试从项目内的Release文件夹中运行它。我也尝试发布api,但问题仍然存在

EDIT2

进一步的调查显示,出于某种原因,以下ConfigureService

   // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
        services.AddOptions();
        services.Configure<AppConfig>(Configuration.GetSection("AppConfig"));
        services.AddHostedService<QueuedHostedService>();
        services.AddSingleton<IBackgroundTaskQueue, BackgroundTaskQueue>();
        // Register the Swagger generator, defining 1 or more Swagger documents
        services.AddSwaggerGen(c =>
        {
            c.SwaggerDoc("v1", new Microsoft.OpenApi.Models.OpenApiInfo { Title = "My Web Api", Version = "v1" });
            // Set the comments path for the Swagger JSON and UI.
            var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
            var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
            c.IncludeXmlComments(xmlPath);
        });
    }

在发行版中运行api时,以下说明将被完全忽略(即跳过)。

        services.Configure<AppConfig>(Configuration.GetSection("AppConfig"));
        services.AddHostedService<QueuedHostedService>();
        services.AddSingleton<IBackgroundTaskQueue, BackgroundTaskQueue>();

这在调试中不会发生

2 个答案:

答案 0 :(得分:1)

使用ConfigurationBuilder:

 private static IConfigurationRoot Get(string path, string[] args = null, string environmentName = null)
        {
            var builder = new ConfigurationBuilder()
                .SetBasePath(path)
                .AddJsonFile("appsettings.json", true, true)
                .AddCommandLine(args ?? new string[0]);

            if (!environmentName.IsNullOrWhiteSpace()) builder = builder.AddJsonFile($"appsettings.{environmentName}.json", true, true);

            builder = builder.AddEnvironmentVariables();

            return builder.Build();
        }

和:

   var host = new WebHostBuilder()
                    ...

                    .UseConfiguration(AppConfigurations.Get(root, args, Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")))
                    .UseEnvironment(Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT"))
                    .Build();

答案 1 :(得分:0)

因此,事实证明这并不是与代码严格相关的问题,但是我发现我必须在项目属性的“构建”选项卡中禁用“优化代码”选项,因为这使调试器搞砸了