web-dev-qa-db-ja.com

実稼働ASP.Net Core MVCアプリケーションによる取得のために、環境変数に接続文字列を正しく格納する方法

ASP.NET Core MVCアプリケーションで作業していますが、接続文字列に問題があります。

実稼働サーバーでASPNETCORE_ENVIRONMENT変数がProductionに設定されており、実稼働サーバーはIISを実行しているWindows Server 2012R2です。また、運用サーバーにDotNetCore.1.0.4_1.1.1-WindowsHosting.exeがインストールされています。

開発中、UserSecretsを使用して接続文字列を保持しています。これは正常に機能しています。

実稼働環境では、実稼働サーバーの環境変数に接続文字列が必要です。ここで問題が発生しています。環境変数を構造化する方法に問題があるのではないかと思います。

実稼働環境でデータベースにアクセスしようとすると、基本的に接続文字列を解析できないことを示すエラーが表示されます。

An exception occurred in the database while iterating the results of a query.

System.ArgumentException: Keyword not supported: '"server'.
at System.Data.Common.DbConnectionOptions.ParseInternal(Dictionary`2 
parsetable, String connectionString, Boolean buildChain, Dictionary`2 synonyms)
at System.Data.Common.DbConnectionOptions..ctor(String connectionString, Dictionary`2 synonyms)
at System.Data.SqlClient.SqlConnectionString..ctor(String connectionString)

接続文字列をappSettings.jsonに入れると、運用サーバーは正常に機能します。

そのため、ここに、実動で機能する接続文字列を示すappSettings.jsonファイルの例を示します。

{
  "ConnectionStrings": {
     "TestDb": "Server=TestServer;Database=TestDb;Persist Security Info=True;User ID=TestUser;Password=testpassword;MultipleActiveResultSets=true"
  },

    ...
    ...
    ...
  }
}

このappSettings.jsonファイルを運用環境に展開すると、正常に機能します。

ASP.Net CoreアプリケーションのStartup.csファイルには、次のものがあります。

public Startup(IHostingEnvironment env)
{
    var builder = new ConfigurationBuilder()
        .SetBasePath(env.ContentRootPath)
        .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
        .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true);

    if (env.IsDevelopment())
    {
        // For more details on using the user secret store see https://go.Microsoft.com/fwlink/?LinkID=532709
        builder.AddUserSecrets<Startup>();
    }

    builder.AddEnvironmentVariables();
    Configuration = builder.Build();

}

私の理解では、リストされている最後のbuilder.add ...が優先されるため、私の場合、接続文字列が環境内に存在する場合、appsettingsのどの文字列よりも優先されるはずです。

したがって、実稼働環境で、次のappSettings.configファイルを使用すると、

{
  "ConnectionStrings": {
     "TestDb": "Placeholder for connection string. Overridden by User Secrets in Development and Environment Variables in Production. "
  },

    ...
    ...
    ...
  }
}

接続文字列の環境変数がある場合、ConnectionStrings:TestDbファイルのappsettings.jsonの値として何を持っているかは問題ではありません。

以下は、私が使用している環境変数です。

Variable                    Value
ConnectionStrings:TestDb    "Server=TestServer;Database=TestDb;Persist Security Info=True;User ID=TestUser;Password=testpassword;MultipleActiveResultSets=true"

ただし、このセットアップを使用すると、データベースにアクセスしようとすると、接続文字列を解析できないことを示すエラーが表示されます。

私は問題が環境変数で指定された接続文字列を持っている方法であると仮定する必要がありますが、かなり長い時間オンラインで検索した後、私は環境変数の値がどのように見えるべきかの例を見つけることができませんでした。たとえば、文字列全体を前後に単一引用符で囲む必要がありますか?接続文字列の個々のセクションには一重引用符または二重引用符が必要ですか?

環境変数で定義された適切な接続文字列の例など、どんな助けでも大歓迎です。

20
EiEiGuy

接続変数にタイプミス/間違った値が設定されています。

貼り付けた次の出力で確認できます。

_Variable                    Value
ConnectionStrings:TestDb    "Server=TestServer;Database=TestDb;Persist Security Info=True;User ID=TestUser;Password=testpassword;MultipleActiveResultSets=true"
_

これは、変数の設定中に発生した可能性があります

_$env:ConnectionStrings:MyDb = """Server=..."""
_

正しい方法は、引用符なしで設定することです。

_$env:ConnectionStrings:MyDb = "Server=..."
_

古い回答(同様の問題を検索する他のユーザー向け)

接続文字列の規則は_SQLCONNSTR__、_MYSQLCONNSTR__、_SQLAZURECONNSTR__、および_CUSTOMCONNSTR__であり、Azure Web Appsで使用されますが、セルフホスティング、VMまたはその他にも機能するはずですクラウドプロバイダー。

したがって、_CUSTOMCONNSTR_TestDb_という環境変数がある場合は、appsettings.jsonで定義するのと同じになります。

_{
    "connectionStrings": {
        "TestDb": "..."
    }
}
_

AddEnvironmentVariables()の後に.UseJsonFile(...)が呼び出された場合、その中の値もオーバーライドします。最後の登録が勝ちます。

_var builder = new ConfigurationBuilder()
    .SetBasePath(env.ContentRootPath)
    .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
    .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
    // This one needs to be last
    .AddEnvironmentVariables();
_

他の変数を使用して、構成値をオーバーライドすることもできます。ちゃんと覚えたら。 _ASPNETCORE__はデフォルトのプレフィックスです(ただし、AddEnvironmentVariables("MY_")で変更できます)。

したがって、_ASPNETCORE_MySettings_は_Configuration["MySettings"]_(またはConfiguration.Get("MySettings"))および_ASPNETCORE_My__Settings_をオーバーライドします(Linuxのレベル階層にはdouble underscoreを使用し、_:_は構成を取得するために使用されます-Linuxは変数名にコロンを許可しません)と同じように_Configuration["My:Settings"]_をオーバーライドします

_{
    "my": {
        "settings": "..."
    }
}
_

最近変更しない限り。

FWIW:私が覚えている限り、環境変数/構成キー名は大文字と小文字を区別しません。

19
Tseng

設定には次の行があります。

.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true);

これは、環境固有の設定を含むJSONファイルが存在する可能性があることを構成システムに伝えています。したがって、次のようなものを含むappSettings.Production.configという本番ボックスに存在するファイルのみが必要です。

{
  "ConnectionStrings": {
     "TestDb": "Server=...;Catalog=...;Etc=..."
  }
}

ここの値は、ベースJSON設定ファイルで指定されたものを上書きします。

0
DavidG