【问题标题】:How to read connection string in .NET Core?如何在 .NET Core 中读取连接字符串?
【发布时间】:2019-04-21 15:43:29
【问题描述】:

我只想从配置文件中读取一个连接字符串,为此向我的项目中添加一个名为“appsettings.json”的文件并在其上添加以下内容:

{
"ConnectionStrings": {
  "DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=aspnet-

 WebApplica71d622;Trusted_Connection=True;MultipleActiveResultSets=true"
  },
    "Logging": {
    "IncludeScopes": false,
    "LogLevel": {
    "Default": "Debug",
    "System": "Information",
    "Microsoft": "Information"
   }
 }
}

在 ASP.NET 上我使用了这个:

 var temp=ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString;

现在如何在 C# 中读取“DefaultConnection”并将其存储在 .NET Core 中的字符串变量中?

【问题讨论】:

标签: c# connection-string asp.net-core-1.0


【解决方案1】:

发布的答案很好,但没有直接回答我在连接字符串中阅读的相同问题。经过大量搜索,我发现了一种稍微简单的方法。

在 Startup.cs 中

public void ConfigureServices(IServiceCollection services)
{
    ...
    // Add the whole configuration object here.
    services.AddSingleton<IConfiguration>(Configuration);
}

在你的控制器中为配置添加一个字段,并在构造函数中为其添加一个参数

private readonly IConfiguration configuration;

public HomeController(IConfiguration config) 
{
    configuration = config;
}

现在稍后在您的视图代码中,您可以像这样访问它:

connectionString = configuration.GetConnectionString("DefaultConnection");

【讨论】:

  • 不会那样做。如果您在没有实体框架的情况下工作,则最好将连接工厂注册为单例,例如与 dapper 一起使用。如果需要,您仍然可以公开 connectionString 属性,但我敢打赌,在 99% 的情况下都不需要。
  • 但是如何在模型而不是控制器中访问配置?
  • 阅读和尝试的次数越多,我就越意识到获取连接字符串是一项艰巨的任务。无论我尝试什么,我都会得到空值。
  • 是的。太多的计算机科学家为了说“Hello World”而创造了巨大的悬而未决的果实。逆天。熵处于最佳状态。
  • 我同意@JustJohn 的观点,这是不必要的过度设计。连接字符串应该很容易获得,并且不应该花费几个小时来实现。没有必要把所有东西都抽象化并包装在工厂里,天知道还有什么。有些事情应该始终保持简单。
【解决方案2】:

您可以使用 GetConnectionString 扩展方法来做到这一点:

string conString = Microsoft
   .Extensions
   .Configuration
   .ConfigurationExtensions
   .GetConnectionString(this.Configuration, "DefaultConnection");

System.Console.WriteLine(conString);

或为 DI 使用结构化类:

public class SmtpConfig
{
    public string Server { get; set; }
    public string User { get; set; }
    public string Pass { get; set; }
    public int Port { get; set; }
}

启动:

public IConfigurationRoot Configuration { get; }


// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
    // http://developer.telerik.com/featured/new-configuration-model-asp-net-core/
    // services.Configure<SmtpConfig>(Configuration.GetSection("Smtp"));
    Microsoft.Extensions.DependencyInjection.OptionsConfigurationServiceCollectionExtensions.Configure<SmtpConfig>(services, Configuration.GetSection("Smtp"));

然后在家庭控制器中:

public class HomeController : Controller
{

    public SmtpConfig SmtpConfig { get; }
    public HomeController(Microsoft.Extensions.Options.IOptions<SmtpConfig> smtpConfig)
    {
        SmtpConfig = smtpConfig.Value;
    } //Action Controller


    public IActionResult Index()
    {
        System.Console.WriteLine(SmtpConfig);
        return View();
    }

在 appsettings.json 中有这个:

"ConnectionStrings": {
"DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=aspnet-WebApplica71d622;Trusted_Connection=True;MultipleActiveResultSets=true"
},

"Smtp": {
    "Server": "0.0.0.1",
    "User": "user@company.com",
    "Pass": "123456789",
    "Port": "25"
  }

【讨论】:

