从 ASP.net Core 2 MVC 应用程序中的 appSettings.json 存储/检索 ConnectionString

Posted

技术标签:

【中文标题】从 ASP.net Core 2 MVC 应用程序中的 appSettings.json 存储/检索 ConnectionString【英文标题】:Store / Retrieve ConnectionString from appSettings.json in ASP.net Core 2 MVC app 【发布时间】:2018-05-24 10:47:06 【问题描述】:

我正在寻找将连接字符串存储在 .net Core 2 MVC 应用程序的 appsettings.json 中的最佳实践方法(就像您在 MVC 5 中的 web.config 中所做的那样)。

我想使用 Dapper 而不是 EF(我找到了很多 EF 示例)。

类似这样的:


  "ConnectionStrings": 
    "myDatabase": "Server=.;Database=myDatabase;Trusted_Connection=true;"
  ,

  "Logging": 
    "IncludeScopes": false,
    "LogLevel": 
      "Default": "Warning"
    
  

网上肯定有很多例子吗?我找不到任何适用于 .net core 2.0 的内容。

在 1 和 2 之间发生了一些变化,我想确保我使用的是版本 2 的最佳做法。

我找到了这个 - 但它似乎是 .net core 1: Visual Studio 2017 - MVC Core - Part 05 - Connection String from appsettings.json

这使用键值对 appsettings - 而不是连接字符串: Read AppSettings in ASP.NET Core 2.0

同样不清楚这是 .net Core 1 还是 2:Net Core Connection String Dapper visual studio 2017

【问题讨论】:

只使用"ConnectionStrings": ...ConfigurationExtensions.GetConnectionString - 这并没有改变并且遵循一个明显的约定(当然是基于意见的)。 谢谢 - 我没有真正关注,有没有机会把这个变成更详细的答案? 自从 Core 首次引入以来,这方面没有任何改变。但是,在实际实践中,您很可能会使用环境变量或 Azure Key Vault 之类的东西,而不是 appsettings.json,因此您不会将实际凭据提交给您的源代码。不过,这对于本地开发连接字符串很好。 有趣 - 即使连接字符串不包含登录凭据(在我的情况下它不包含) - 只是数据库名称? 我发现这更直接-***.com/a/51780754/1042288 【参考方案1】:

appsettings.json 中定义您的连接字符串


    "connectionStrings": 
        "appDbConnection": "..."
    

在启动时读取其值

如果您遵循约定并在connectionStrings 下定义连接字符串,则可以使用扩展方法GetConnectionString() 来读取其值。

public class Startup

    public IConfiguration Configuration  get; private set; 

    public Startup(IConfiguration configuration)
    
        Configuration = configuration;
    

    public void ConfigureServices(IServiceCollection services)
    
        // Since you said you're using Dapper, I guess you might want to
        // inject IDbConnection?
        services.AddTransient<IDbConnection>((sp) => 
            new SqlConnection(this.Configuration.GetConnectionString("appDbConnection"))
        );

        // ...
    

在存储库中使用 IDbConnection?

public interface ISpecificationRepository

    Specification GetById(int specificationId);


public SpecificationRepository : ISpecificationRepository

    private readonly IDbConnection _dbConnection;

    public SpecificationRepository(IDbConnection dbConnection)
    
        _dbConnection = dbConnection;
    

    public Specification GetById(int specificationId)
    
        const string sql = @"SELECT * FROM [YOUR_TABLE]
                             WHERE Id = @specId;";

        return _dbConnection
            .QuerySingleOrDefault<Specification>(sql,
                new  specId = specificationId );
    

只需要 POCO 中的连接字符串?

您可以使用Options Pattern。

    在 appsettings.json 中定义一个与JSON 对象结构完全匹配的类

    public class ConnectionStringConfig
    
        public string AppDbConnection  get; set; 
    
    

    在启动时注册该配置

    public void ConfigureServices(IServiceCollection services)
    
       // ...
    
       services.Configure<ConnectionStringConfig>(
           this.Configuration.GetSection("connectionStrings")
       );
    
       // ...
    
    

    在您的 POCO 中接收访问器

    public class YourPoco
    
        private readonly ConnectionStringConfig _connectionStringConfig;
    
        public YourPoco(IOptions<ConnectionStringConfig> configAccessor)
        
            _connectionStringConfig = configAccessor.Value;
    
            // Your connection string value is here:
            // _connectionStringConfig.AppDbConnection;
        
    
    

注意事项:

    请参阅my sample codes,了解如何在 Core 1.x 和 2.0 上从 appsettings.json 读取值。 如果您有超过 1 个连接字符串,请参阅 how I setup。

【讨论】:

谢谢。是否有机会在此处粘贴相关位以确保完整性? 我需要在数据访问类中读取这个值——目前是一个 POCO。所有这些 DI 东西都很棒,但现在我只需要像以前一样访问 POCO 中的连接字符串。我该怎么做? 我猜把 3 扔进一个基类? 在 1 中“完全匹配连接字符串结构”是什么意思? 评论区这里没法做详细的解释。你需要阅读docs.microsoft.com/en-us/aspnet/core/fundamentals/…。【参考方案2】:

只需将如下所示的内容放在 appsettings.json 中即可。

"ConnectionStrings": 
    "DefaultConnection": "Data Source=;Initial Catalog=;Persist Security Info=True;User ID=; Password=;"

在 Startup.cs 中如下所述获取它:

public class Startup

    public Startup(IHostingEnvironment env)
    
        var builder = new ConfigurationBuilder()
            .SetBasePath(env.ContentRootPath)
            .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
            .AddJsonFile($"appsettings.env.EnvironmentName.json", optional: true);

        builder.AddEnvironmentVariables();
        Configuration = builder.Build();
    

    public IConfigurationRoot Configuration  get; 

使用依赖注入在控制器中注入配置,如下所述:

public class MyController : Controller

    private readonly IConfiguration _configuration;
    private string connectionString;

    public MyController(IConfiguration configuration) 
    
        _configuration = configuration;

        connectionString = _configuration.GetConnectionString("DefaultConnection");
    

【讨论】:

我的 Startup 构造函数中已经有(IConfiguration 配置)。将其更改为 (IHostingEnvironment env) 会有什么影响?有什么缺点吗? 或者我也应该保留另一个构造函数? 您是否真的需要使用 IConfigurationRoot - 而不仅仅是 IConfiguration?如果是,为什么? 我还需要从数据类访问连接字符串,而不是从控制器。我已经尝试使用与 MyController 相同的构造函数为此创建一个 POCO 类,但它不起作用(connectionString 为空) - 我错过了什么?控制器如何将配置传递给它的构造函数? Controller 正在使用依赖注入获取它,如果您使用 IConfiguration 并在构造函数中对其进行初始化,如上面代码所示,您将不会收到该错误。

以上是关于从 ASP.net Core 2 MVC 应用程序中的 appSettings.json 存储/检索 ConnectionString的主要内容,如果未能解决你的问题,请参考以下文章

从 ASP.net Core 2 MVC 应用程序中的 appSettings.json 存储/检索 ConnectionString

从 ASP.NET Core 1.1 MVC 迁移到 2.0 后,自定义 cookie 身份验证不起作用

从 ASP.NET MVC 迁移到 ASP.NET Core MVC

从 ASP.NET Core MVC 项目提供 Angular SPA 时,我可以使用 OIDC 混合流吗?

ASP.NET Core 2.2 MVC MapRoute 项目到 ASP.NET 3.0 端点 MapAreaControllerRoute “找不到此本地主机页面”

单独程序集中的 ASP.NET Core MVC 控制器