2010-08-27 28 views
10

Tôi đã tạo phần cấu hình tùy chỉnh trong thư viện lớp c bằng cách kế thừa từ ConfigurationSection. Tôi tham khảo các thư viện lớp trong ứng dụng web của tôi (cũng C#, ASP.NET), điền vào các thuộc tính thích hợp và tất cả mọi thứ hoạt động tuyệt vời. Sự cố bắt đầu khi tôi bắt đầu thêm trình xác thực.Tại sao StringValidator luôn thất bại trong phần cấu hình tùy chỉnh?

Ví dụ, khách sạn này:

[ConfigurationProperty("appCode", IsRequired = true)] 
    public string ApplicationCode 
    { 
     get 
     { 
      return (string)base["appCode"]; 
     } 
     set 
     { 
      base["appCode"] = value; 
     } 
    } 

Như là nó hoạt động tốt, nhưng ngay sau khi tôi thêm này:

[StringValidator(MinLength=1)] 

Nó bom với các lỗi sau:

Giá trị cho thuộc tính 'appCode' không hợp lệ. Lỗi là: Chuỗi phải dài ít nhất 1 ký tự.

Tôi gặp lỗi này mặc dù giá trị appCode hợp lệ nằm trong tệp web.config của tôi. Nếu tôi xóa trình xác thực, nó hoạt động hoàn hảo. Có ai biết làm thế nào để làm được việc này?

+0

Tôi đã đọc rằng toàn bộ series, tiếc là nó không giải thích lý do tại sao tôi nhận được lỗi. –

+1

Bạn đã thử khởi tạo thuộc tính ApplicationCode với giá trị mặc định (hợp lệ) chưa? Có vẻ như quy tắc xác nhận không thành công tại một số điểm trước khi giá trị được đọc từ tệp cấu hình. – Shackles

+0

Có, và nó hoạt động tốt với các giá trị mặc định. Tuy nhiên, không phải tất cả các trường đều có mặc định hợp lệ/hợp lý, đặc biệt là các trường tùy chọn, vì vậy nó khó chịu vì nó không thể khởi tạo từ cấu hình. –

Trả lời

3

tôi đã có thể làm việc xung quanh vấn đề này bằng cách sử dụng một rõ ràng ConfigurationProperty là chìa khóa để thu thập tài sản của tôi chứ không phải là một chuỗi, theo việc thực hiện sau đây:

public class AssemblyElement : ConfigurationElement 
{ 
    private static readonly ConfigurationProperty _propAssembly; 
    private static readonly ConfigurationPropertyCollection _properties; 

    static AssemblyElement() 
    { 
     _propAssembly = new ConfigurationProperty("assembly", typeof(string), null, null, new StringValidator(1), ConfigurationPropertyOptions.IsKey | ConfigurationPropertyOptions.IsRequired); 
     _properties = new ConfigurationPropertyCollection(); 
     _properties.Add(_propAssembly); 
    } 

    internal AssemblyElement() { } 
    public AssemblyElement(string assemblyName) 
    { 
     this.Assembly = assemblyName; 
    } 

    [ConfigurationProperty("assembly", IsRequired = true, IsKey = true, DefaultValue = "")] 
    [StringValidator(MinLength = 1)] 
    public string Assembly 
    { 
     get { return (string)base[_propAssembly]; } 
     set { base[_propAssembly] = value; } 
    } 

    internal AssemblyName AssemblyName 
    { 
     get { return new AssemblyName(this.Assembly); } 
    } 

    protected override ConfigurationPropertyCollection Properties 
    { 
     get { return _properties; } 
    } 
} 

(Mã này được mô hình hóa chặt chẽ sau khi mã được phản ánh từ lớp phần tử cấu hình AssemblyInfo. Tôi vẫn muốn tôi không phải sao chép xác thực của mình, nhưng ít nhất mã này cho phép tôi chỉ định giá trị mặc định trống trong khi vẫn yêu cầu giá trị được nhập.)

+0

Bạn nói đúng, tôi ước tôi cũng không phải làm điều đó. Tôi đã thử nó mặc dù và nó hoạt động, vì vậy cảm ơn. –

+0

Tôi đã dành cả ngày để chống lại vấn đề đó. Tuyệt vời - điều đó đã giúp tôi. –

3

Có vẻ như câu trả lời thực sự là vì chúng không có giá trị mặc định. Có vẻ kỳ lạ, vì vậy nếu ai đó có một câu trả lời tốt hơn cho tôi biết và tôi sẽ chấp nhận của họ.

2

I đã có vấn đề này trong một thời gian, sau đó tôi nhận ra rằng các nhà xác nhận không phải để tạo thuộc tính hoặc các phần tử được yêu cầu, chúng là để xác thực chúng.

Để yêu cầu bất động sản, bạn cần phải sử dụng IsRequired và ConfigrationPropertyOptions.IsRequired, ví dụ:

[ConfigurationProperty("casLogoutUrl", DefaultValue = null, IsRequired = true, Options = ConfigurationPropertyOptions.IsRequired)] 
[StringValidator(MinLength=10)] 

Hoặc (nếu sử dụng api)

ConfigurationProperty casLoginUrl = new ConfigurationProperty("casLoginUrl", typeof(string), null, null, new StringValidator(1), ConfigurationPropertyOptions.IsRequired); 

Việc làm này, khuôn khổ cấu hình sẽ xử lý tài sản được yêu cầu riêng của mình, và validator handle xác nhận những gì trong các giá trị. Người xác thực không có nghĩa là làm một cái gì đó cần thiết.

Điều này cũng hoạt động trên các yếu tố để làm cho các yếu tố con được yêu cầu. Ví dụ. nếu bạn đang thực hiện một ConfigSection tùy chỉnh với các phần tử con và cần một phần tử con được yêu cầu. Tuy nhiên, nếu bạn tạo CustomValidator kế thừa từ ConfigurationValidatorBase, bạn cần sử dụng ElementInformation.IsPresent, ví dụ:

  public override void Validate(object value) 
     { 
      CredentialConfigurationElement element = (CredentialConfigurationElement)value; 
      if (!element.ElementInformation.IsPresent) 
       return; //IsRequired is handle by the framework, don't throw error here only throw an error if the element is present and it fails validation. 
      if (string.IsNullOrEmpty(element.UserName) || string.IsNullOrEmpty(element.Password)) 
       throw new ConfigurationErrorsException("The restCredentials element is missing one or more required Attribute: userName or password."); 
     } 

Ngắn câu chuyện, bạn thiếu phần tùy chọn thuộc tính để yêu cầu và không nên sử dụng StringValidator (MinLength = 1) để thực hiện yêu cầu. Trong thực tế StringValidator (MinLength = 1) là hoàn toàn dư thừa.Nếu bạn làm cho nó yêu cầu nó không thể cho MinLength = 1 thất bại mà không có yêu cầu thất bại đầu tiên bởi vì nếu nó có mặt, nó được đảm bảo dài ít nhất 1 ký tự.

Thay đổi validator của bạn để

[ConfigurationProperty("appCode", IsRequired = true, Options=ConfigurationPropertyOptions.IsRequired)] 

Sau đó, mương chuỗi validator.

1

Các giải quyết của StringValidator thể được thực hiện bởi bất kỳ một trong các cách sau:

  • Loại bỏ MINLENGTH luận
  • Thiết MINLENGTH = 0
  • Loại bỏ các thuộc tính StringValidator
  • Thêm Mặc địnhValue đến thuộc tính ConfigurationProperty

Định nghĩa lý tưởng cho vị trí này cách như:

[ConfigurationProperty("title", IsRequired = true, DefaultValue = "something")] 
[StringValidator(InvalidCharacters = "[email protected]#$%^&*()[]{}/;’\"|\\" 
    , MinLength = 1 
    , MaxLength = 256)] 
public string Title 
{ 
    get { return this["title"] as string; } 
    set { this["title"] = value; } 
} 
Các vấn đề liên quan