Làm cách nào để đọc chuỗi kết nối trong .NET Core?


108

Tôi chỉ muốn đọc một chuỗi kết nối từ tệp cấu hình và đối với việc này, hãy thêm tệp có tên "appsettings.json" vào dự án của tôi và thêm nội dung này vào đó:

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

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

Trên ASP.NET, tôi đã sử dụng cái này:

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

Bây giờ làm cách nào để đọc "DefaultConnection" trong C # và lưu trữ nó trên một biến chuỗi trong .NET Core?


Câu trả lời:


101

Bạn có thể thực hiện việc này bằng phương thức mở rộng GetConnectionString:

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

System.Console.WriteLine(conString);

hoặc với một lớp có cấu trúc cho DI:

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

Khởi động:

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

Và sau đó trong bộ điều khiển gia đình:

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();
    }

với điều này trong 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
Configurelà một phương thức mở rộng. Nó nên được sử dụng phổ biến nhất như thế này: services.Configure<SmtpConfig>(Configuration.GetSection("Smtp"));Chắc chắn, nó cũng giống như vậy, nhưng tôi nghĩ những người không biết sẽ bắt đầu làm nó theo cách "sai", sử dụng dòng không có chú thích, vì vậy có lẽ tốt nhất là xóa dòng. ;)
James Wilkins

@James Wilkins: Mối quan tâm rất xác đáng. Tuy nhiên, tôi thực sự thích ký hiệu này hơn là sử dụng nó làm phương thức mở rộng - bằng cách này tôi biết những gì đang được thực hiện ở đâu và có thể sao chép-dán từ nơi này sang nơi khác mà không gặp sự cố vì thiếu không gian tên nhập. Vấn đề duy nhất là MS sử dụng không gian tên để phân loại thay vì ngăn chặn xung đột tên - do đó, không gian tên quá dài. Ngoài ra, nếu bạn loại bỏ các không gian tên và sử dụng các phương thức mở rộng, những người tương tự sẽ bắt đầu phàn nàn về việc mã không được biên dịch. Không phải ai cũng sử dụng IDE, vì vậy cách này tốt hơn.
Stefan Steiger

3
@JedatKinports: Không, chỉ tiêm thôi. Ngay cả khi bạn viết một phương thức tĩnh, bạn vẫn cần cấu hình. Tuy nhiên, bạn chỉ có thể đọc tệp JSON / YAML theo cách thủ công. Nhưng điều đó sẽ loại bỏ ghi đè, chẳng hạn như bí mật người dùng hoặc những thứ khác (ví dụ: cấu hình từ sổ đăng ký).
Stefan Steiger

1
Tôi nhận được một lỗi: "MyClass có chứa một định nghĩa cho 'Cấu hình' ..."
Robert Smith

3
"This.Configuration" đề cập đến điều gì trong phần chuỗi kết nối? GetConnectionString (this.Configuration, "DefaultConnection")
MC9000 22/09/19

111

Câu trả lời đã đăng là tốt nhưng không trả lời trực tiếp câu hỏi tương tự mà tôi đã có về việc đọc trong một chuỗi kết nối. Qua nhiều tìm kiếm, tôi đã tìm thấy một cách đơn giản hơn một chút để làm việc này.

Trong Startup.cs

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

Trong bộ điều khiển của bạn, hãy thêm một trường cho cấu hình và một tham số cho nó trên một hàm tạo

private readonly IConfiguration configuration;

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

Bây giờ, sau này trong mã chế độ xem của bạn, bạn có thể truy cập nó như:

connectionString = configuration.GetConnectionString("DefaultConnection");

2
Sẽ không làm như vậy. Nếu bạn làm việc mà không có khung thực thể, tốt hơn bạn nên đăng ký một nhà máy kết nối dưới dạng singleton, ví dụ: để sử dụng với dapper. Sau đó, bạn vẫn có thể hiển thị thuộc tính connectionString nếu cần, nhưng tôi cá rằng nó sẽ không cần thiết trong 99% trường hợp.
Stefan Steiger

2
Nhưng làm thế nào để truy cập Cấu hình trong Mô hình thay vì Bộ điều khiển?
Tanmay

