Sử dụng Trình quản lý cấu hình để tải cấu hình từ một vị trí tùy ý


124

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

Tôi muốn sử dụng một tùy chỉnh ConfigurationSectionvà đối với các trang ASP.NET, điều này hoạt động rất 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 yêu cầu ASP.NET và do đó không có kiến ​​thức về web.config.

Có cách nào để bảo ConfigurationManagerchỉ tải cấu hình từ một đường dẫn tùy ý (ví dụ: ..\web.confignếu lắp ráp của tôi nằm trong /binthư mục)? Nếu có thì tôi nghĩ thành phần của tôi có thể quay lại đó nếu mặc định ConfigurationManager.GetSectiontrả về nullcho phần tùy chỉnh của tôi.

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


Câu trả lời:


124

Thử cái này:

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

Làm cách nào tôi có thể nhận giá trị strConfigPath theo chương trình cho ứng dụng ASP.NET WebForms của tôi được lưu trữ trong sub.domain.com/virtualDir2 và đường dẫn C: \ Portals \ App1 \ v2tệp cấu hình trong C: \ Portals \ App1 \ v2 \ web.config ?
Kiquenet

1
@Kiquenet: Điểm của câu hỏi là strConfigPath là một vị trí tùy ý . Nói cách khác, bạn quyết định đường dẫn là gì, thay vì dựa vào khung để thử tải tệp cấu hình từ vị trí thông thường của nó. Tôi cho rằng Server.MapPath sẽ cung cấp cho bạn vị trí tuyệt đối cho bất kỳ tệp nào trong giải pháp của bạn.
Ishmaeel

1
Có lẽvar config = System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration("~/web.config");
Kiquenet

@Kiquenet Chắc chắn.
Ucho

66

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 thấy đó là giải pháp tốt nhất cho tải tập tin cấu hình đường dẫn không tầm thường, cụ thể là cách tốt nhất để đính kèm tập tin cấu hình vào dll.

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

Thí 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 blog này .

Ngoài ra, câu trả lời khác này có một 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à một IDisposableđối tượng để đặt lại về trạng thái ban đầu. Với giải pháp này, bạn có thể giữ cấu hình ứng dụng tạm thời trong phạm vi:

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 tin web.config. Tôi sử dụng nó để tải một web.config thay vì app.config cho một ứng dụng bảng điều khiển liên quan đến nhiệm vụ. ;)
James Wilkins

1
Điều này (và các câu trả lời khác ở đây) không phù hợp với tôi. Tôi đã thêm mã trong chương trình.cs - function: Main (). Cấu hình của tôi chứa chuyển hướng phiên bản lắp ráp (xem stackoverflow.com/questions/30165393/, ) nhưng chuyển hướng không ảnh hưởng khi thay đổi cấu hình theo cách thủ công.
Vortex852456

1
Bạn đã sử dụng "APP_CONFIG_FILE"?
Saturn Technologies

40

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 đề, đó là việc sử dụng OpenMappedMachineConfigurationdường như làm mất các nhóm phần được 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 (đó là tất cả những gì OP muốn), nhưng không phải là các phần hệ thống thông thường. Ví dụ: mã này sẽ không hoạt động:

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 đồng hồ trên configuration.SectionGroups, bạn sẽ thấy system.net không được đăng ký dưới dạng Mục nhóm, do đó, nó không thể truy cập được thông qua các kênh thông thường.

Có hai cách tôi tìm thấy để làm việc này. Điều đầu tiên, mà tôi không thích, là triển khai lại 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, vd

<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 bản thân ứng dụng web sẽ chạy chính xác sau đó, nhưng bạn có thể truy cập chính xác vào nhóm.

Thay vào đó, giải pháp thứ hai là mở web.config dưới dạng cấu hình EXE, có lẽ gần với chức năng dự định của nó hơn:

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 khẳng định không có câu trả lời nào được cung cấp ở đây, cả của tôi và của Ishmaeel, đều sử dụng các chức năng này theo cách mà 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 Cấu hình Trình quản lý cấu hình.OpenExeConfiguration (Chuỗi) cho cùng một mục đích. Xem: codeproject.com/KB/dotnet/mysteriesofconfiguration3.aspx#t2_1
Ohad Schneider

10

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


9

Câu trả lời được chấp nhận là sai !!

Nó ném ngoại lệ sau đây khi truy cập thuộc tính AppSinstall:

Không thể truyền đối tượng thuộc loại 'System.Configuration.DefaultSection' để nhập 'System.Configuration.AppSinstallSection'.

Đây là giải pháp chính xác:

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

1
vâng, đây chắc chắn là câu trả lời đúng! Cảm ơn đã gửi câu trả lời của bạn.
Fabio Milheiro

Tôi nghĩ System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration thậm chí còn đúng hơn nhưng nó không có sẵn cho .NET Core vì vậy trong trường hợp đó câu trả lời này dường như đã hoàn thành công việc.
Risord

4

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

Một thành phần Thư viện lớp .NET được gọi / lưu trữ trong MS Word. Để cung cấp 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"];

1

Đối với ASP.NET, hãy sử dụng WebConfigurationManager:

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

0

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(...)

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.