由于 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核心2,Entity Framework核心2,ASP.NET核心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 运行s 没有问题但是应用程序 运行ning 作为 "Windows Service" 不是因为它找不到 appsettings.json 文件。

如何修改配置,以便不再需要注释以上行?

谢谢。

迈克尔

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

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

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

这是 Microsoft 关于 User Secrets

的文档

您可能想要覆盖 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);
}

我将 secrets.json 包括在 Program.cs 中。此文件存储在存储库外部,并作为 link 添加到项目中。之后它的内容可以访问,例如 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>();
                });
    }