.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

@ジェームズウィルキンス:非常に有効な懸念。しかし、私は実際には、この表記法を拡張メソッドとして使用するよりも好みます。これにより、どこで何が行われているのかがわかり、インポート名前空間がないために問題が発生することなく、1つの場所から別の場所にコピーして貼り付けることができます。唯一の問題は、MSが名前の衝突防止の代わりに分類法にネームスペースを使用することです。そのため、ネームスペースが長すぎます。また、名前空間を削除して拡張メソッドを使用すると、同じ種類の人々がコードがコンパイルされないことについて不平を言うようになります。誰もがIDEを使用するわけではないので、この方法の方が適しています。
Stefan Steiger 2017年

3
@JedatKinports:いいえ、注入のみ。静的メソッドを作成する場合でも、構成は必要です。ただし、JSON / YAMLファイルを手動で読み取ることもできます。ただし、これにより、usersecretsなどの上書き(レジストリからの構成など)が排除されます。
Stefan Steiger

1
「MyClassには 'Configuration'の定義が含まれています...」というエラーが表示されます
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%のケースでは不要になると思います。
シュテファンシュタイガー

2
しかし、コントローラではなくモデルの構成にアクセスするにはどうすればよいですか?
タンメイ

2
物事を読んで試してみると、接続文字列を取得することは大きな仕事であることがわかります。何を試してもヌルになるだけです。
MC9000

7
うん。「Hello World」と言うだけで巨大な高ぶるぶるフルーツを生み出しているコンピューター科学者が多すぎます。信じられない。エントロピーは最高です。
JustJohn

2
@JustJohn:私はあなたの不満を理解していますが、適切なデザインはテスト可能です。つまり、コンストラクターで依存関係を渡す必要があります。そうでなければ、アプリケーション/フレームワークは単体テストできません。これは適切な設計でもあります。多くのコードを変更する必要なく、コンポーネントを単に置き換えることができるためです。100個の引数を渡したくない場合は、System.IServiceProviderをクラスに渡して、依存関係をそこにフェッチすることもできます。しかし、もう一方の側面は、複雑さが増すことです。
ステファンシュタイガー

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

これを解決するために見つけた方法は、起動時にビルダーで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

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.