【问题标题】:add-migration can not read the connection string from the file appsettings.json because of the path to appsettings.json由于 appsettings.json 的路径,add-migration 无法从文件 appsettings.json 中读取连接字符串
【发布时间】:2018-09-03 17:08:47
【问题描述】:

工具:VS2017、ASP.NET Core 2、Entity Framework Core 2、ASP.NET Core JavaScript 服务

我正在使用以下 BuildWebHost 方法:

public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
    .UseContentRoot(Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName))
    .UseStartup<Startup>()
    .UseNLog()
    .Build();

为了加载连接字符串,我在 ConfigureServices (startup.cs) 中有以下代码:

Action<DbContextOptionsBuilder> optionsAction = options =>
    options.UseSqlServer(Configuration.GetConnectionString("RecipeDatabase")); 
services.AddDbContext<RecipeContext>(optionsAction);

通过上述配置,应用程序在调试模式和 Windows 服务(发布后)下运行没​​有问题。

但如果我运行 add-migration,该工具将无法从 appsettings.json 加载连接字符串:

如果我这样评论以下行

//.UseContentRoot(Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName))

add-migration 运行没有问题,但应用程序作为“Windows 服务”运行不是因为它找不到 appsettings.json 文件。

我怎样才能修改配置,这样就不需要再注释上面的行了?

谢谢。

迈克尔

【问题讨论】:

    标签: c# asp.net-core entity-framework-core asp.net-core-2.0 asp-net-core-spa-services


    【解决方案1】:

    您可能想要覆盖 DbContext 中的 OnConfiguring 方法。这是我正在使用的示例。只要您使用命令行或 Windows 服务,它就可以工作:

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        if (optionsBuilder.IsConfigured)
        {
            base.OnConfiguring(optionsBuilder);
            return;
        }
    
        string pathToContentRoot = Directory.GetCurrentDirectory();
        string json = Path.Combine(pathToContentRoot, "appsettings.json");
    
        if (!File.Exists(json))
        {
            string pathToExe = Process.GetCurrentProcess().MainModule.FileName;
            pathToContentRoot = Path.GetDirectoryName(pathToExe);
        }
    
        IConfigurationBuilder configurationBuilder = new ConfigurationBuilder()
            .SetBasePath(pathToContentRoot)
            .AddJsonFile("appsettings.json");
    
        IConfiguration configuration = configurationBuilder.Build();
    
        optionsBuilder.UseSqlServer(configuration.GetConnectionString("RecipeDatabase"));
    
        base.OnConfiguring(optionsBuilder);
    }
    

    【讨论】:

    • 这似乎很有希望!我会尽快检查的。谢谢。
    • 好的,你指出了我正确的方向,所以你的回答帮助我解决了问题。最后我实现了接口“IDesignTimeDbContextFactory”并将“BuildWebHost”重命名为“BuildHost”,因为以下博客文章:wildermuth.com/2018/01/10/…。如果实现,添加迁移将使用“IDesignTimeDbContextFactory”。但是按照惯例,它会首先检查“BuildWebHost”,如果找到它就永远不会执行“IDesignTimeDbContextFactory”。这将通过重命名“BuildWebHost”来解决。
    • 我用过,效果很好!谢谢 ! if (optionsBuilder.IsConfigured) { base.OnConfiguring(optionsBuilder);返回; }
    【解决方案2】:

    在开发环境中,最好使用“User Secrets”来存储配置,而不是 appsettings.json。您可以在解决方案资源管理器 > 项目的上下文菜单 > 管理用户密码中获得用户密码。

    User Secrets 将配置存储在当前用户的 romaing 配置文件目录中,例如:C:\users\john\AppData\Roaming\Microsoft\UserSecrets\ProjectName012822aasd\secrets.json

    虽然 User Secrets 选项仅适用于开发环境,但对于生产环境,您需要依赖其他配置管理,例如:Azure App Service 的 App Config。

    这是 Microsoft 在 User Secrets 上的文档

    【讨论】:

      【解决方案3】:

      我在 Program.cs 中包含了 secrets.json。该文件存储在存储库之外,并作为链接添加到项目中。之后,它的内容就可以访问了,例如Configuration["SectionName:SectionLine"]。 SetBasePath 代码行修复了在创建迁移等时访问此文件时出现的错误。

        public class Program
          {
      
              public static void Main(string[] args)
              {
                  CreateHostBuilder(args).Build().Run();
              }
      
              public static IHostBuilder CreateHostBuilder(string[] args) =>
                  Host.CreateDefaultBuilder(args)
                      .ConfigureAppConfiguration((hostingContext, config) =>
                      {
                          var basePath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
                          Console.WriteLine($"Launched program with base at {basePath}");
                          config.SetBasePath(basePath);
                          config.AddJsonFile("secrets.json", optional: false, reloadOnChange: true);
                          config.AddJsonFile($"secrets.{hostingContext.HostingEnvironment.EnvironmentName}.json", optional: true, reloadOnChange: true);
      #if DEV_DB
                          config.AddJsonFile($"secrets.LocalDb.json", optional: true);
      #endif
                      })
                      .ConfigureWebHostDefaults(webBuilder =>
                      {
                          webBuilder.UseStartup<Startup>();
                      });
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-01-22
        • 1970-01-01
        • 1970-01-01
        • 2019-08-05
        • 1970-01-01
        • 2020-04-17
        • 2021-06-20
        • 1970-01-01
        相关资源
        最近更新 更多