  • Configure 是一种扩展方法。它应该最常这样使用:services.Configure&lt;SmtpConfig&gt;(Configuration.GetSection("Smtp")); 当然,这几乎是一回事,但我认为不知道的人会以“错误”的方式开始使用未注释的行,因此最好删除该行。 ;)
  • @JedatKinports:不,只有注射。即使您编写静态方法,您仍然需要配置。不过,您可以手动读取 JSON/YAML 文件。但这将消除覆盖,例如用户密码或其他内容(例如来自注册表的配置)。
  • 我收到一个错误:“MyClass 确实包含 'Configuration' 的定义...”
  • 连接字符串部分中的“this.Configuration”指的是什么? GetConnectionString(this.Configuration, "DefaultConnection")
  • 太棒了。而对于ConnectionString,这是一个关于如何去做的问题?
【解决方案3】:

查看链接了解更多信息: https://docs.microsoft.com/en-us/ef/core/miscellaneous/connection-strings

JSON

    {
      "ConnectionStrings": {
        "BloggingDatabase": "Server=(localdb)\\mssqllocaldb;Database=EFGetStarted.ConsoleApp.NewDb;Trusted_Connection=True;"
      },
    }

C# Startup.cs

public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<BloggingContext>(options =>
        options.UseSqlServer(Configuration.GetConnectionString("BloggingDatabase")));
}

编辑:aspnetcore,从 3.1 开始: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration/?view=aspnetcore-3.1

【讨论】:

  • 为什么 JSON 文件应该有 ConnectionStrings 而不是 ConnectionString ?因为当我使用ConnectionString 时,我们得到了空值。
  • @Vijay 然后尝试使用规定的方法 ;) 请查看附加链接。
  • 这个方法在Microsoft.Extensions.Configuration (3.1.5) 看来已经过时了
  • @Ju66ernaut 我相信我的编辑应该让答案恢复相关性
【解决方案4】:

我发现解决此问题的方法是在 Startup 的构建器中使用 AddJsonFile(它允许它找到存储在 appsettings.json 文件中的配置),然后使用它来设置私有 _config 变量

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)
            .AddEnvironmentVariables();
        _config = builder.Build();
    }

然后我可以如下设置配置字符串:

var connectionString = _config.GetConnectionString("DbContextSettings:ConnectionString"); 

这是在 dotnet core 1.1 上

【讨论】:

  • 如何在我的控件中访问_config?
  • 通过将其添加到 Startup.cs 中 ConfigureServices 中的 DI 容器中。
【解决方案5】:

我就是这样做的:

我在 appsettings.json 中添加了连接字符串

"ConnectionStrings": {
"conStr": "Server=MYSERVER;Database=MYDB;Trusted_Connection=True;MultipleActiveResultSets=true"},

我创建了一个名为 SqlHelper 的类

public class SqlHelper
{
    //this field gets initialized at Startup.cs
    public static string conStr;

    public static SqlConnection GetConnection()
    {
        try
        {
            SqlConnection connection = new SqlConnection(conStr);
            return connection;
        }
        catch (Exception e)
        {
            Console.WriteLine(e);
            throw;
        }
    }
}

在 Startup.cs 我使用 ConfigurationExtensions.GetConnectionString 来获取连接,并将其分配给 SqlHelper.conStr

public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
        SqlHelper.connectionString = ConfigurationExtensions.GetConnectionString(this.Configuration, "conStr");
    }

现在只要你需要连接字符串,你就可以这样称呼它:

SqlHelper.GetConnection();

【讨论】:

  • “connectionString”在哪里定义? SqlHelper.connectionString?
【解决方案6】:

ASP.NET Core在我的例子中是 3.1)为我们提供了构造函数注入到控制器中,所以您可以简单地添加以下构造函数:

[Route("api/[controller]")]
[ApiController]
public class TestController : ControllerBase
{
    private readonly IConfiguration m_config;

    public TestController(IConfiguration config)
    {
        m_config = config;
    }

