2009-02-20 9 views
13

He estado rastreando la red durante los últimos 3 días y no puedo encontrar ninguna referencia a esta pregunta. Creé una clase de configuración personalizada para usar con mi app.config. Todo funciona bien El problema aparece cuando una propiedad de configuración (de un elemento de configuración) no es necesaria y no está definida en el archivo app.config. Parece que se devuelven valores predeterminados para la propiedad de configuración. ¿Alguien sabe cómo determinar si la propiedad no está definida en la aplicación.config? (He estado tratando de publicar mi app.config, pero no puedo encontrar la manera de hacerlo ... Alguien sabe cómo?)Configuración personalizada, ConfigurationElements y 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"]; } } 
    } 
} 

Respuesta

4

Las 2 cosas que puedo pensar en la parte superior de mi head sería usar un DefaultValue, así:

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

Suponiendo que hay algún valor que no es válido. En este caso, CustomSettingItem == -1 significa que wasnt set, y> = 0 era un valor establecido en config. Por supuesto, eso supone que -1 no era una entrada válida en primer lugar.

segunda idea es utilizar un int anulable en su lugar:

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

Ahora bien, si no hay nada escrito en config, debe valor NULL en lugar de 0.

+0

Eso funciona, pero esperaba que hubiera una manera de suprimir el valor predeterminado cuando la propiedad no está definida. El trabajo que estoy usando en este momento es config.Setting2.IsPresent – user62064

0

Hasta ahora no he podido para decirle a una propiedad que sea nula si no está definida en el archivo de configuración. Parece que en su sabiduría infinita, Microsoft decidió que realmente quiere decir String.Empty o nuevo ConfigurationElement() cuando escribe null.

La forma en que actualmente estoy resolver es la siguiente:

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 un truco y sin razón, marcará la propiedad según sea necesario. Si está usando una herramienta para editar su archivo de configuración, no le gustará esto.

11

Encontré que la mejor manera es anular ConfigurationSection.PostDeserialize() y verificar la propiedad IsPresent de cada miembro de la sección que se deriva de ConfigurationElement.

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

Cada ConfigurationElement que no ha sido leído desde el archivo de configuración será null después.

+0

Como nota al margen, no tienes que hacer esto en el evento 'PostDeserialize'. El 'ElementInformation' siempre está disponible:' Console.WriteLine ("Setting1 {0}", config.Setting1.CustomSettingItem.ElementInformation.IsPresent? "Y": "N"); ' –

2

intente lo siguiente:

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

La propiedad ValueOrigin te dice dónde viene el valor proviene de.

+0

' IsPresent' no devolvía el esperado valor por alguna razón (devolvió falso para todo).'ValueOrigin' funcionó para mí. – atheaos

0

También puede comprobar utilizando la siguiente:

config.Setting1.CustomSettingItem.ElementInformation.IsPresent 

que le dará falso si no se encuentra en su archivo de configuración.

Cuestiones relacionadas