7 days of WordPress plugins, themes & templates - for free!* Unlimited asset downloads! Start 7-Day Free Trial
Advertisement
  1. Code
  2. ASP.NET

Cómo agregar ajustes de configuración personalizados para una aplicación .NET (ASP)

Scroll to top
Read Time: 15 mins

Spanish (Español) translation by Steven (you can also view the original English article)

Desde su lanzamiento, las aplicaciones y componentes ASP.NET han buscado en el archivo web.config para cargar cualquier configuración que necesiten para funcionar. Sin embargo, agregar configuraciones personalizadas para agregar flexibilidad y robustez a una aplicación o componente no es tan sencillo como a la mayoría le gustaría. Este artículo te enseña cómo escribir las clases necesarias para manejar los elementos de configuración XML y usar la configuración que contienen dentro de tu código.

Tutorial republicado

Cada pocas semanas, revisamos algunas de las publicaciones favoritas de nuestros lectores de toda la historia del sitio. Este tutorial fue publicado por primera vez en noviembre de 2012.

El Framework .NET proporciona una amplia variedad de configuraciones que se pueden configurar dentro de web.config para modificar el comportamiento de uno o más componentes integrados dentro de la aplicación. Para algunos desarrolladores, basta únicamente con la configuración proporcionada por .NET Framework. Pero muchos más desarrolladores encuentran que necesitan controlar una colección más amplia de configuraciones, ya sea para componentes (escritos por ellos mismos o por un tercero), o simplemente un conjunto de valores que se encuentran usando a lo largo de su aplicación.

El archivo web.config te permite establecer configuraciones personalizadas con el elemento <appSettings/>, pero no permite nada más que simples pares clave/valor. El siguiente elemento XML es un ejemplo de una configuración contenida en <appSettings/>:

Las configuraciones de Clave/Valor ciertamente pueden ser útiles en muchas circunstancias, pero las configuraciones de <appSettings/> simplemente no son lo suficientemente flexibles para componentes o configuraciones robustas o complejas.

Afortunadamente, Microsoft permite a los desarrolladores escribir clases que agregan acceso programático a las configuraciones personalizadas contenidas en web.config.


La sección de configuración

Las configuraciones dentro de web.config están categorizadas en secciones de configuración. Por ejemplo, la configuración contenida en la sección <system.web/> pertenece a la configuración de ASP.NET para tu aplicación. Puedes cambiar el esquema de autenticación de tu aplicación, así como agregar o eliminar controladores HTTP para realizar funciones específicas para tipos de archivos específicos. La sección <system.webServer/> te permite controlar muchas de las configuraciones de IIS7 sin tener acceso directo a IIS7.

Se requiere una sección de configuración de todas las configuraciones no contenidas en el elemento <appSettings/>. Por lo tanto, es una buena idea diseñar la estructura XML de tus ajustes de configuración antes de escribir cualquier código.

La configuración utilizada como ejemplo en este tutorial es para un componente que recupera feeds RSS o Atom. No realiza ningún análisis, ya que está fuera del alcance de este tutorial. En lugar de codificar la lista de fuentes para recuperar, el componente busca su configuración para contener los nombres y las direcciones URL de las fuentes para recuperar. El componente se llama FeedRetriever, y la estructura XML deseada de su configuración se ve así:

El elemento <feedRetriever/> se define en la sección de configuración. Como regla general, una sección de configuración debe compartir el nombre del componente para el que está diseñado. El elemento <feedRetriever/> hijo único es el elemento <feeds/>. Piensa en este elemento como una colección de fuentes porque contiene varios elementos <add/> (piensa en el método Add() que tienen la mayoría de los objetos de colección). La opción de usar un elemento llamado "add" puede parecer extraña al principio, pero el elemento se usa en la mayoría de las secciones de configuración incorporadas. Entonces, usarlo aquí simplemente sigue las prácticas de diseño presentadas por Microsoft.

Estos elementos <add/> utilizan los atributos de nombre, url y caché para establecer ciertas configuraciones para cada fuente. Naturalmente, los atributos de nombre y url son obligatorios, pero el atributo de caché no lo es, y debería ser predeterminado como verdadero.

