ConfigurationManagerを使用して任意の場所から構成をロードする


124

従来のASPページとASP.NETページが混在するWebサイトで使用されるデータアクセスコンポーネントを開発しています。その構成設定を管理するための優れた方法が必要です。

カスタムを使用したいのConfigurationSectionですが、ASP.NETページの場合、これはうまく機能します。ただし、コンポーネントが従来のASPページからCOM相互運用機能を介して呼び出された場合、コンポーネントはASP.NET要求のコンテキストで実行されていないため、web.configに関する知識がありません。

ConfigurationManager任意のパスから構成をロードするように指示する方法はあります..\web.configか(たとえば、アセンブリが/binフォルダーにある場合)?存在する場合、カスタムセクションのデフォルトConfigurationManager.GetSectionが返さnullれた場合、コンポーネントはそれにフォールバックできると考えています。

これに対する他のアプローチは歓迎されます!


回答:


124

これを試して:

System.Configuration.ConfigurationFileMap fileMap = new ConfigurationFileMap(strConfigPath); //Path to your config file
System.Configuration.Configuration configuration = System.Configuration.ConfigurationManager.OpenMappedMachineConfiguration(fileMap);

sub.domain.com/virtualDir2でホストされているASP.NET WebFormsアプリケーションのstrConfigPath値とパスC:\ Portals \ App1 \ v2およびC:\ Portals \ App1 \ v2 \ web.configの構成ファイルプログラムで 取得するにはどうすればよいですか?
Kiquenet 2015年

1
@Kiquenet:問題の要点は、strConfigPathが任意の場所であるということです。つまり、フレームワークに依存して従来の場所から構成ファイルをロードするのではなく、パス決定します。Server.MapPathがソリューション内のファイルの絶対的な場所を提供すると思います。
Ishmaeel、2015年

1
たぶんvar config = System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration("~/web.config");
Kiquenet、2015年

@Kiquenet間違いなく。
ウチョ

66

別の解決策は、デフォルトの環境設定ファイルのパスを上書きすることです。

私はそれが重要なパスの構成ファイルの読み込み、特に構成ファイルをdllに添付するための最良の方法の最良の解決策だと思います。

AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", <Full_Path_To_The_Configuration_File>);

例:

AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", @"C:\Shared\app.config");

詳細については、このブログをご覧ください。

さらに、この他の回答には優れたソリューションがあり、アプリの構成を更新するコードと、IDisposableそれを元の状態にリセットするオブジェクトが備わっています。このソリューションを使用すると、一時的なアプリ構成のスコープを維持できます。

using(AppConfig.Change(tempFileName))
{
    // tempFileName is used for the app config during this context
}

1
これは、web.configファイルのロードにも機能します。タスク関連のコンソールアプリのapp.configではなく、web.configを読み込むために使用します。;)
James Wilkins

1
これ(およびここでの他の答え)は私にはうまくいきません。私はprogram.csにコードを追加しました-関数:Main()。私の構成には、アセンブリバージョンのリダイレクト(stackoverflow.com/questions/30165393/…を参照)が含まれていますが、構成を手動で変更してもリダイレクトは影響しません。
Vortex852456 2015年

1
「APP_CONFIG_FILE」を使用しましたか?
Saturn Technologies

40

Ishmaeelの答えは一般的には機能しOpenMappedMachineConfigurationますが、使用するとmachine.configから継承したセクショングループが失われるように見えるという問題が1つ見つかりました。これは、独自のカスタムセクション(必要なすべてのOP)にアクセスできますが、通常のシステムセクションにはアクセスできないことを意味します。たとえば、次のコードは機能しません。

ConfigurationFileMap fileMap = new ConfigurationFileMap(strConfigPath);
Configuration configuration = ConfigurationManager.OpenMappedMachineConfiguration(fileMap);
MailSettingsSectionGroup thisMail = configuration.GetSectionGroup("system.net/mailSettings") as MailSettingsSectionGroup;  // returns null

基本的に、時計を configuration.SectionGroups system.netがSectionGroupとして登録されていないため、通常のチャネルからはほとんどアクセスできません。

これを回避するには2つの方法があります。最初は、私が好きではありませんが、machine.configから独自のweb.configにコピーして、システムセクショングループを再実装することです。

<sectionGroup name="system.net" type="System.Net.Configuration.NetSectionGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
  <sectionGroup name="mailSettings" type="System.Net.Configuration.MailSettingsSectionGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
    <section name="smtp" type="System.Net.Configuration.SmtpSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
  </sectionGroup>
</sectionGroup>

その後、Webアプリケーション自体が正しく実行されるかどうかはわかりませんが、sectionGroupsに正しくアクセスできます。

2つ目の解決策は、代わりにweb.configをEXE構成として開くことです。これはおそらくいずれにしても、目的の機能に近いものです。

ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap() { ExeConfigFilename = strConfigPath };
Configuration configuration = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
MailSettingsSectionGroup thisMail = configuration.GetSectionGroup("system.net/mailSettings") as MailSettingsSectionGroup;  // returns valid object!

ここで提供された答えのどれも、私のものでもIshmaeelのものでも、.NETデザイナーが意図した方法でこれらの関数をまったく使用していません。しかし、これは私にはうまくいくようです。


1
同じ目的でConfigurationManager.OpenExeConfiguration(String)オーバーロードを使用することもできます。参照:codeproject.com/KB/dotnet/mysteriesofconfiguration3.aspx#t2_1
シュナイダー、

10

Ishmaeelの回答に加えて、メソッドOpenMappedMachineConfiguration()は常にConfigurationオブジェクトを返します。したがって、読み込まれたかどうかを確認するには、HasFileプロパティをチェックする必要があります。trueは、ファイルから取得したことを意味します。


9

受け入れられた答えは間違っています!!

AppSettingsプロパティにアクセスすると、次の例外がスローされます。

タイプ「System.Configuration.DefaultSection」のオブジェクトをタイプ「System.Configuration.AppSettingsSection」にキャストできません。

これが正しい解決策です:

System.Configuration.ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap();
fileMap.ExeConfigFilename = "YourFilePath";
System.Configuration.Configuration configuration = System.Configuration.ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);

1
はい、これは間違いなく正しい答えです!回答を投稿していただきありがとうございます。
Fabio Milheiro

System.Web.Configuration.WebConfigurationManager.OpenWebConfigurationの方が正しいと思いますが、.NET Coreでは使用できないので、この場合、この回答で問題が解決したようです。
Risord

4

次のように、ワードホストの.nETコンポーネントに構成値を指定しました。

MS Wordで呼び出される/ホストされる.NETクラスライブラリコンポーネント。コンポーネントに構成値を提供するために、C:\ Program Files \ Microsoft Office \ OFFICE11フォルダーにwinword.exe.configを作成しました。従来の.NETで行うように構成値を読み取ることができるはずです。

string sMsg = System.Configuration.ConfigurationManager.AppSettings["WSURL"];

1

ASP.NETの場合は、WebConfigurationManagerを使用します。

var config = WebConfigurationManager.OpenWebConfiguration("~/Sites/" + requestDomain + "/");
(..)
config.AppSettings.Settings["xxxx"].Value;

0

XML処理を使用します。

var appPath = AppDomain.CurrentDomain.BaseDirectory;
var configPath = Path.Combine(appPath, baseFileName);;
var root = XElement.Load(configPath);

// can call root.Elements(...)

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