การใช้ ConfigurationManager เพื่อโหลดการกำหนดค่าจากตำแหน่งที่กำหนดเอง


124

ฉันกำลังพัฒนาองค์ประกอบการเข้าถึงข้อมูลที่จะใช้ในเว็บไซต์ที่มีการผสมผสานระหว่างหน้า ASP และ ASP.NET แบบคลาสสิกและต้องการวิธีที่ดีในการจัดการการตั้งค่าคอนฟิก

ฉันต้องการใช้แบบกำหนดเองConfigurationSectionและสำหรับหน้า ASP.NET สิ่งนี้ใช้งานได้ดี แต่เมื่อคอมโพเนนต์ถูกเรียกผ่าน COM interop จากเพจ ASP แบบคลาสสิกคอมโพเนนต์จะไม่ทำงานในบริบทของคำขอ 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 WebFormsแอพลิเคชันเจ้าภาพในsub.domain.com/virtualDir2และเส้นทางC: \ พอร์ทัล \ App1 \ v2และการตั้งค่าไฟล์ในC: \ พอร์ทัล \ App1 \ 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 ได้ด้วย ฉันใช้มันเพื่อโหลด web.config แทน app.config สำหรับแอปคอนโซลที่เกี่ยวข้องกับงาน ;)
James Wilkins

1
สิ่งนี้ (และคำตอบอื่น ๆ ที่นี่) ไม่ได้ผลสำหรับฉัน ฉันได้เพิ่มรหัสใน program.cs - function: Main () การกำหนดค่าของฉันมีการเปลี่ยนเส้นทางเวอร์ชันแอสเซมบลี (ดูstackoverflow.com/questions/30165393/… ) แต่การเปลี่ยนเส้นทางจะไม่มีผลเมื่อมีการเปลี่ยนการกำหนดค่าด้วยตนเอง
Vortex852456

1
คุณใช้ "APP_CONFIG_FILE" หรือไม่
Saturn Technologies

40

คำตอบของอิชมาเอลโดยทั่วไปใช้งานได้ แต่ฉันพบปัญหาหนึ่งนั่นคือการใช้OpenMappedMachineConfigurationดูเหมือนว่าจะสูญเสียกลุ่มส่วนที่สืบทอดมาจาก machine.config ซึ่งหมายความว่าคุณสามารถเข้าถึงส่วนที่กำหนดเองได้ (ซึ่งเป็น 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 ดังนั้นจึงไม่สามารถเข้าถึงได้ผ่านช่องทางปกติ

มีสองวิธีที่ฉันพบในการแก้ไขปัญหานี้ สิ่งแรกที่ฉันไม่ชอบคือการนำกลุ่มส่วนระบบมาใช้ใหม่โดยคัดลอกจาก 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!

ฉันไม่กล้าตอบคำตอบที่นี่ทั้งของฉันหรือของอิชมาเอลต่างก็ใช้ฟังก์ชันเหล่านี้ตามที่นักออกแบบ. NET ตั้งใจไว้ แต่ดูเหมือนว่าจะได้ผลสำหรับฉัน


1
คุณยังสามารถใช้ ConfigurationManager.OpenExeConfiguration (String) overload เพื่อวัตถุประสงค์เดียวกัน ดู: codeproject.com/KB/dotnet/mysteriesofconfiguration3.aspx#t2_1
Ohad Schneider

10

นอกจากคำตอบของอิชมาเอลแล้วเมธอด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

ฉันให้ค่าคอนฟิกูเรชันให้กับ word ที่โฮสต์. NET Compoent ดังนี้

ส่วนประกอบ. NET Class Library ถูกเรียก / โฮสต์ใน MS Word ในการระบุค่าการกำหนดค่าให้กับส่วนประกอบของฉันฉันสร้าง winword.exe.config ในโฟลเดอร์ C: \ Program Files \ Microsoft Office \ OFFICE11 คุณควรจะอ่านค่าการกำหนดค่าได้เช่นเดียวกับที่คุณทำใน. 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.