2009-02-20 10 views
13

Przeszukuję sieć przez ostatnie 3 dni i nie mogę znaleźć żadnego odniesienia do tego pytania. Stworzyłem niestandardową klasę konfiguracji, która będzie używana z moim app.config. Wszystko dziala. Problem pojawia się, gdy właściwość konfiguracji (elementu konfiguracji) nie jest wymagana i nie jest zdefiniowana w pliku app.config. Wygląda na to, że wartości domyślne są zwracane dla właściwości konfiguracji. Czy ktoś wie, jak określić, czy właściwość nie jest zdefiniowany w app.config? (Próbowałem odpowiedzieć moje app.config, ale nie mogę dowiedzieć się, jak to zrobić ... ktoś wie jak?)Niestandardowa konfiguracja, opcje konfiguracji i właściwości konfiguracji


//Main 
namespace TestStub 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      CustomSettingsHandler config = (CustomSettingsHandler)ConfigurationManager.GetSection("CustomSettingsManager"); 
      Console.WriteLine("Setting1 {0}", config.Setting1.CustomSettingItem); 
      Console.WriteLine("Setting2 {0}", config.Setting2.CustomSettingItem); 
     } 
    } 
} 

//Custom Configuration Class 
namespace CustomConfiguration 
{ 
    public class CustomSettingsHandler : ConfigurationSection 
    { 
     [ConfigurationProperty("setting1", IsRequired = false)] 
     public CustomSettingElement Setting1 { get { return (CustomSettingElement)this["setting1"]; } } 

     [ConfigurationProperty("setting2", IsRequired = false)] 
     public CustomSettingElement Setting2 { get { return (CustomSettingElement)this["setting2"]; } } 
    } 

    public class CustomSettingElement : ConfigurationElement 
    { 
     [ConfigurationProperty("customsettingitem", IsRequired = false)] 
     public int CustomSettingItem { get { return (int)this["customsettingitem"]; } } 
    } 
} 

Odpowiedz

4

na 2 rzeczy mogę myśleć poza czubek Głowa będzie używać wartości DefaultValue, tak jak:

[ConfigurationProperty("customsettingitem", DefaultValue = -1)] 
    public int CustomSettingItem { get { return (int)this["customsettingitem"]; } } 

Zakładając, że istnieje pewna wartość, która jest nieważna. W tym przypadku CustomSettingItem == -1 oznacza, że ​​nie było ustawione, a> = 0 było wartością ustawioną w config. Oczywiście zakłada się, że -1 nie było ważnego wejścia w pierwszej kolejności.

Drugi pomysł jest użycie int zerowalne Zamiast:

[ConfigurationProperty("customsettingitem", IsRequired = false)] 
    public int? CustomSettingItem { get { return (int?)this["customsettingitem"]; } } 

Teraz, jeśli nic nie zostanie ustawiony w konfiguracji, należy domyślne null zamiast 0.

+0

To działa, ale miałem nadzieję, że był sposób, aby wyłączyć domyślne, gdy właściwość nie jest zdefiniowana. Praca, której teraz używam, to config.Setting2.IsPresent – user62064

0

Do tej pory nie udało aby powiedzieć, że właściwość ma wartość null, jeśli nie jest zdefiniowana w pliku konfiguracyjnym. Wydaje się, że w swojej nieskończonej mądrości Microsoft zdecydował, że naprawdę masz na myśli String.Empty lub new ConfigurationElement() po wpisaniu wartości null.

Sposób Jestem obecnie rozwiązanie to jest tak:

bool _hasProp = true; 
    protected override object OnRequiredPropertyNotFound(string name) 
    { 
     if (name == "prop") 
     { 
      _hasProp = false; 
      return null; // note that this will still not make prop null 
     } 
     return base.OnRequiredPropertyNotFound(name); 
    } 

    [ConfigurationProperty("prop", IsRequired = true)] 
    public string Prop 
    { 
     get { return _hasProp ? (string) this["prop"] : null; } 
    } 

Jest to hack i błędnie oznaczyć właściwość w miarę potrzeb. Jeśli używasz narzędzia do edycji pliku konfiguracyjnego, to się nie spodoba.

11

znalazłem najlepszym sposobem jest, aby zastąpić ConfigurationSection.PostDeserialize() i sprawdzić właściwość każdego z członków sekcji, który wywodzi się z ConfigurationElementIsPresent.

public class CustomSettingsHandler : ConfigurationSection 
{ 
    // ... 

    protected override void PostDeserialize() 
    { 
     foreach (ConfigurationProperty property in Properties) 
     { 
      var configElement = this[property] as ConfigurationElement; 

      if (configElement != null 
       && !configElement.ElementInformation.IsPresent) 
      { 
       this[property] = null; 
      } 
     } 

     base.PostDeserialize(); 
    } 
} 

Każdy ConfigurationElement które nie zostały odczytane z pliku konfiguracyjnego będą null później.

+0

Na marginesie, nie musisz tego robić w przypadku zdarzenia 'PostDeserialize'. "ElementInformation" jest zawsze dostępny: 'Console.WriteLine (" Setting1 {0} ", config.Setting1.CustomSettingItem.ElementInformation.IsPresent?" Y ":" N ");' –

2

Spróbuj wykonać następujące czynności:

configElement.ElementInformation.Properties[propName].ValueOrigin = 
     PropertyValueOrigin.SetHere 

Obiekt ValueOrigin powie Ci, gdzie ma wartość pochodzą.

+0

'IsPresent' nie zwrócił oczekiwanego wartość z jakiegoś powodu (wszystko zwróciło fałsz).'ValueOrigin' pracował dla mnie. – atheaos

0

Można również sprawdzić przy użyciu następujących:

config.Setting1.CustomSettingItem.ElementInformation.IsPresent 

da Ci fałszywy jeśli nie został znaleziony w pliku konfiguracyjnym.