10

Tôi có một ứng dụng giao diện điều khiển đang cố gắng tải một CustomConfigurationSection từ một tệp web.config.Tải một ConfigurationSection với một đứa trẻ được yêu cầu ConfigurationElement với .Net configuration framework

Phần cấu hình tùy chỉnh có phần tử cấu hình tùy chỉnh được yêu cầu. Điều này có nghĩa là khi tôi tải phần cấu hình, tôi hy vọng sẽ thấy một ngoại lệ nếu phần tử cấu hình đó không có trong cấu hình. Vấn đề là .NET framework dường như hoàn toàn bỏ qua thuộc tính isRequired. Vì vậy, khi tôi tải phần cấu hình, tôi chỉ tạo một thể hiện của phần tử cấu hình tùy chỉnh và đặt nó trên phần cấu hình.

Câu hỏi của tôi là, tại sao điều này lại xảy ra? Tôi muốn phương thức GetSection() để kích hoạt một ngoại lệ ConfigurationErrors vì thiếu một phần tử cần thiết từ cấu hình.

Đây là cách cấu hình phần của tôi.

public class MyConfigSection : ConfigurationSection 
{ 
    [ConfigurationProperty("MyConfigElement", IsRequired = true)] 
    public MyConfigElement MyElement 
    { 
     get { return (MyConfigElement) this["MyConfigElement"]; } 
    } 
} 
public class MyConfigElement : ConfigurationElement 
{ 
    [ConfigurationProperty("MyAttribute", IsRequired = true)] 
    public string MyAttribute 
    { 
     get { return this["MyAttribute"].ToString(); } 
    } 
} 

Đây là cách tôi tải phần cấu hình.

class Program 
    { 
     public static Configuration OpenConfigFile(string configPath) 
     { 
      var configFile = new FileInfo(configPath); 
      var vdm = new VirtualDirectoryMapping(configFile.DirectoryName, true, configFile.Name); 
      var wcfm = new WebConfigurationFileMap(); 
      wcfm.VirtualDirectories.Add("/", vdm); 
      return WebConfigurationManager.OpenMappedWebConfiguration(wcfm, "/"); 
     } 

     static void Main(string[] args) 
     { 
      try{ 
       string path = @"C:\Users\vrybak\Desktop\Web.config"; 

       var configManager = OpenConfigFile(path); 
       var configSection = configManager.GetSection("MyConfigSection") as MyConfigSection; 

       MyConfigElement elem = configSection.MyElement; 
      } catch (ConfigurationErrorsException ex){ 
       Console.WriteLine(ex.ToString()); 
      } 
     } 

Đây là tệp cấu hình của tôi.

<?xml version="1.0"?> 
<configuration> 
    <configSections> 
    <section name="MyConfigSection" type="configurationFrameworkTestHarness.MyConfigSection, configurationFrameworkTestHarness" /> 
    </configSections> 

    <MyConfigSection> 

    </MyConfigSection> 

Phần khó khăn hơn là nếu tôi mở tệp cấu hình và tải phần 2 lần liên tiếp, tôi sẽ nhận ngoại lệ mà tôi mong đợi.

var configManager = OpenConfigFile(path); 
var configSection = configManager.GetSection("MyConfigSection") as MyConfigSection; 
configManager = OpenConfigFile(path); 
configSection = configManager.GetSection("MyConfigSection") as MyConfigSection; 

Nếu tôi sử dụng mã ở trên, ngoại lệ sẽ kích hoạt và cho tôi biết rằng MyConfigElement là bắt buộc. Câu hỏi đặt ra là tại sao nó không ném ngoại lệ này lần đầu tiên ??

Trả lời

3

Tôi thấy rằng giải pháp tốt nhất cho việc này là để lặp lại theo cách thủ công thông qua tất cả thuộc tính lồng nhau của loại ConfigurationElement và tự kiểm tra chúng sau khi nhận được phần. Nếu một phần tử là bắt buộc nhưng không có trong tệp tôi chỉ cần ném một ConfigurationErrorsException.

Đây là mã của tôi.

private void ProcessMissingElements(ConfigurationElement element) 
{ 
    foreach (PropertyInformation propertyInformation in element.ElementInformation.Properties) 
    { 
     var complexProperty = propertyInformation.Value as ConfigurationElement; 
     if (complexProperty == null) 
      continue; 

     if (propertyInformation.IsRequired && !complexProperty.ElementInformation.IsPresent) 
      throw new ConfigurationErrorsException("ConfigProperty: [{0}] is required but not present".FormatStr(propertyInformation.Name)); 
     if (!complexProperty.ElementInformation.IsPresent) 
      propertyInformation.Value = null; 
     else 
      ProcessMissingElements(complexProperty); 
    } 
} 
3

Eric has answered this trong MS đàn

Để trích dẫn câu trả lời của mình:

Các IsRequired viên của ConfigurationPropertyAttribute không không hoạt động khi áp dụng cho một đối tượng con (bắt nguồn từ ConfigurationElement)

+0

Tôi không nghĩ rằng Eric đã trả lời chính xác điều này. Bạn có thể thấy phản ứng của tôi với anh ta ở đây. http://social.msdn.microsoft.com/Forums/en-US/netfxbcl/thread/710c69e7-0c70-4905-8a5d-448c1e12a2e5?prof=required –

+0

Thật kì lạ khi nó hoạt động lần thứ hai. Sẽ rất thú vị khi gỡ lỗi vào mã .NET framework để xem điều gì đang xảy ra dưới mui xe. -dave –

0

Bạn đã thử gán nó trực tiếp cho đúng loại biến, tức là MyConfigSection i nstead của var? Đó là sự khác biệt duy nhất tôi có thể thấy giữa hai dòng mã. (tức là trong dòng thứ hai, var hiện đã lấy một loại cụ thể).

+1

Sử dụng loại cụ thể thay vì var không tạo sự khác biệt –

Các vấn đề liên quan