2009-02-20 13 views
13

Ich habe das Netz für die letzten 3 Tage durchsucht und kann keine Referenz zu dieser Frage finden. Ich habe eine benutzerdefinierte Konfigurationsklasse erstellt, die mit meiner app.config verwendet werden kann. Alles funktioniert gut. Das Problem tritt auf, wenn eine Konfigurationseigenschaft (eines Konfigurationselements) nicht erforderlich ist und nicht in der app.config definiert ist. Es scheint, dass Standardwerte für die Konfigurationseigenschaft zurückgegeben werden. Kann jemand feststellen, ob die Eigenschaft in der app.config nicht definiert ist? (Ich habe versucht, meine app.config zu schreiben, kann aber nicht herausfinden, wie es zu tun ... Wer weiß, wie?)Benutzerdefinierte Konfiguration, ConfigurationElements und ConfigurationProperties


//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"]; } } 
    } 
} 

Antwort

4

Die 2 Dinge, die ich von aus der Spitze denken kann meine Kopf wäre eine Default zu verwenden, etwa so:

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

Unter der Annahme, dass ein Wert, der ungültig ist. In diesem Fall bedeutet CustomSettingItem == -1, dass es nicht festgelegt wurde, und> = 0 war ein Wert in config. Natürlich wird davon ausgegangen, dass -1 keine gültige Eingabe war.

zweite Idee ist stattdessen ein Nullable-int zu verwenden:

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

Nun, wenn nichts in Config gesetzt ist, sollte es so weit statt 0

+0

Das funktioniert, aber ich hatte gehofft, es gab eine Möglichkeit, den Standard zu unterdrücken, wenn die Eigenschaft nicht definiert ist. Die Arbeit, die ich gerade benutze, ist config.Setting2.IsPresent – user62064

0

auf null Default Ich habe nicht in der Lage gewesen, eine Eigenschaft als null angeben, wenn sie nicht in der Konfigurationsdatei definiert ist. Es scheint, dass Microsoft in seiner unendlichen Weisheit entschieden hat, dass Sie String.Empty oder new ConfigurationElement() wirklich meinen, wenn Sie null eingeben.

So wie ich zur Zeit es zu lösen habe, ist, wie folgt aus:

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; } 
    } 

Es ist ein Hack ist und markieren falsch die Eigenschaft als erforderlich. Wenn Sie ein Tool verwenden, um Ihre Konfigurationsdatei zu bearbeiten, wird dies nicht so sein.

11

Ich fand den besten Weg ist, ConfigurationSection.PostDeserialize() zu überschreiben und überprüfen Sie die IsPresent Eigenschaft jedes Abschnitts Mitglied, das von ConfigurationElement abgeleitet ist.

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(); 
    } 
} 

Jeder ConfigurationElement, die aus der Konfigurationsdatei nicht wird danach null sein gelesen hat.

+0

Als eine Randnotiz müssen Sie dies beim 'PostDeserialize' Event nicht machen. Die 'ElementInformation' ist immer verfügbar:' Console.WriteLine ("Setting1 {0}", config.Setting1.CustomSettingItem.ElementInformation.IsPresent? "Y": "N"); ' –

2

Versuchen Sie Folgendes:

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

Die ValueOrigin Eigenschaft, die Sie sagt, wo sich der Wert kommen.

+0

' IsPresent' gab das erwartete Ergebnis nicht zurück Wert aus irgendeinem Grund (es wurde für alles falsch zurückgegeben).'ValueOrigin' hat für mich funktioniert. – atheaos

0

Sie können auch überprüfen Sie Folgendes mit:

config.Setting1.CustomSettingItem.ElementInformation.IsPresent 

es wird Ihnen falsch, wenn es nicht in Ihrer Konfigurationsdatei gefunden wurde.

Verwandte Themen