由于 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>();
});
}
工具: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>();
});
}