ASP.NET Core 2.x OnConfiguring:如何从appsettings.json获取连接字符串?

4

刚开始接触ASP.NET Core,目前印象相当不错。在生成的代码中(见下文),我想将硬编码的连接字符串更改为从appsettings.json文件中获取。

这似乎是不可能的。我还没有找到一个可以工作(甚至能构建)的例子。

到底发生了什么事情?请帮忙。

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        if (!optionsBuilder.IsConfigured)
        {
#warning To protect potentially sensitive information in your connection string, you should move it out of source code. See http://go.microsoft.com/fwlink/?LinkId=723263 for guidance on storing connection strings.
            optionsBuilder.UseSqlServer("Server=xxxxxxx;Database=xxxxx;Trusted_Connection=True;");
        }
    }

提供的链接可以解决一个区域的问题,但在OnConfiguring这里不起作用。我做错了什么?
public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        services.Configure<CookiePolicyOptions>(options =>
        {
            // This lambda determines whether user consent for non-essential cookies is needed for a given request.
            options.CheckConsentNeeded = context => true;
            options.MinimumSameSitePolicy = SameSiteMode.None;
        });

        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

        var connection = Configuration.GetConnectionString("ConnectionName");
        services.AddDbContext<SurveyContext>(options => options.UseSqlServer(connection));
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/Home/Error");
            app.UseHsts();
        }

        app.UseHttpsRedirection();
        app.UseStaticFiles();
        app.UseCookiePolicy();

        app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "{controller=Home}/{action=Index}/{id?}");
        });
    }
}

这个函数是否在你的数据库上下文中?你确切生成了什么代码?你能提供一下你所采取的步骤吗? - Neville Nazerane
请查看以下链接:https://learn.microsoft.com/zh-cn/aspnet/core/fundamentals/configuration/?view=aspnetcore-2.1 - Neville Nazerane
不是我的代码,是由VS2017使用包管理器窗口中的“Scaffold-DbContext”命令生成的。 - djack109
当您使用 Scaffold-DbContext 选项时,应该在您的 DbContext 类顶部获得一个文档 URL。您有检查过吗? - Neville Nazerane
为了读者的清晰度,请更新您的问题,说明您使用了“Scaffold-DbContext”进行代码生成。 - Neville Nazerane
@NevilleNazerane 是的,我已经检查过了,没有帮助。我似乎找不到通过任何方法访问appsettings.json文件的方法。 - djack109
3个回答

2
在.NET Core项目的启动类中,通常会在ConfigureServices函数中进行注册。
public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<YourContext>(options => options.UseSqlServer(connection));
}

当你在.NET Core的启动类中时,从appsettings.json读取值是没有问题的。

你可以在微软官网上阅读更多相关信息,例如:https://learn.microsoft.com/en-us/ef/core/get-started/aspnetcore/existing-db


是的,确实这样做了,我在那一行上设置了断点,但程序甚至没有执行到那里。 - djack109
@djack109,您能展示一下启动类是什么样的并且启动类在哪里被调用吗?从那里开始,我相信我可以帮助您。 - Karl Fridlund
添加到我的原始帖子中。 - djack109
我查看了你的启动代码,没有立即发现任何问题。但是具体发生了什么,您进入了ConfigureServices或Configure函数吗?如果没有,我相信问题在Startup类之外。@djack109 - Karl Fridlund
已删除了 ConfigureServices,我认为这就是问题的原因。 - djack109
好的,希望你能够解决它! - Karl Fridlund

1

在您想要访问appsettings.json的位置,

JToken jAppSettings = JToken.Parse( 
      File.ReadAllText(Path.Combine(Environment.CurrentDirectory, 
      "appsettings.json")));

现在你已经拥有了这个对象,你可以访问它的内容。如果可行,请告诉我。

IConfiguration 是访问信息的最佳方式。它干净简单易用。但是您需要先了解依赖注入的工作原理。https://learn.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection?view=aspnetcore-2.1 - Neville Nazerane
这段代码是有效的:string conn = jAppSettings.SelectToken("ConnectionStrings").SelectToken("ConnectionName").Value<string>(); - djack109
1
使用 .NET Core 的棘手之处在于您需要了解一系列的概念才能熟练使用它。 - Neville Nazerane
@NevilleNazerane 我明白你的意思。但我不理解的是,如果在Asp.Net框架中一切都正常运作,为什么要让事情变得更加困难呢? - djack109
1
这个答案可能“可行”,但我认为它不是正确的解决方案。就像@NevilleNazerane所说,你需要使用IConfiguration。你必须确保它被正确生成并且使用正确的路径到你的连接字符串。 - Gerald Chifanzwa
显示剩余5条评论

1
当您使用Scaffold-DbContext时,默认情况下它会将您的字符串硬编码到DbContext类中(因此可以立即使用)。您需要在启动类中注册DbContext才能继续。要设置这个,您可以查看this answer中的说明。
请注意,Configuration属性直接连接到您的appsettings.json和其他几个位置。您可以在this documentation中了解更多信息。虽然您始终可以使用appsettings.json文件,但通常建议将安全密钥放在源代码之外的外部json文件中。在开发过程中实现这一点的最佳解决方案是使用secret manager。使用这个的最简单方法是在Visual Studio上右键单击您的项目,然后选择“管理用户机密”。这将打开一个已连接到您的Configuration对象的json文件。

一旦设置完成,您需要使用依赖注入来访问您的数据库上下文。

public class HomeController : Controller
{


     public HomeController(SurveyContext context)
     {
         // you can set the context you get here as a property or field
         // you can use visual studio's shortcut ctrl + . when the cursor is on "context"

         // you can then use the context variable inside your actions
     }
}

当您使用 "using" 时,它每次都会创建一个新连接。使用注入可确保每个请求只创建一个连接,无论使用次数多少。

是的,我也试过了,按照文档所说。StartUp.cs中的代码甚至都没有被触及。 - djack109
就像我多年来在EF中所做的那样,在using语句中使用using (var context = new SurveyContext()) - djack109
一旦您的启动设置完成,您需要使用依赖注入而不是不使用来调用您的Db Context。请再次查看该链接,我会更新我的答案以说明您如何使用您的db context。 - Neville Nazerane
我在你的回答中没有看到你在控制器中使用 DI 来获取数据,而不是使用 using 语句。 - djack109
public HomeController(SurveyContext context) 部分是 DI。如果它不可见,您可以刷新页面。 - Neville Nazerane
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接