La configuración anterior es simple. El elemento <feedRetriever/> podría modificarse para que contenga otro elemento secundario, llamado <globalSettings/>, para que contenga la configuración que se aplicaría a todas las fuentes. Los elementos <add/> también podrían usar atributos adicionales, como cacheTime y requestFrequency, para controlar cuánto tiempo se almacena en caché un feed y con qué frecuencia se solicita desde el host remoto. El único límite a la extensibilidad y configurabilidad es tu imaginación.


Escribir el controlador de configuración

Después de diseñar la estructura XML, el siguiente paso es escribir un controlador de configuración para procesar las configuraciones definidas en el XML. El controlador es principalmente una clase que hereda de System.Configuration.ConfigurationSection, pero también incorpora el uso de otras clases, como las clases que se derivan de System.Configuration.ConfigurationElement y System.Configuration.ConfigurationElementCollection.

Las clases basadas en ConfigurationElement representan elementos individuales; es el bloque de construcción de una sección de configuración. Los tipos que se derivan de ConfigurationElementCollection simplemente representan elementos que contienen más de un tipo de elemento. De la configuración mencionada anteriormente, el elemento <feeds/> está representado por una clase que deriva de ConfigurationElementCollection, y los elementos <add/> están representados por una clase basada en ConfigurationElement.


Representando el elemento <add/>

Comenzarás con el elemento <add/> representándolo con una clase llamada FeedElement (derivada de ConfigurationElement). Esta clase, y las futuras clases relacionadas con la configuración, residen en el espacio de nombres FeedRetriever.Configuration.

Cada objeto ConfigurationElement funciona como un indexador para su colección interna de valores de propiedad. Es esta colección interna, junto con los atributos .NET, lo que te permite asignar los atributos del elemento a las propiedades de la clase FeedElement.

El siguiente código es el código completo para la clase FeedElement:

La clase ConfigurationElement sirve como un indexador para una colección subyacente de propiedades de configuración (de ahí la notación del indexador de este [keyValue]). Al utilizar esta palabra clave y acceder a la propiedad subyacente con una clave de cadena, puedes obtener y establecer el valor de la propiedad sin necesidad de un campo privado para contener esos datos. La colección de propiedades subyacente almacena datos como tipo Objeto; por lo tanto, tienes que convertir el valor como el tipo apropiado si deseas hacer algo con él.

Las propiedades que representan atributos XML están decoradas con atributos ConfigurationPropertyAttribute. El primer parámetro del atributo ConfigurationPropertyAttribute es el nombre del atributo XML que se encuentra dentro del elemento . Después del primer parámetro hay un conjunto de cualquier número de parámetros nombrados. La siguiente lista es una lista completa de posibles parámetros:

  • DefaultValue: obtiene o establece el valor predeterminado para la propiedad decorada. Este parametro
    no es requerido.
  • IsDefaultCollection: obtiene o establece un valor booleano que indica si la propiedad
    es la colección de propiedades predeterminada para la propiedad decorada. Este parametro es
    no requerido, y el valor predeterminado es 'false'.
  • IsKey: obtiene o establece un valor booleano que indica si esta propiedad es una propiedad clave
    por el elemento decorado de la propiedad. Este parámetro no es necesario, y su valor predeterminado
    es 'false'.
  • IsRequired: obtiene o establece un valor booleano que indica si la propeidad del elemento decorado
    es requerido. Este parámetro no es obligatorio y su valor predeterminado es falso.

El valor predeterminado de "http://localhost" para la propiedad Url no es un error. El Framework .NET también te otorga la posibilidad de decorar las propiedades con atributos de validador, como el RegexStringValidatorAttribute que decora la propiedad Url. Este validador toma el valor de la propiedad Url y lo valida contra la expresión regular proporcionada al atributo; sin embargo, también valida la propiedad Url antes de que contenga los datos del elemento XML. El valor predeterminado de la propiedad Url es una cadena vacía cuando se crea un objeto FeedElement por primera vez. Una cadena vacía no se valida con la expresión regular proporcionada, por lo que el validador emite una ArgumentException antes de que se cargue ningún dato del archivo XML.

Hay dos soluciones posibles para este problema. El primer enfoque modifica la expresión regular para permitir cadenas vacías. El segundo enfoque asigna un valor predeterminado a la propiedad. No importa en este caso particular. Incluso con un valor predeterminado, el atributo url sigue siendo un atributo requerido en el elemento <add />, la aplicación lanza una excepción ConfigurationErrorsException si un elemento <add/> no tiene un atributo url.

Hay varios otros atributos de validación en el espacio de nombres de System.Configuration para validar los datos asignados a las propiedades y los atributos XML a los que se asignan. A continuación se enumeran todos los atributos del validador dentro del espacio de nombres de System.Configuration:

Con la excepción de CallbackValidatorAttribute, no tienes que crear los objetos de validador correspondientes para utilizarlos junto con los atributos de validador. El tiempo de ejecución de .NET crea los objetos de validador apropiados para ti, y los atributos contienen los parámetros necesarios para configurar los objetos del validador.

Este pequeño fragmento de código es todo lo que se requiere para representar mediante programación los elementos individuales de <add/>. El siguiente paso es escribir una clase que represente el elemento <feeds />.


Escribir una clase de colección de elementos

La representación XML del elemento <feeds/> es la de una colección de elementos feed. Del mismo modo, la representación programática del elemento <feeds/> es una colección de objetos FeedElement. Esta clase, llamada FeedElementCollection, deriva de la clase abstracta ConfigurationElementCollection.

La clase ConfigurationElementCollection contiene varios miembros, pero solo dos están marcados como abstractos. Por lo tanto, la implementación más sencilla de ConfigurationElementCollection tiene dos métodos:

  • CreateNewElement(): crea un nuevo objeto ConfigurationElement (FeedElement en este
    caso).
  • GetElementKey(): obtiene la clave del elemento para un elemento de configuración especificado (el
    Nombre de la propiedad de los objetos FeedElement en este caso).

Con eso en mente, mira el código completo para la clase FeedElementCollection a continuación:

Un ConfigurationCollectionAttribute decora esta clase de colección. El primer parámetro del atributo es un objeto Type: el tipo de los elementos que contiene la colección. En este caso, es el tipo FeedElement. Después del parámetro de tipo hay varios parámetros con nombre que puede pasar al atributo. Estos se enumeran a continuación:

  • AddItemName: establece el nombre del elemento <add/> de configuración . Por ejemplo,
    establecer esto como "feed" requeriría los elementos en la
    configuración a cambiar a <feed/>.
  • ClearItemsName: establece el nombre del elemento <clear/> de configuración (usado
    para borrar todos los elementos de la colección).
  • RemoveItemName: establece el nombre para el elemento de configuración (usado
    para eliminar un elemento de la colección).

Dejando estos parámetros con nombre en blanco, se predeterminan para<add/>, <clear/>, <remove/>.


Escribiendo la clase FeedRetreiverSection

La clase final, llamada FeedRetrieverSection, deriva de ConfigurationSection y representa el elemento <feedRetriever/>. Esta es la clase más simple de las clases de configuración, ya que el único requisito que debe cumplir es proporcionar acceso programático al elemento (FeedElementCollection).

Es una propiedad, del tipo FeedElementCollection y llamada Feeds, está decorada con un ConfigurationPropertyAttribute - asignándola al elemento .


Modificar web.config

Con el controlador de configuración completo, puedes agregar los elementos adecuados a web.config. La sección <feedRetriever/> puede ir a cualquier parte del archivo siempre y cuando sea un descendiente directo del elemento raíz (el elemento <configuration/>). Colocarlo en otra sección de configuración da como resultado un error.