    [HttpGet]
    public string Get()
    {
        //you can get connection string as follows
        string connectionString = m_config.GetConnectionString("Default")
    }
}

appsettings.json 可能如下所示:

{
    "ConnectionStrings": {
        "Default": "YOUR_CONNECTION_STRING"
        }
}

【讨论】:

    【解决方案7】:

    还有另一种方法。在我的示例中,您会在存储库类中看到一些业务逻辑,我在 ASP .NET MVC Core 3.1 中与依赖注入一起使用。

    在这里,我想为该业务逻辑获取 connectiongString,因为可能另一个存储库将完全可以访问另一个数据库。

    这种模式允许您在同一个业务逻辑存储库中访问不同的数据库。

    C#

    public interface IStatsRepository
    {
                IEnumerable<FederalDistrict> FederalDistricts();
    }
    
    class StatsRepository : IStatsRepository
    {
       private readonly DbContextOptionsBuilder<EFCoreTestContext>
                    optionsBuilder = new DbContextOptionsBuilder<EFCoreTestContext>();
       private readonly IConfigurationRoot configurationRoot;
    
       public StatsRepository()
       {
           IConfigurationBuilder configurationBuilder = new ConfigurationBuilder().SetBasePath(Environment.CurrentDirectory)
               .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);
           configurationRoot = configurationBuilder.Build();
       }
    
       public IEnumerable<FederalDistrict> FederalDistricts()
       {
            var conn = configurationRoot.GetConnectionString("EFCoreTestContext");
            optionsBuilder.UseSqlServer(conn);
    
            using (var ctx = new EFCoreTestContext(optionsBuilder.Options))
            { 
                return ctx.FederalDistricts.Include(x => x.FederalSubjects).ToList();
            }
        }
    }
    

    appsettings.json

    {
      "Logging": {
        "LogLevel": {
          "Default": "Information",
          "Microsoft": "Warning",
          "Microsoft.Hosting.Lifetime": "Information"
        }
      },
      "AllowedHosts": "*",
      "ConnectionStrings": {
        "EFCoreTestContext": "Data Source=DESKTOP-GNJKL2V\\MSSQLSERVER2014;Database=Test;Trusted_Connection=True;MultipleActiveResultSets=true"
      }
    }
    

    【讨论】:

      【解决方案8】:

      在 3.1 中已经为“ConnectionStrings”定义了一个部分

      System.Configuration.ConnnectionStringSettings

      定义

        "ConnectionStrings": {
          "ConnectionString": "..."
        }
      

      注册

      public void ConfigureServices(IServiceCollection services)
      {
           services.Configure<ConnectionStringSettings>(Configuration.GetSection("ConnectionStrings"));
      }
      

      注入

      public class ObjectModelContext : DbContext, IObjectModelContext
      {
      
           private readonly ConnectionStringSettings ConnectionStringSettings;
      
          ...
      
           public ObjectModelContext(DbContextOptions<ObjectModelContext> options, IOptions<ConnectionStringSettings> setting) : base(options)
          {
                ConnectionStringSettings = setting.Value;
          }
      
          ...
      }
      

      使用

         public static void ConfigureContext(DbContextOptionsBuilder optionsBuilder, ConnectionStringSettings connectionStringSettings)
          {
              if (optionsBuilder.IsConfigured == false)
              {
                  optionsBuilder.UseLazyLoadingProxies()
                                .UseSqlServer(connectionStringSettings.ConnectionString);
              }
          }
      

      【讨论】:

        【解决方案9】:

        在 .NET Core 6 中

        appsettings.json

         "ConnectionStrings": {
           "DefaultConnection": "Server=**Server Name**;Database=**DB NAME**;Trusted_Connection=True;MultipleActiveResultSets=true"
          }
        

        Program.cs

        var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
        builder.Services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(connectionString));
        

        数据库上下文

        public class ApplicationDbContext : DbContext
        {
            public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options)
            {
        
            }
        
        }
        

        【讨论】:

          【解决方案10】:

          为时已晚,但在阅读了所有有用的答案和 cmets 之后,我最终使用了 Microsoft.Extensions.Configuration.Binder 扩展包并尝试摆脱硬编码的配置键。

          我的解决方案:

          IConfigSection.cs

          public interface IConfigSection
          {
          }
          

          ConfigurationExtensions.cs

          public static class ConfigurationExtensions
          {
              public static TConfigSection GetConfigSection<TConfigSection>(this IConfiguration configuration) where TConfigSection : IConfigSection, new()
              {
                  var instance = new TConfigSection();
                  var typeName = typeof(TConfigSection).Name;
                  configuration.GetSection(typeName).Bind(instance);
          
                  return instance;
              }
          }
          

          appsettings.json

          {
             "AppConfigSection": {
                "IsLocal": true
             },
             "ConnectionStringsConfigSection": {
                "ServerConnectionString":"Server=.;Database=MyDb;Trusted_Connection=True;",
                "LocalConnectionString":"Data Source=MyDb.db",
             },
          }
          

          要访问强类型配置,您只需要为此创建一个类,该类实现 IConfigSection 接口(注意:类名和字段名应完全匹配部分在 appsettings.json)

          AppConfigSection.cs

          public class AppConfigSection: IConfigSection
          {
              public bool IsLocal { get; set; }
          }
          

          ConnectionStringsConfigSection.cs

          public class ConnectionStringsConfigSection : IConfigSection
          {
              public string ServerConnectionString { get; set; }
              public string LocalConnectionString { get; set; }
          
              public ConnectionStringsConfigSection()
              {
                  // set default values to avoid null reference if
                  // section is not present in appsettings.json
                  ServerConnectionString = string.Empty;
                  LocalConnectionString = string.Empty;
              }
          }
          

          最后是一个用法示例:

          Startup.cs

          public class Startup
          {
              public Startup(IConfiguration configuration)
              {
                  Configuration = configuration;
              }
          
              public IConfiguration Configuration { get; }
          
              public void ConfigureServices(IServiceCollection services)
              {
                  // some stuff
          
                  var app = Configuration.GetConfigSection<AppConfigSection>();
                  var connectionStrings = Configuration.GetConfigSection<ConnectionStringsConfigSection>();
          
                  services.AddDbContext<AppDbContext>(options =>
                  {
                      if (app.IsLocal)
                      {
                          options.UseSqlite(connectionStrings.LocalConnectionString);
                      }
                      else
                      {
                          options.UseSqlServer(connectionStrings.ServerConnectionString);
                      }
                  });
          
                  // other stuff
              }
          }
          

          为了简洁,你可以将上面的代码移到扩展方法中。

          就是这样,没有硬编码的配置键。

          【讨论】:

            【解决方案11】:
            private readonly IConfiguration configuration;
                    public DepartmentController(IConfiguration _configuration)
                    {
                        configuration = _configuration;
                    }
            
                    [HttpGet]
                    public JsonResult Get()
                    {
            string sqlDataSource = configuration["ConnectionStrings:DefaultConnection"];
            

            【讨论】:

              【解决方案12】:
              【解决方案13】:

              我有一个可与 .net 核心和 .net 框架一起使用的数据访问库。

              诀窍是在 .net 核心项目中将连接字符串保存在名为“app.config”的 xml 文件中(也适用于 Web 项目),并将其标记为“复制到输出目录”,

              <?xml version="1.0" encoding="utf-8"?>
              <configuration>
                <connectionStrings>
                  <add name="conn1" connectionString="...." providerName="System.Data.SqlClient" />
                </connectionStrings>
              </configuration>
              

              ConfigurationManager.ConnectionStrings - 将读取连接字符串。

                  var conn1 = ConfigurationManager.ConnectionStrings["conn1"].ConnectionString;
              

              【讨论】:

              • 如果您使用的是 .NET Core,最好采用它的配置模式,而不是硬塞进 .NET Framework 模式。
              猜你喜欢
              • 2020-07-05
              • 2012-09-24
              • 1970-01-01
              • 2020-07-30
              • 2019-01-07
              • 2016-10-02
              • 1970-01-01
              • 2016-12-17
              相关资源
              最近更新 更多