c# - Cargar una sección de configuración con un elemento de configuración hijo requerido con el marco de configuración.Net
configuration configurationsection (3)
Tengo una aplicación de consola que intenta cargar una CustomConfigurationSection desde un archivo web.config.
La sección de configuración personalizada tiene un elemento de configuración personalizado que se requiere. Esto significa que cuando cargue la sección de configuración, espero ver una excepción si ese elemento de configuración no está presente en la configuración. El problema es que el .NET framework parece estar ignorando por completo el atributo isRequired. Entonces, cuando cargo la sección de configuración, solo creo una instancia del elemento de configuración personalizado y lo configuro en la sección de configuración.
Mi pregunta es, ¿por qué está sucediendo esto? Quiero que el método GetSection () dispare una excepción de ConfigurationErrors ya que falta un elemento requerido en la configuración.
Así es como se ve mi sección de configuración.
public class MyConfigSection : ConfigurationSection
{
[ConfigurationProperty("MyConfigElement", IsRequired = true)]
public MyConfigElement MyElement
{
get { return (MyConfigElement) this["MyConfigElement"]; }
}
}
public class MyConfigElement : ConfigurationElement
{
[ConfigurationProperty("MyAttribute", IsRequired = true)]
public string MyAttribute
{
get { return this["MyAttribute"].ToString(); }
}
}
Aquí es cómo cargo la sección de configuración.
class Program
{
public static Configuration OpenConfigFile(string configPath)
{
var configFile = new FileInfo(configPath);
var vdm = new VirtualDirectoryMapping(configFile.DirectoryName, true, configFile.Name);
var wcfm = new WebConfigurationFileMap();
wcfm.VirtualDirectories.Add("/", vdm);
return WebConfigurationManager.OpenMappedWebConfiguration(wcfm, "/");
}
static void Main(string[] args)
{
try{
string path = @"C:/Users/vrybak/Desktop/Web.config";
var configManager = OpenConfigFile(path);
var configSection = configManager.GetSection("MyConfigSection") as MyConfigSection;
MyConfigElement elem = configSection.MyElement;
} catch (ConfigurationErrorsException ex){
Console.WriteLine(ex.ToString());
}
}
Aquí está mi archivo de configuración.
<?xml version="1.0"?>
<configuration>
<configSections>
<section name="MyConfigSection" type="configurationFrameworkTestHarness.MyConfigSection, configurationFrameworkTestHarness" />
</configSections>
<MyConfigSection>
</MyConfigSection>
La parte más extraña es que si abro el archivo de configuración y cargo la sección 2 veces seguidas, obtendré la excepción que esperaba.
var configManager = OpenConfigFile(path);
var configSection = configManager.GetSection("MyConfigSection") as MyConfigSection;
configManager = OpenConfigFile(path);
configSection = configManager.GetSection("MyConfigSection") as MyConfigSection;
Si utilizo el código anterior, la excepción se activará y me dirá que se requiere MyConfigElement. La pregunta es ¿Por qué no lanza esta excepción la primera vez?
Eric ha respondido esto en los foros de MS
Para citar su respuesta:
El miembro IsRequired de ConfigurationPropertyAttribute no funciona cuando se aplica a un objeto secundario (derivado de ConfigurationElement)
¿Intentó asignarlo directamente al tipo correcto de variable, es decir, MyConfigSection en lugar de var? Esa es la única diferencia que puedo ver entre las dos líneas de código. (es decir, en la segunda línea, var ahora ha tomado un tipo específico).
Descubrí que la mejor solución para esto era iterar manualmente a través de todas las propiedades anidadas del tipo ConfigurationElement y verificarlas después de obtener la sección. Si se requiere un elemento pero no está presente en el archivo, solo lanzo una excepción ConfigurationErrorsException.
Aquí está mi código.
private void ProcessMissingElements(ConfigurationElement element)
{
foreach (PropertyInformation propertyInformation in element.ElementInformation.Properties)
{
var complexProperty = propertyInformation.Value as ConfigurationElement;
if (complexProperty == null)
continue;
if (propertyInformation.IsRequired && !complexProperty.ElementInformation.IsPresent)
throw new ConfigurationErrorsException("ConfigProperty: [{0}] is required but not present".FormatStr(propertyInformation.Name));
if (!complexProperty.ElementInformation.IsPresent)
propertyInformation.Value = null;
else
ProcessMissingElements(complexProperty);
}
}