.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의 문자열 변수에 저장하려면 어떻게해야합니까?


답변:


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

@James Wilkins : 매우 유효한 문제입니다. 그러나 실제로는 확장 방법으로 사용하는 것보다이 표기법을 선호합니다. 이렇게하면 어디서 수행되고 있는지 알 수 있으며 가져 오기 네임 스페이스 누락으로 인한 문제없이 한 위치에서 다른 위치로 복사하여 붙여 넣을 수 있습니다. 유일한 문제는 MS가 이름 충돌 방지 대신 분류에 네임 스페이스를 사용한다는 것입니다. 그 때문에 네임 스페이스가 너무 깁니다. 또한 이름 공간을 제거하고 확장 메서드를 사용하면 같은 종류의 사람들이 코드가 컴파일되지 않는다고 불평하기 시작합니다. 모든 사람이 IDE를 사용하는 것은 아니므로이 방법이 더 좋습니다.
Stefan Steiger 2017 년

3
@JedatKinports : 아니요, 주입 만합니다. 정적 메서드를 작성하더라도 구성이 필요합니다. 하지만 JSON / YAML 파일을 수동으로 읽을 수 있습니다. 그러나 이렇게하면 usersecrets 또는 기타 (예 : 레지스트리의 구성)와 같은 덮어 쓰기가 제거됩니다.
Stefan Steiger

1
오류가 발생합니다. "MyClass에 '구성'에 대한 정의가 포함되어 있습니다 ..."
Robert Smith

3
연결 문자열 부분에서 참조하는 "this.Configuration"은 무엇입니까? GetConnectionString (this.Configuration, "DefaultConnection")
MC9000

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 2018

2
그러나 컨트롤러 대신 모델의 구성에 액세스하는 방법은 무엇입니까?
Tanmay

2
더 많이 읽고 시도할수록 연결 문자열을 얻는 것이 중요한 작업이라는 것을 더 많이 깨닫습니다. 나는 내가 무엇을 시도하더라도 null을 얻습니다.
MC9000

7
네. 너무나 많은 컴퓨터 과학자들이 "Hello World"라고 말하기 위해 거대한 높은 매달린 과일을 만들고 있습니다. 믿을 수 없는. 엔트로피가 가장 좋습니다.
JustJohn

2
@JustJohn : 귀하의 불만을 이해하지만 적절한 디자인은 테스트 할 수 있으며 이는 생성자에서 종속성을 전달해야 함을 의미합니다. 그렇지 않으면 애플리케이션 / 프레임 워크가 단위 테스트가 불가능합니다. 이것은 또한 많은 코드를 변경하지 않고도 한 구성 요소를 다른 구성 요소로 교체 할 수 있으므로 적절한 디자인입니다. 100 개의 인수를 전달하지 않으려면 System.IServiceProvider를 클래스에 전달한 다음 여기에서 종속성을 가져올 수도 있습니다. 그러나 동전의 다른 측면은 이것이 복잡성이 추가된다는 것입니다.
Stefan Steiger 19 년

18

자세한 내용은 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


ConnectionStrings대신 JSON 파일에 있어야하는 이유는 무엇 ConnectionString입니까? 을 사용할 때 ConnectionString우리는 null을 얻습니다.
Vijay

@Vijay 그런 다음 규정 된 방법을 사용해보십시오;) 첨부 된 링크를 참조하십시오.
markokstate

1
이 방법은 Microsoft.Extensions.Configuration(3.1.5) 현재 구식으로 보입니다
Ju66ernaut

7

이 문제를 해결하기 위해 찾은 방법은 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에 있습니다.


5
내 컨트롤에서 _config에 액세스하려면 어떻게해야합니까?
sunny

Startup.cs의 ConfigureServices에서 DI 컨테이너에 추가합니다.
Stefan Steiger

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다른 저장소가 다른 데이터베이스에 전혀 액세스 할 수 없기 때문에 해당 비즈니스 논리 를 얻고 싶습니다 .

이 패턴을 사용하면 동일한 비즈니스 로직 저장소에서 다른 데이터베이스에 액세스 할 수 있습니다.

씨#

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 파일 (웹 프로젝트 용)에 연결 문자열을 유지하고 '출력 디렉터리에 복사'로 표시하는 것이 었습니다.

<?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

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.