2010-11-03 29 views
7

Tôi đang gặp vấn đề này ... trong mã của tôi cho dù tôi đặt giá trị của IsRequired thành false hay true thì nó vẫn sai. Tuy nhiên nếu tôi đặt trong DefaultValue nó hoạt động?C# - ConfigurationSection isRequired attribute

Mã không làm việc là:

public class FtpSettingsSection : ConfigurationSection 
{ 
    [ConfigurationProperty("host", IsRequired = true)] 
    public HostElement Host 
    { 
     get { return (HostElement)this["host"]; } 
     set { this["host"] = value; } 
    } 

} 

public class HostElement : ConfigurationElement 
{ 
    [ConfigurationProperty("URL", IsRequired = true)] 
    public string URL 
    { 
     get { return (string)this["URL"]; } 
     set { this["URL"] = value; } 
    } 
} 

và mã làm việc là:

public class FtpSettingsSection : ConfigurationSection 
{ 
    [ConfigurationProperty("host", DefaultValue = "", IsRequired = true)] 
    public HostElement Host 
    { 
     get { return (HostElement)this["host"]; } 
     set { this["host"] = value; } 
    } 

} 

public class HostElement : ConfigurationElement 
{ 
    [ConfigurationProperty("URL", DefaultValue = "", IsRequired = true)] 
    public string URL 
    { 
     get { return (string)this["URL"]; } 
     set { this["URL"] = value; } 
    } 
} 

Tại sao mà tôi cần phải thiết lập DefaultValue để ""?

Trả lời

0

Tôi giả sử bạn không có giá trị của URL propertie được tuần tự hóa trong cấu hình của bạn. Vì vậy, khi cấu hình đang được tải, ConfigurationManager kiểm tra các thuộc tính để xem giá trị thuộc tính có cần thiết và sau đó ném ngoại lệ nếu không tìm thấy giá trị nào. Nếu giá trị mặc định được đặt, thì giá trị đó được sử dụng nếu không tìm thấy giá trị nào trong cấu hình.

+1

Ví dụ đầu tiên của mã dosent ném bất kỳ ngoại lệ nào ngay cả khi thuộc tính máy chủ không được xác định trong tệp cấu hình? – ebb

+0

Ví dụ đầu tiên sẽ ném một ngoại lệ, thứ hai với thuộc tính mặc định sẽ không. – dexter

+0

Thực ra tôi đã thử nghiệm điều này và ví dụ ĐẦU TIÊN không ném một ngoại lệ. Trong ứng dụng bảng điều khiển thử nghiệm, IsRequired dường như bị bỏ qua. Nếu nó IsRequired bạn không nên đặt giá trị mặc định bởi vì sau đó nó thực sự là không cần thiết. Nếu bạn gắn cờ nó IsRequired = true thì nó sẽ ném một ngoại lệ nếu bạn không cung cấp một mặc định nhưng nó không. Tôi đã thử nghiệm trong .Net 4. –

6

Tôi đã gặp phải vấn đề tương tự và tìm thấy giải pháp ở đây http://msdn.microsoft.com/en-us/library/system.configuration.configurationpropertyattribute%28v=vs.90%29.aspx#1. Các bình luận về ConfigurationPropertyAttribute là không hoàn toàn chính xác, nhưng nó giải thích những điều cơ bản của vấn đề:

các IsRequired viên của ConfigurationPropertyAttribute không hoạt động khi áp dụng cho một đối tượng trẻ em (bắt nguồn từ ConfigurationElement). Khi hệ thống con phản ánh các thuộc tính của phần/phần tử cha để xác định thuộc tính cấu hình nào được định nghĩa, nó sẽ tạo một cá thể mới (của kiểu thích hợp) cho mỗi phần tử con và lưu nó trong danh sách giá trị của cha. Sau đó, khi nó xác nhận xem tất cả các thuộc tính bắt buộc đã được chỉ định hay chưa, nó không thể phân biệt được giữa phần tử con được khởi tạo mặc định và phần tử được chứa rõ ràng trong tệp cấu hình.

Cách giải quyết lý tưởng nhất sẽ là khai báo theo chương trình các thành phần bắt buộc thông qua lớp ConfigurationProperty. Điều này đòi hỏi công việc nhiều hơn đáng kể so với cách tiếp cận khai báo. Một cách khác ...

Theo như tôi có thể nói thay thế không chính xác.

Ví dụ về mô hình có lập trình có thể được tìm thấy trên trang ConfigurationProperty. Tôi đã quản lý để khắc phục vấn đề cho bản thân mình bằng cách khai báo các thuộc tính mà tôi cần trong constructor của phần tử custom của tôi và để mọi thứ khác giống nhau.

Tôi nghi ngờ bạn không thực sự làm việc khi bạn thêm DefaultValue, mà là ném ngoại lệ vì một lý do khác. Bạn sẽ phải đi sâu vào cuối chuỗi InnerException để tìm số ConfigurationErrorsException. Thông báo chính xác khi một thuộc tính bắt buộc bị thiếu là "Không tìm thấy thuộc tính bắt buộc 'máy chủ. (C: \ path \ to \ yourproject \ bin \ Debug \ yourproject.vshost.exe.Config line ##)"

Khi bạn cung cấp giá trị mặc định chuỗi rỗng, hệ thống con cấu hình sẽ cố gắng phân tích cú pháp chuỗi đó thành HostElement và không thành công. Kết quả ConfigurationErrorsException có thông báo "Không thể phân tích cú pháp giá trị mặc định của máy chủ lưu trữ thuộc tính. Lỗi này là: Tham chiếu đối tượng không được đặt thành phiên bản của đối tượng. (C: \ path \ to \ yourproject \ bin \ Debug \ yourproject.vshost.exe.Config line ##) "

3

Xin lỗi vì đã necroposting, nhưng vấn đề này đánh tôi quá nhưng theo một cách đặc biệt hơn và giải pháp của tôi cũng áp dụng cho câu hỏi.

Tôi đã triển khai tải lại cấu hình mà không cần khởi động lại quy trình. Khi quá trình bắt đầu, thuộc tính IsRequired bị "bỏ qua" và Cấu hìnhElement được tự động khởi chạy với giá trị mặc định. Nhưng khi cấu hình được tải lại, số lượng IsRequired được gán là được tôn trọng! Vì vậy, tôi hardcoded tải lại cấu hình trên bắt đầu quá trình và nó giải quyết được vấn đề thiếu ngoại lệ!

Mã giả:

config = (SampleConfiguration)ConfigurationManager.GetSection(ConfigSectionName); 
// <-- no exception thrown for missing required properties 

ConfigurationManager.RefreshSection(ConfigSectionName); 

config = (SampleConfiguration)ConfigurationManager.GetSection(ConfigSectionName); 
// <-- exception thrown! 
2

Đào lên một sợi chết. Nhưng tôi vô tình tìm thấy một công việc xung quanh cho việc này.

Trong hàm tạo phần tùy chỉnh của bạn, hãy tham chiếu đến ElementInformation của phần tử tùy chỉnh. Bằng cách đó, một thể hiện khác của phần tùy chỉnh của bạn sẽ được tạo ra trong ngữ cảnh của phần tử. Và vì một lý do nào đó mà tôi không hiểu đầy đủ, tài sản IsRequired được vinh danh.

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