2
Tôi càng đọc và thử nhiều thứ, tôi càng nhận ra rằng việc nhận được một chuỗi kết nối là một nhiệm vụ chính. Tôi chỉ nhận được nulls bất kể tôi cố gắng gì.
MC9000

7
Vâng. Quá nhiều nhà khoa học máy tính tạo ra quả treo cao khổng lồ chỉ để nói "Xin chào thế giới". Không thể tin được. Entropy ở mức tốt nhất.
JustJohn

2
@JustJohn: Tôi hiểu sự than phiền của bạn, nhưng thiết kế phù hợp có thể kiểm tra được và điều đó có nghĩa là bạn phải vượt qua các phụ thuộc trong phương thức khởi tạo, nếu không ứng dụng / khuôn khổ của bạn không thể kiểm tra đơn vị. Đây cũng là thiết kế phù hợp, vì bạn có thể chỉ cần thay thế một thành phần này bằng một thành phần khác, mà không cần phải thay đổi toàn bộ mã. Nếu bạn không muốn chuyển 100 đối số xung quanh, bạn cũng có thể truyền System.IServiceProvider vào lớp, sau đó bạn có thể tìm nạp các phụ thuộc ở đó. Nhưng mặt khác của đồng xu là điều này đi kèm với sự phức tạp hơn.
Stefan Steiger

18

Xem liên kết để biết thêm thông tin: https://docs.microsoft.com/en-us/ef/core/mis linh tinh/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")));
}

CHỈNH SỬA: aspnetcore, bắt đầu 3.1: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration/?view=aspnetcore-3.1


Tại sao nên có tệp JSON ConnectionStringsthay vì ConnectionString? Bởi vì khi tôi sử dụng ConnectionString, sau đó chúng tôi nhận được giá trị không.
Vijay

@Vijay Hãy thử sử dụng phương pháp được chỉ định sau đó;) Vui lòng xem liên kết đính kèm.
markokstate

1
Phương pháp này có vẻ đã lỗi thời kể từ Microsoft.Extensions.Configuration(3.1.5)
Ju66ernaut

7

Cách mà tôi tìm ra để giải quyết vấn đề này là sử dụng AddJsonFile trong trình tạo ở Startup (cho phép nó tìm thấy cấu hình được lưu trữ trong tệp appsettings.json) và sau đó sử dụng nó để đặt biến _config riêng tư

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();
    }

Và sau đó tôi có thể đặt chuỗi cấu hình như sau:

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

Đây là trên dotnet core 1.1


5
làm cách nào để truy cập _config trong quyền kiểm soát của tôi?
nắng

Bằng cách thêm nó vào vùng chứa DI trong ConfigureServices trong Startup.cs.
Stefan Steiger

3

ASP.NET Core ( trong trường hợp của tôi là 3.1 ) cung cấp cho chúng tôi hàm tạo Khối lệnh vào Bộ điều khiển , vì vậy bạn có thể chỉ cần thêm hàm tạo sau:

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

Dưới đây, appsettings.json có thể trông như thế nào:

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

0

Có một cách tiếp cận khác. Trong ví dụ của tôi, bạn thấy một số logic nghiệp vụ trong lớp kho lưu trữ mà tôi sử dụng với việc tiêm phụ thuộc trong ASP .NET MVC Core 3.1.

Và ở đây tôi muốn lấy connectiongStringlogic nghiệp vụ đó vì có thể một kho lưu trữ khác sẽ có quyền truy cập vào cơ sở dữ liệu khác.

Mẫu này cho phép bạn trong cùng một kho lưu trữ logic nghiệp vụ có quyền truy cập vào các cơ sở dữ liệu khác nhau.

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

tôi có một thư viện truy cập dữ liệu hoạt động với cả .net core và .net framework.

thủ thuật nằm trong các dự án lõi .net để giữ các chuỗi kết nối trong tệp xml có tên "app.config" (cũng dành cho các dự án web) và đánh dấu nó là 'sao chép vào thư mục đầu ra',

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

ConfigurationManager.ConnectionStrings - sẽ đọc chuỗi kết nối.

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

Nếu bạn đang sử dụng .NET Core, tốt nhất nên sử dụng mẫu cấu hình của nó thay vì áp dụng mẫu .NET Framework.
Simmetric

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.