¿Cómo puedo definir secciones web.config personalizadas con elementos secundarios y atributos potenciales para las propiedades?

Las aplicaciones web que desarrollo a menudo requieren configuraciones de configuración co-dependientes y también hay configuraciones que tienen que cambiar a medida que nos movemos entre cada uno de nuestros entornos.

Todas nuestras configuraciones son actualmente pares de valores clave simples, pero sería útil crear secciones de configuración personalizadas para que sea obvio cuando dos valores deben cambiarse juntos o cuando las configuraciones deben cambiar para un entorno.

¿Cuál es la mejor manera de crear secciones de configuración personalizadas y hay alguna consideración especial que hacer al recuperar los valores?

Uso de atributos, secciones de configuración secundaria y restricciones

También existe la posibilidad de utilizar atributos que automáticamente se ocupan de las tuberías, además de proporcionar la capacidad de agregar restricciones fácilmente.

Aquí presento un ejemplo del código que utilizo en uno de mis sitios. Con una restricción dicto la cantidad máxima de espacio en disco que cualquier usuario puede usar.

MailCenterConfiguration.cs:

namespace Ani { public sealed class MailCenterConfiguration : ConfigurationSection { [ConfigurationProperty("userDiskSpace", IsRequired = true)] [IntegerValidator(MinValue = 0, MaxValue = 1000000)] public int UserDiskSpace { get { return (int)base["userDiskSpace"]; } set { base["userDiskSpace"] = value; } } } } 

Esto está configurado en web.config como tal

   
...

Elementos secundarios

El correo del elemento xml secundario se crea en el mismo archivo .cs que el anterior. Aquí he agregado restricciones en el puerto. Si al puerto se le asigna un valor que no está en este rango, el tiempo de ejecución se quejará cuando se cargue la configuración.

MailCenterConfiguration.cs:

 public sealed class MailCenterConfiguration : ConfigurationSection { [ConfigurationProperty("mail", IsRequired=true)] public MailElement Mail { get { return (MailElement)base["mail"]; } set { base["mail"] = value; } } public class MailElement : ConfigurationElement { [ConfigurationProperty("host", IsRequired = true)] public string Host { get { return (string)base["host"]; } set { base["host"] = value; } } [ConfigurationProperty("port", IsRequired = true)] [IntegerValidator(MinValue = 0, MaxValue = 65535)] public int Port { get { return (int)base["port"]; } set { base["port"] = value; } } 

Utilizar

Para luego usarlo prácticamente en código, todo lo que tiene que hacer es crear una instancia del MailCenterConfigurationObject, esto leerá automáticamente las secciones relevantes de web.config.

MailCenterConfiguration.cs

 private static MailCenterConfiguration instance = null; public static MailCenterConfiguration Instance { get { if (instance == null) { instance = (MailCenterConfiguration)WebConfigurationManager.GetSection("mailCenter"); } return instance; } } 

AnotherFile.cs

 public void SendMail() { MailCenterConfiguration conf = MailCenterConfiguration.Instance; SmtpClient smtpClient = new SmtpClient(conf.Mail.Host, conf.Mail.Port); } 

Verificar validez

Anteriormente mencioné que el tiempo de ejecución se quejará cuando se cargue la configuración y algunos datos no cumplan con las reglas que ha configurado (por ejemplo, en MailCenterConfiguration.cs). Tiendo a querer saber estas cosas lo antes posible cuando mi sitio se active. Una forma de resolver esto es cargar la configuración en _Global.asax.cx.Application_Start_; si la configuración no es válida, se lo notificará con los medios de una excepción. Su sitio no comenzará y, en su lugar, se le presentará información detallada sobre excepciones en la pantalla amarilla de la muerte .

Global.asax.cs

 protected void Application_ Start(object sender, EventArgs e) { MailCenterConfiguration.Instance; } 

Quick’n Dirty:

Primero crea tus clases ConfigurationSection y ConfigurationElement :

 public class MyStuffSection : ConfigurationSection { ConfigurationProperty _MyStuffElement; public MyStuffSection() { _MyStuffElement = new ConfigurationProperty("MyStuff", typeof(MyStuffElement), null); this.Properties.Add(_MyStuffElement); } public MyStuffElement MyStuff { get { return this[_MyStuffElement] as MyStuffElement; } } } public class MyStuffElement : ConfigurationElement { ConfigurationProperty _SomeStuff; public MyStuffElement() { _SomeStuff = new ConfigurationProperty("SomeStuff", typeof(string), ""); this.Properties.Add(_SomeStuff); } public string SomeStuff { get { return (String)this[_SomeStuff]; } } } 

Luego, deje que el framework sepa cómo manejar sus clases de configuración en web.config :

   
...

Y agrega tu propia sección a continuación:

     

Entonces puedes usarlo en tu código así:

 MyWeb.Configuration.MyStuffSection configSection = ConfigurationManager.GetSection("MyStuffSection") as MyWeb.Configuration.MyStuffSection; if (configSection != null && configSection.MyStuff != null) { Response.Write(configSection.MyStuff.SomeStuff); } 

Hay un excelente ejemplo en MSDN usando ConfigurationCollection y .NET 4.5 para secciones personalizadas en web.config que tiene una lista de elementos de configuración.

La configuración personalizada es bastante práctica y, a menudo, las aplicaciones terminan demandando una solución extensible.

Para .NET 1.1, consulte el artículo http://aspnet.4guysfromrolla.com/articles/020707-1.aspx

Nota: La solución anterior también funciona para .NET 2.0.

Para la solución específica de .NET 2.0, consulte el artículo http://aspnet.4guysfromrolla.com/articles/032807-1.aspx

Puede lograr esto con Section Handlers. Hay una descripción general básica de cómo escribir uno en http://www.codeproject.com/KB/aspnet/ConfigSections.aspx; sin embargo, se refiere a app.config, que sería más o menos lo mismo que escribir uno para su uso en la web. config. Esto le permitirá esencialmente tener su propio árbol XML en el archivo de configuración y realizar una configuración más avanzada.

El método más simple, que encontré, es el uso de la sección appSettings .

  1. Agregue a Web.config lo siguiente:

        

  2. Acceda desde su código

     NameValueCollection appSettings = ConfigurationManager.AppSettings; string myPropVal = appSettings["MyProp"];