ConfigurationManager를 사용하여 임의 위치에서 구성로드


124

클래식 ASP와 ASP.NET 페이지가 혼합 된 웹 사이트에서 사용할 데이터 액세스 구성 요소를 개발 중이며 구성 설정을 관리하는 좋은 방법이 필요합니다.

사용자 지정을 사용하고 싶습니다 ConfigurationSection. ASP.NET 페이지의 경우 이것은 훌륭하게 작동합니다. 그러나 구성 요소가 클래식 ASP 페이지에서 COM interop을 통해 호출 될 때 구성 요소는 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);

어떻게 얻을 수있는 프로그램 strConfigPath의 내 ASP.NET 가치 웹폼 에서 호스팅되는 응용 프로그램 sub.domain.com/virtualDir2 및 경로 C를 : \ 포털 \ 앱 1 \ V2설정 파일C : \ 포털 \ 앱 1 \ v2를 \의 Web.config ?
Kiquenet

1
@Kiquenet : 질문의 요점은 strConfigPath가 임의의 위치라는 것입니다. 즉, 당신은 경로 대신 기존의 위치에서 설정 파일을로드하려고하는 프레임 워크에 의존, 무엇인지 결정합니다. Server.MapPath 가 솔루션 내의 모든 파일에 대한 절대 위치를 제공 한다고 가정 합니다.
Ishmaeel

1
아마var config = System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration("~/web.config");
Kiquenet

@Kiquenet 확실히.
Ucho

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 2015 년

1
이것은 (및 여기의 다른 답변) 저에게 효과가 없습니다. program.cs-function : Main ()에 코드를 추가했습니다. 내 구성에는 어셈블리 버전 리디렉션이 포함되어 있지만 ( stackoverflow.com/questions/30165393/… 참조 ) 리디렉션은 구성을 수동으로 변경할 때 영향을주지 않습니다.
Vortex852456

1
"APP_CONFIG_FILE"을 사용하셨습니까?
Saturn Technologies

40

Ishmaeel의 대답은 일반적으로 작동하지만 한 가지 문제를 발견했습니다. 이는 OpenMappedMachineConfigurationmachine.config에서 상속 된 섹션 그룹을 잃는 것 같습니다. 즉, 사용자 정의 섹션 (원하는 모든 OP)에 액세스 할 수 있지만 일반 시스템 섹션에는 액세스 할 수 없습니다. 예를 들어 다음 코드는 작동하지 않습니다.

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

기본적으로에 watch를 넣으면 configuration.SectionGroupssystem.net이 SectionGroup으로 등록되지 않았으므로 일반 채널을 통해 거의 액세스 할 수 없음을 알 수 있습니다.

이 문제를 해결하는 방법에는 두 가지가 있습니다. 내가 좋아하지 않는 첫 번째는 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>

그 후 웹 응용 프로그램 자체가 올바르게 실행 될지 모르겠지만 sectionGroups에 올바르게 액세스 할 수 있습니다.

두 번째 해결책은 대신 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
Ohad Schneider

10

Ishmaeel의 답변 외에도 메서드 OpenMappedMachineConfiguration()는 항상 Configuration객체를 반환 합니다. 따라서로드되었는지 확인하려면 HasFiletrue가 파일에서 온 것을 의미 하는 속성을 확인해야 합니다.


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 2010 년

4

다음과 같이 .nET Compoent 호스팅 단어에 구성 값을 제공했습니다.

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.