2008-08-07 26 views
110

Tôi đang phát triển thành phần truy cập dữ liệu sẽ được sử dụng trong trang web có chứa trang ASP và ASP.NET cổ điển và cần một cách tốt để quản lý cài đặt cấu hình của nó .Sử dụng ConfigurationManager để tải cấu hình từ vị trí tùy ý

Tôi muốn sử dụng tùy chỉnh ConfigurationSection và cho các trang ASP.NET hoạt động tốt. Nhưng khi thành phần được gọi thông qua COM interop từ một trang ASP cổ điển, thành phần không chạy trong ngữ cảnh của một yêu cầu ASP.NET và do đó không có kiến ​​thức về web.config.

Có cách nào để thông báo cho ConfigurationManager để chỉ tải cấu hình từ đường dẫn tùy ý (ví dụ: ..\web.config nếu hội đồng của tôi nằm trong thư mục /bin) không? Nếu có thì tôi nghĩ rằng thành phần của tôi có thể rơi trở lại đó nếu mặc định ConfigurationManager.GetSection trả về null cho phần tùy chỉnh của tôi.

Bất kỳ cách tiếp cận nào khác với điều này đều sẽ được hoan nghênh!

+2

Xem http: // stackoverflow.com/questions/3912727/openmappedexeconfiguration-vs-openexeconfiguration/6599688#6599688 –

Trả lời

104

Hãy thử điều này:

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

Làm cách nào để có được giá trị _programmatically_ ** strConfigPath ** cho ứng dụng ASP.NET _WebForms_ của tôi được lưu trữ trong *** http: //sub.domain.com/virtualDir2/*** và đường dẫn *** C: \ Portals \ App1 \ v2 *** và _config file_ trong *** C: \ Portals \ App1 \ v2 \ web.config ***? – Kiquenet

+0

@Kiquenet: Điểm của câu hỏi là strConfigPath là một vị trí _arbitrary_. Nói cách khác, _you_ quyết định đường dẫn là gì, thay vì dựa vào khung công tác để thử tải một tệp cấu hình từ vị trí thông thường của nó. Tôi sẽ giả định [Server.MapPath] (https://msdn.microsoft.com/en-us/library/system.web.httpserverutility.mappath (v = vs.110) .aspx) sẽ cung cấp cho bạn vị trí tuyệt đối cho bất kỳ các tệp trong giải pháp của bạn. – Ishmaeel

+0

Có thể 'var config = System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration (" ~/web.config ");' – Kiquenet

9

Ngoài câu trả lời Ishmaeel của, phương pháp OpenMappedMachineConfiguration() sẽ luôn luôn trả về một đối tượng Configuration. Vì vậy, để kiểm tra xem nó có được tải hay không, bạn nên kiểm tra thuộc tính HasFile trong đó có nghĩa là nó đến từ một tệp.

37

Câu trả lời của Ishmaeel thường hoạt động, tuy nhiên tôi đã tìm thấy một vấn đề, tức là sử dụng OpenMappedMachineConfiguration dường như mất nhóm phần kế thừa của bạn từ machine.config. Điều này có nghĩa là bạn có thể truy cập các phần tùy chỉnh của riêng bạn (tất cả đều là OP mong muốn), nhưng không phải là các phần hệ thống bình thường. Ví dụ, đoạn mã này sẽ không làm việc:

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

Về cơ bản, nếu bạn đặt một chiếc đồng hồ trên configuration.SectionGroups, bạn sẽ thấy system.net mà không được đăng ký như một SectionGroup, vì vậy nó là khá nhiều không thể tiếp cận thông qua bình thường kênh truyền hình.

Có hai cách tôi tìm thấy để giải quyết vấn đề này. Đầu tiên, mà tôi không thích, là tái triển khai các nhóm phần hệ thống bằng cách sao chép chúng từ machine.config vào web.config của riêng bạn, ví dụ:

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

Tôi không chắc chắn chính ứng dụng web sẽ chạy chính xác sau đó, nhưng bạn có thể truy cập phần chính xác.

Giải pháp thứ hai đó là thay vì để mở web.config bạn như là một cấu hình EXE, mà có lẽ gần gũi hơn với chức năng dự định của nó anyway:

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! 

Tôi dám nói là không ai trong số các câu trả lời cung cấp ở đây, chẳng thuộc về tao hay Ishmaeel's, khá sử dụng các chức năng này như thế nào các nhà thiết kế .NET dự định. Nhưng, điều này dường như làm việc cho tôi.

+1

Bạn cũng có thể sử dụng quá tải ConfigurationManager.OpenExeConfiguration (String) cho cùng một mục đích. Xem: http://www.codeproject.com/KB/dotnet/mysteriesofconfiguration3.aspx#t2_1 –

4

Tôi đã cung cấp các giá trị cấu hình cho từ được lưu trữ .nET Compoent như sau.

Thành phần Thư viện lớp .NET được gọi/lưu trữ trong MS Word. Để cung cấp các giá trị cấu hình cho thành phần của tôi, tôi đã tạo winword.exe.config trong thư mục C: \ Program Files \ Microsoft Office \ OFFICE11. Bạn sẽ có thể đọc các giá trị cấu hình như Bạn làm trong .NET truyền thống.

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

Một giải pháp khác là ghi đè đường dẫn tệp cấu hình môi trường mặc định.

Tôi tìm thấy giải pháp tốt nhất cho tải tệp cấu hình đường dẫn không tầm thường, đặc biệt là cách tốt nhất để đính kèm tệp cấu hình vào dll.

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

Ví dụ:

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

Thông tin chi tiết có thể được tìm thấy tại this blog.

Ngoài ra, this other answer có giải pháp tuyệt vời, hoàn chỉnh với mã để làm mới cấu hình ứng dụng và đối tượng IDisposable để đặt lại trạng thái ban đầu. Với giải pháp này, bạn có thể giữ cho ứng dụng cấu hình tạm thời scoped:

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

Điều này cũng hoạt động để tải các tệp web.config. Tôi sử dụng nó để tải một web.config thay vì app.config cho một nhiệm vụ liên quan đến giao diện điều khiển ứng dụng. ;) –

+1

Điều này (và các câu trả lời khác ở đây) không hoạt động đối với tôi. Tôi đã thêm mã trong program.cs - function: Main(). Cấu hình của tôi chứa một chuyển hướng phiên bản lắp ráp (xem http://stackoverflow.com/questions/30165393/avoid-assembly-reference-problems-generally) nhưng chuyển hướng không ảnh hưởng đến khi cấu hình được thay đổi theo cách thủ công. – Undercover1989

+1

Bạn có sử dụng "APP_CONFIG_FILE" không? –

1

Đối với ASP.NET sử dụng WebConfigurationManager:

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

Sử dụng xử lý XML:

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

// can call root.Elements(...) 
Các vấn đề liên quan