繁体   English   中英

由于 appsettings.json 的路径,add-migration 无法从文件 appsettings.json 读取连接字符串

[英]add-migration can not read the connection string from the file appsettings.json because of the path to appsettings.json

工具: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 文件。

如何修改配置以便不再需要评论以上行?

谢谢你。

迈克尔

您可能想在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);
}

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

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

尽管“用户机密”选项仅适用于开发环境,但对于生产而言,您需要依赖于其他配置管理,例如:Azure App Service的App Config。

这是Microsoft关于用户机密的文档

我在 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>();
                });
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM