如何在.NET Core中读取连接字符串?


108

我只想从配置文件中读取连接字符串,为此向我的项目中添加一个名称为“ 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中的字符串变量中?


Answers:


101

您可以使用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"
  }

9
Configure是一种扩展方法。应该最常这样使用它:services.Configure<SmtpConfig>(Configuration.GetSection("Smtp"));当然,这是几乎相同的事情,但是我认为没有意识到的人会以“错误”的方式开始使用未注释的行,因此最好删除该行。;)
James Wilkins

@詹姆斯·威尔金斯:非常有效的担忧。但是,我实际上更喜欢这种表示法,而不是将其用作扩展方法-这样,我就知道在哪里进行操作,并且可以将粘贴从一个位置复制粘贴到另一个位置,而不会因为缺少导入名称空间而出现问题。唯一的问题是,MS使用名称空间进行分类,而不是防止名称冲突-因此,名称空间太长。同样,如果删除命名空间并使用扩展方法,同一类人将开始抱怨代码未编译。并非每个人都使用IDE,所以这样更好。
Stefan Steiger

3
@JedatKinports:不,只能注射。即使您要编写静态方法,也仍然需要配置。不过,您可以手动读取JSON / YAML文件。但这将消除诸如用户秘密或其他(例如来自注册表的配置)之类的覆盖。
Stefan Steiger '18

1
我收到一个错误:“ MyClass确实包含“配置”的定义...”
Robert Smith,

3
连接字符串部分中指的“ this.Configuration”是什么?GetConnectionString(this.Configuration,“ DefaultConnection”)
MC9000,19年

111

发布的答案很好,但是没有直接回答关于读取连接字符串的相同问题。通过大量搜索,我发现了一种更简单的方法。

在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");

2
不会那样做。如果没有实体框架,则最好将连接工厂注册为单例,例如与dapper一起使用。然后,您仍然可以根据需要公开一个connectionString属性,但是我敢保证在99%的情况下都不需要。
Stefan Steiger '18

2
但是,如何访问模型而不是控制器中的配置?
坦美

2
我阅读和尝试的内容越多,我就越意识到获得连接字符串是一项主要任务。无论我尝试什么,我都会得到null。
MC9000

7
是的 太多的计算机科学家仅仅为了说“ Hello World”而创造了巨大的成就。难以置信的。熵是最好的。
JustJohn

2
@JustJohn:我理解您的不满,但是正确的设计是可以测试的,这意味着您必须在构造函数中传递依赖关系,否则您的应用程序/框架不能进行单元测试。这也是正确的设计,因为您可以将一个组件替换为另一个组件,而无需更改大量代码。如果您不想传递100个参数,也可以将System.IServiceProvider传递给该类,然后可以在其中获取依赖项。但是另一方面,这带来了更多的复杂性。
Stefan Steiger,

18

请参阅链接以获取更多信息:https : //docs.microsoft.com/zh-cn/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/zh-cn/aspnet/core/fundamentals/configuration/?view = aspnetcore-3.1


为什么应使用JSON文件ConnectionStrings而不是ConnectionString?因为当我使用时ConnectionString,我们将为空。
维杰

@Vijay然后尝试使用规定的方法;)请参阅附件链接。
markokstate

1
Microsoft.Extensions.Configuration(3.1.5)开始,此方法似乎已过时
Ju66ernaut

7

我发现解决此问题的方法是在启动时在构建器中使用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上


5
如何在控件中访问_config?
阳光明媚的

通过将其添加到Startup.cs的ConfigureServices中的DI容器中。
Stefan Steiger '18

3

ASP.NET Core在我的情况下为3.1)为我们提供了到Controllers的构造函数注入,因此您可以简单地添加以下构造函数:

[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"
        }
}

0

还有另一种方法。在我的示例中,您看到了存储库类中的一些业务逻辑,这些逻辑与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"
  }
}

-1

我有一个数据访问库,可与.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模式中费力。
Simmetric

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.