El siguiente paso es agregar un elemento <section/> secundario a <configSections/>. El elemento <section/>tiene dos atributos de interés:

  • name: el nombre del elemento de la sección de configuración. En este caso, el nombre es feedRetriever.
  • type: el nombre calificado de la clase asociada con la sección y, si es necesario,
    el nombre del conjunto en el que reside la clase. En este caso, el nombre calificado
    es FeedRetriever.Configuration.FeedRetrieverSection. Si reside en un lugar separado
    ensamblado, el atributo de tipo tendría un valor de "FeedRetriever.Configuration.FeedRetrieverSection,
    <assemblyName> ", donde <assemblyName> es el nombre del ensamblado
    sin los soportes angulares.

El siguiente elemento <section/> es lo que agregas a un archivo web.config, en <configSections/>, cuando las clases de configuración no residen en un conjunto separado (como es el caso en la descarga del código):

Ahora tu aplicación está configurada correctamente para usar las clases FeedRetrieverSection, FeedElementCollection y FeedElement para otorgarte acceso programático a las configuraciones personalizadas contenidas en la sección de configuración <feedRetriever/> en web.config. Entonces, ¿cómo accedes a estas configuraciones desde tu código?


Acceso a los datos de configuración desde el código

El espacio de nombres System.Configuration contiene una clase estática llamada ConfigurationManager. Si usas la sección para alojar tus cadenas de conexión, por lo menos estás familiarizado con ConfigurationManager. Tiene un método llamado GetSection(), que acepta una cadena que contiene el nombre de la sección de configuración para recuperar. El siguiente código lo demuestra (supongamos que el uso de System.Configuration se encuentra en la parte superior del archivo de código):

El método GetSection() devuelve un valor de tipo Object, por lo que se debe convertir al tipo que sea el controlador para esa sección. Este código recupera la sección denominada feedRetriever y convierte el resultado como FeedRetrieverSection. Una vez que tengas el objeto, puedes comenzar a acceder a los datos de configuración mediante programación.

Para darte una idea de cómo se pueden usar los ajustes de configuración dentro de tu componente o aplicación, el siguiente código es una implementación muy básica del componente FeedRetriever.

Primero, una variable estática llamada _Config, de tipo FeedRetreiverSection, se declara y se le asigna un valor llamando a ConfigurationManager.GetSection(). Hacer la variable estática es una opción de diseño. Al hacerlo, todos los miembros de la clase, ya sea instancia o estática, tendrían acceso a los ajustes de configuración sin tener que realizar varias llamadas a GetSection().

Una vez que recuperes el controlador de sección con GetSection(), tendrás acceso completo a los objetos creados a partir de tus clases de controlador. La primera línea de GetFeeds() es para cada bucle que recorre todos los objetos FeedElement contenidos con el objeto FeedElementCollection devuelto por la propiedad Feeds. Esto te brinda acceso directo a esos objetos FeedElement, lo que facilita el acceso al nombre, la URL y la configuración de la memoria caché de cada fuente.

Durante cada iteración del bucle, el método realiza una solicitud utilizando la propiedad Url del objeto FeedElement. Si la solicitud resulta exitosa, los datos del feed se recuperan y almacenan en la variable feedData. Luego, el código verifica la propiedad Caché del objeto FeedElement para determinar si se debe o no almacenar la alimentación. El almacenamiento en caché de la fuente implica la construcción de un nombre de archivo utilizando la propiedad Name del objeto FeedElement y la fecha y hora actuales. Luego, un objeto StreamWriter crea el archivo y escribe los datos del feed en él.

Como puedes ver, usar las clases del handler (controlador) de la sección de configuración es clave para recuperar y usar configuraciones personalizadas que residen en web.config. Sin duda, requiere más tiempo y esfuerzo tuyo, pero definitivamente hace que tu aplicación o componente sea mucho más fácil de configurar para ti y para otros desarrolladores.


¡Vende tus componentes .NET en CodeCanyon!


CodeCanyon

¿Sabías que tenemos una categoría .NET en CodeCanyon? Si eres un experto en desarrollo de .NET, ¿por qué no vender tus scripts/componentes/controles como autor y ganar el 40-70% de cada venta?

  • Síguenos en Twitter o suscríbete a Tuts + RSS Feed para obtener los mejores tutoriales de desarrollo web de manera Online.
Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.