<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Juanma Santoyo &#187; asp.net</title>
	<atom:link href="http://www.juanmasantoyo.es/index.php/tag/asp-net/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.juanmasantoyo.es</link>
	<description>En ocasiones me llaman friki</description>
	<lastBuildDate>Thu, 19 Jan 2012 06:33:10 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=</generator>
		<item>
		<title>XML dinámicos con asp.Net</title>
		<link>http://www.juanmasantoyo.es/index.php/2010/03/16/xml-dinamicos-con-asp-net/</link>
		<comments>http://www.juanmasantoyo.es/index.php/2010/03/16/xml-dinamicos-con-asp-net/#comments</comments>
		<pubDate>Tue, 16 Mar 2010 19:04:33 +0000</pubDate>
		<dc:creator>Juanma</dc:creator>
				<category><![CDATA[.net]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[asmx]]></category>
		<category><![CDATA[asp.net]]></category>
		<category><![CDATA[webservice .net]]></category>
		<category><![CDATA[xml dinamicos]]></category>

		<guid isPermaLink="false">http://www.juanmasantoyo.es/?p=397</guid>
		<description><![CDATA[Desde que me inicié en el asp.Net (no hace demasiado de eso) me he estado preguntando cómo se podría hacer una llamada al servidor que devolviese un contenido XML dinámico. Dicho de otra forma, lo que yo quería era generar un contenido XML en base a un parámetro enviado por GET o POST. Estos XML son necesarios para cualquier aplicación basada en Ajax que se precie, además de ser especialmente útiles para otras situaciones (como por ejemplo, compartir contenido interno a un destinatario externo).

Pues bien, hace un par de días me surgió la necesidad y investigué un poco al respecto. En realidad, la solución que nos propone asp.Net no está nada mal: un archivo asmx que actúa como WebService. <a href="http://www.juanmasantoyo.es/index.php/2010/03/16/xml-dinamicos-con-asp-net/">Seguir leyendo <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Desde que me inicié en el asp.Net (no hace demasiado de eso) me he estado preguntando cómo se podría hacer una llamada al servidor que devolviese un contenido <em>XML</em> dinámico. Dicho de otra forma, lo que yo quería era generar un contenido XML en base a un parámetro enviado por GET o POST. Estos <em>XML</em> son necesarios para cualquier aplicación basada en <a href="http://www.juanmasantoyo.es/index.php/category/ajax/">Ajax</a> que se precie, además de ser especialmente útiles para otras situaciones (como por ejemplo, compartir contenido interno a un consumidor externo).</p>
<p>Pues bien, hace un par de días me surgió la necesidad y investigué un poco al respecto. En realidad, la solución que nos propone <em>.Net</em> no está nada mal: un archivo <em>.asmx</em> que actúa como <em>WebService</em>.<br />
<span id="more-397"></span></p>
<h3>Sobre los <em>.asmx</em></h3>
<p>De la misma forma que podemos añadir archivos <em>.aspx</em> a un proyecto web, también podemos añadir archivos <em>.asmx</em>. Estos archivos son la base de cualquier proyecto de <em>WebService</em> que desarrollemos en <em>.Net</em>, pero también podemos usarlos en los proyectos web normales.</p>
<h3>¿Cómo se usan los <em>.asmx</em>?</h3>
<p>El uso de los <em>.asmx</em> es simple: básicamente, lo que debemos hacer es crear un método, que devuelva un valor y que tenga la etiqueta [WebMethod]. Al final, la llamada a servidor: &#8220;http://&lt;ruta al asmx&gt;/&lt;nombre del método&gt;/&lt;parámetros get si hay&gt;&#8221; nos devolverá el resultado devuelto por el método.</p>
<p>Por supuesto, el método puede tener parámetros, que enviaremos por <em>GET</em> o por <em>POST</em>; en cuyo caso, al hacer la llamada los parámetros enviados deberán tener el mismo nombre que el parámetro en el método.</p>
<p>Es importante destacar que si queremos enviar parámetros por <em>GET</em> o <em>POST</em>, deberemos activar ambos protocolos en el <em>Web.config</em> de nuestra aplicación.</p>
<h3>Un ejemplo</h3>
<p>La mejor forma de ver cómo funciona un <em>.asmx</em> es viendo un pequeño ejemplo. Con poco esfuerzo podremos hacer algunas pruebas.</p>
<h4>Crear el proyecto</h4>
<p>Sólo necesitaremos crear un nuevo proyecto web en nuestro Visual Studio. Nos creará por defecto un <em>.aspx</em>, pero no nos interesa demasiado.</p>
<h4>Crear el asmx</h4>
<p>Añadiremos en el proyecto web un nuevo elemento, que será un Servicio web. Lo encontrarás entre los posibles elementos de la categoría &#8220;Web&#8221;. Lo llamaremos &#8220;<em>test.asmx</em>&#8220;.</p>
<p>Cuando tengamos nuestro <em>.asmx</em> creado, lo estableceremos como la página inicial de nuestro proyecto (es una opción que aparecerá si clicamos con el botón derecho en el <em>.asmx</em>).</p>
<h4>Un nuevo método en el <em>.asmx</em></h4>
<p>En el <em>.asmx</em> ya tenemos un método creado: <em>HelloWorld</em>. Es muy ilustrativo, ya que nos indica dos cosas: la primera, que nuestros métodos deberán tener al principio la etiqueta <strong>[WebMethod]</strong>. La segunda, que el valor retornado será lo que mostrará nuestro <em>WebService</em> al realizar una petición al método.</p>
<p>Vamos a programar un método más bien absurdo, pero que nos permitirá ver cómo funciona el envío de parámetros:</p>
<pre class="brush:csharp">
	[WebMethod]
	public string ReturnThisString(string str)
	{
		return str;

	}
</pre>
<p>Hay dos cosas a destacar:</p>
<ol>
<li>El parámetro que recibe este método se llama <strong>str</strong>.</li>
<li>El resultado que genera este método, es un <em>string</em>.</li>
</ol>
<h3>Activamos los protocolos <em>GET</em> y <em>POST</em></h3>
<p>Como dije unas líneas más arriba, debemos activar los protocolos de envío <em>GET</em> y <em>POST</em> si queremos usarlos en nuestro <em>WebService</em>. Todo lo que debemos hacer es incluir <strong>dentro</strong> del nodo <em>&lt;system.web/&gt;</em> de nuestro <em>Web.config</em> las siguientes líneas:</p>
<pre class="brush:xml">
	&lt;webServices&gt;
		&lt;protocols&gt;
			&lt;add name=&quot;HttpGet&quot; /&gt;
			&lt;add name=&quot;HttpPost&quot; /&gt;
		&lt;/protocols&gt;
	&lt;/webServices&gt;
</pre>
<h4>Probamos el <em>WebService</em></h4>
<p>Y toca inicar una depuración. La primera vez que lo hagamos nos pedirá que activemos el modo debug. Le decimos que sí, y arrancará el <em>.asmx</em>.</p>
<p><a href="http://www.juanmasantoyo.es/wp-content/uploads/2010/03/XmlDinamicosAspNet-01-e1268766894973.png"><img src="http://www.juanmasantoyo.es/wp-content/uploads/2010/03/XmlDinamicosAspNet-01-e1268766894973.png" alt="Métodos del WebService" title="Métodos del WebService" width="450" height="131" class="aligncenter size-full wp-image-403" /></a></p>
<p>Lo que veremos, será un resumen de los métodos que tiene el <em>.asmx</em> (esto no se vería en un entorno de producción). Podemos clicar en el nombre de nuestro método &#8220;<em>ReturnThisString</em>&#8221; para que nos muestre un pequeño formulario donde indicaremos el valor del parámetro &#8220;<em>str</em>&#8220;. Al enviarlo, veremos el resultado de nuestro método de <em>WebService</em>.</p>
<p><a href="http://www.juanmasantoyo.es/wp-content/uploads/2010/03/XmlDinamicosAspNet-02-e1268766971605.png"><img src="http://www.juanmasantoyo.es/wp-content/uploads/2010/03/XmlDinamicosAspNet-02-e1268766971605.png" alt="Formulario de envío de parámetros" title="Formulario de envío de parámetros" width="450" height="244" class="aligncenter size-full wp-image-404" /></a></p>
<p>Hay varias cosas interesantes en las que fijarse ahora:</p>
<ol>
<li>
		El resultado devuelto es un XML.	</p>
<p>		Sea cual sea el resultado, el asmx siempre nos dará una respuesta XML.
	</li>
<li>
		La ruta de la página.</p>
<p>		Como ves, la url de este xml es: &#8220;http://&lt;ruta al asmx&gt;/&lt;nombre del método&gt;/&lt;parámetros get si hay&gt;&#8221;. Esta es la dirección a la que accederemos para obtener resultados de nuestro <em>WebService</em>, ya sea con <em>Ajax</em> o con otra tecnología.
	</li>
<li>
		El nodo <em>string</em>.</p>
<p>		El resultado del método viene, en realidad, dentro de un nodo llamado <em>string</em>. Esto es, efectívamente, el tipo del dato devuelto. ¿imaginas lo que pasaría si en vez de un <em>string</em>, devolvemos una lista de <em>strings</em>? Efectivamente, el <em>XML</em> resultante sería una lista de nodos <em>string</em>.</p>
<p><a href="http://www.juanmasantoyo.es/wp-content/uploads/2010/03/XmlDinamicosAspNet-03-e1268766951190.png"><img src="http://www.juanmasantoyo.es/wp-content/uploads/2010/03/XmlDinamicosAspNet-03-e1268766951190.png" alt="Resultado de una llamada al método ReturnThisString" title="Resultado de una llamada al método ReturnThisString" width="450" height="114" class="aligncenter size-full wp-image-405" /></a>
	</li>
</ol>
<h4>Generamos un <em>XML</em> como respuesta del método</h4>
<p>Como ves, los <em>WebServices</em> <em>.asmx</em> no son demasiado complicados, aunque por el momento seguimos teniendo un pequeño problema: los <em>XML</em> que generamos como resultado son generados automáticamente y no tenemos control sobre ellos. Vamos a poner solución a esto.</p>
<p>La cuestión es que si en lugar de un <em>string</em>, devolvemos un objeto <em>XmlDocument</em>, el resultado devuelto por el <em>WebService</em> será el contenido del <em>XmlDocument</em> tal cual. Por lo tanto, se podría decir que el proceso para generar respuestas <em>XML</em> personalizadas (la razón de este artículo) es el siguiente:</p>
<ol>
<li>Creamos un método en el <em>.asmx</em> que devuelva un objeto <em>XmlDocument</em>.</li>
<li>Obtenemos todos los datos que queramos devolver.</li>
<li>Los metemos en un <em>XmlDocument</em>.</li>
<li>Retornamos el <em>XmlDocument</em>.</li>
</ol>
<h4>Un último ejemplo</h4>
<p>Vamos a crear un último ejemplo: un pequeño método que nos introducirá en la creación de <em>XML</em> dinámicos:</p>
<pre class="brush:csharp">
	[WebMethod]
	public XmlDocument ReturnXml()
	{
		XmlDocument xml = new XmlDocument();

		XmlNode rootNode = xml.CreateElement("RespuestaXml");
		XmlNode txtNode = xml.CreateTextNode("Xml generado automáticamente");
		XmlNode subNode = xml.CreateElement("HolaMundo");
		XmlNode commentNode = xml.CreateComment("Esto es un comentario");

		subNode.AppendChild(commentNode);
		rootNode.AppendChild(txtNode);
		rootNode.AppendChild(subNode);
		xml.AppendChild(rootNode);

		return xml;
	}
</pre>
<p>Esto generaría el siguiente resultado:</p>
<p><a href="http://www.juanmasantoyo.es/wp-content/uploads/2010/03/XmlDinamicosAspNet-04-e1268766930458.png"><img src="http://www.juanmasantoyo.es/wp-content/uploads/2010/03/XmlDinamicosAspNet-04-e1268766930458.png" alt="Resultado de una llamada al método ReturnXml" title="Resultado de una llamada al método ReturnXml" width="450" height="211" class="aligncenter size-full wp-image-406" /></a></p>
<h3>Descargar el ejemplo</h3>
<p>Puedes descargar el ejemplo si algo no te ha quedado claro. Recuerda también que puedes dejar comentarios.</p>
<p><a href='http://www.juanmasantoyo.es/wp-content/uploads/2010/03/JuanmaSantoyoXmlDinamicos.zip'>JuanmaSantoyoXmlDinamicos</a></p>
<h3>¡Hemos terminado!</h3>
<p>Y de momento no hay mucho más que decir. Con este ejemplo, hemos tocado un tema especialmente importante para la mayoría de proyectos web, ya que los <em>XML</em> dinámicos son importantes para las funcionalidades <em>Ajax</em> y para comunicarnos con otras aplicaciones externas. ¿Aún no tienes RSS en tu sitio web? <a href="http://www.rssboard.org/rss-specificationg">¡A qué esperas!</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.juanmasantoyo.es/index.php/2010/03/16/xml-dinamicos-con-asp-net/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Clase para acceso avanzado a las AppSettings del WebConfig</title>
		<link>http://www.juanmasantoyo.es/index.php/2010/02/08/clase-para-acceso-avanzado-a-las-appsettings-del-webconfig/</link>
		<comments>http://www.juanmasantoyo.es/index.php/2010/02/08/clase-para-acceso-avanzado-a-las-appsettings-del-webconfig/#comments</comments>
		<pubDate>Mon, 08 Feb 2010 17:41:54 +0000</pubDate>
		<dc:creator>Juanma</dc:creator>
				<category><![CDATA[.net]]></category>
		<category><![CDATA[appsettings]]></category>
		<category><![CDATA[asp.net]]></category>
		<category><![CDATA[webconfig]]></category>

		<guid isPermaLink="false">http://www.juanmasantoyo.es/?p=292</guid>
		<description><![CDATA[Para quien no lo sepa, el WebConfig de asp.Net es un archivo XML que contiene todos los aspectos de configuración de nuestra aplicación. Entre los distintos parámetros, hay un nodo llamado AppSettings que nos permite definir pares clave / valor para después acceder a ellas desde cualquier punto de la aplicación.

Pero, a pesar de que el api proporciona dos métodos diferentes de acceso a las AppSettings, ambos tienen algunos inconvenientes. Lo que haremos, es crear una pequeña clase que nos permitirá tratar las AppSettings de una forma más simple y con una funcionalidad mejorada. <a href="http://www.juanmasantoyo.es/index.php/2010/02/08/clase-para-acceso-avanzado-a-las-appsettings-del-webconfig/">Seguir leyendo <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Para quien no lo sepa, el WebConfig de asp.Net es un archivo XML que contiene todos los aspectos de configuración de nuestra aplicación. Entre los distintos parámetros, hay un nodo llamado AppSettings que nos permite definir pares clave / valor para después acceder a ellas desde cualquier punto de la aplicación.</p>
<p>Pero, a pesar de que el api proporciona dos métodos diferentes de acceso a las AppSettings, ambos tienen algunos inconvenientes. Lo que haremos, es crear una pequeña clase que nos permitirá tratar las AppSettings de una forma más simple y con una funcionalidad mejorada.<br />
<span id="more-292"></span></p>
<p><a href='http://www.juanmasantoyo.es/wp-content/uploads/2010/02/AppSettings.zip'>Clase AppSettings</a></p>
<h3>Los inconvenientes</h3>
<p>Los inconvenientes a la hora de trabajar con las variables de AppSettings son varios. Se podría decir que hay dos formas de acceder. Comentemos las dos formas:</p>
<h4>Primera forma: la clase ConfigurationManager</h4>
<p>La clase ConfigurationManager nos proporciona un diccionario estático que contiene los valores definidos en AppSettings:</p>
<pre class="brush:c-sharp">
ConfigurationManager.AppSettings["clave"];
</pre>
<p>A mi modo de ver, más largo de lo necesario y poco intuitivo (escribid &#8220;Configuration&#8221; en un VisualStudio y mirad cuantas entradas muestra el intellisense). Prometo que me costó un par de intentos memorizar esta línea.</p>
<p>Por otra parte, lo más grave es que el dato devuelto es siempre un <em>string</em>, lo cual nos obliga a hacer una conversión del dato inmediatamente después si queremos otro formato.</p>
<h4>Segunda forma: la clase AppSettingsReader</h4>
<p>Esta segunda clase, tiene algunas ventajas respecto a la anterior, pero también es mejorable.</p>
<p>Por una parte, su uso requiere de una instancia de AppSettingsReader y la posterior invocación a un método:</p>
<pre class="brush:c-sharp">
AppSettingsReader settings = new AppSettingsReader();
string valor = (string) settings.GetValue("clave", typeof(string));
</pre>
<p>Por no mencionar el casting obligatorio.</p>
<p>Por otra parte, aunque en principio se puede especificar el tipo del dato devuelto, hay poco control sobre él. ¿Qué pasa si es una fecha? Sinceramente, ni lo he probado.</p>
<h3>Una posible solución</h3>
<p>Yendo al grano, lo cierto es que el acceso a las AppSettings es mejorable. Vamos a considerar y a anotar algunas cosas sobre una posible alternativa que nos solucione los inconvenientes comentados:</p>
<ul>
<li>Se accede desde una clase estática, pero más simple que la vista en la primera forma de acceder. No debería ser mucho más complejo que <em>AppSettings.GetValue(&#8220;clave&#8221;)</em>.</li>
<li>Se ofrecen varios tipos básicos (pocos, pero controlados) como posibles retornos. Nuestra clase se encarga de hacer la conversión.</li>
<li>Además, la clase será capaz de realizar un tratamiento avanzado del contenido de las AppSettings: podrá retornar listas y diccionarios de los tipos básicos.</li>
</ul>
<h3>Definimos los diferentes tipos básicos de AppSettings</h3>
<p>Serán solamente cuatro, pero a cambio ganaremos el control absoluto sobre los valores que retornamos.</p>
<p>Los tipos serán:</p>
<ul>
<li><em>string</em></li>
<li><em>int</em></li>
<li><em>bool</em></li>
<li><em>DateTime</em></li>
</ul>
<h3>Definimos los diferentes formatos de las claves del AppSettings</h3>
<p>Vamos a estipular como deberán ser escritos los datos en el WebConfig. A partir de ahora, deberemos escribir los valores en AppSettings siguiendo uno de los formatos siguientes. aunque ante cualquier excepción, siempre podremos obtener los datos como un tipo básico <em>string</em> (que será como si no aplicásemos ninguna conversión). </p>
<h4>Datos básicos</h4>
<p>No consideraremos un formato para los datos básicos porque no lo necesitan (excepto las fechas, que las vemos ahora mismo). Las cadenas se escribirán como cadenas, los números como números, y los booleanos como <em>&#8220;true&#8221;</em> y <em>&#8220;false&#8221;</em>.</p>
<h4>Fechas</h4>
<p>Las fechas seguirán un formato típicamente español:</p>
<p>dia/mes/año</p>
<p>Donde los días van del 1 al 31, los meses del 1 al 12, y los años tienen cuatro cifras.</p>
<h4>Listas</h4>
<p>Separaremos los diferentes elementos con comas.</p>
<p>valor1, valor2, valor3, valor4</p>
<p>Los espacios en blanco entre los valores y las comas serán indiferentes.</p>
<h4>Diccionarios</h4>
<p> Separaremos los pares con comas, y los clave valor con dos puntos.</p>
<p>clave1: valor1, clave2: valor2, clave3: valor3</p>
<p>Al igual que antes, los espacios en blanco entre los separadores y los valores son indiferentes.</p>
<h3>Programamos la clase AppSettings</h3>
<p>Ya sabemos que formatos tenemos que considerar. Ahora vamos a programar nuestra clase.</p>
<p>Antes que nada, debemos tener más o menos claro cómo queremos hacerlo. Lo haremos así:</p>
<ul>
<li>Tendremos un método privado, llamado <em>Get</em>; que se encargará simplemente de obtener el dato de WebConfig como un <em>string</em>.</li>
<li>Tendremos tres métodos privados que se encargarán de convertir un <em>string</em> al resto de formatos. Se llamarán <em>ToInt</em>, <em>ToBool</em> y <em>ToDate</em>.</li>
<li>Tendremos varios métodos públicos, cada uno devolverá un tipo de dato. Los métodos se llamarán <em>GetAsString</em>, <em>GetAsStringList</em>, <em>GetAsStringDict</em>, <em>GetAsInt</em>, etc.</li>
</ul>
<h4>El método Get</h4>
<pre class="brush:c-sharp">
private static string Get(string key)
{
	AppSettingsReader settings = new AppSettingsReader();            

	return (string) settings.GetValue(key, typeof(string));
}
</pre>
<p>En este método tenemos la única instancia de AppSettingsReader que vamos a usar. El resto de métodos de la clase se apoyarán en este para obtener la información del WebConfig.</p>
<h4>Los métodos conversores</h4>
<p>Serán tres. Uno convertirá un <em>string</em> a <em>int</em>, otro a <em>bool</em> y el último a <em>DateTime</em>.</p>
<pre class="brush:c-sharp">
private static int ToInt(string value)
{
	int v = 0;

	if (int.TryParse(value, out v))
	{
		return v;
	}

	return 0;
}

private static bool ToBool(string value)
{
	bool v = false;

	if (bool.TryParse(value, out v))
	{
		return v;
	}

	return false;
}

private static DateTime ToDateTime(string value)
{
	DateTime v = DateTime.Today;

	if (DateTime.TryParseExact(value, "dd/MM/yyyy", new CultureInfo("es-ES"), DateTimeStyles.None, out v))
	{
		return v;
	}

	else return new DateTime();
}
</pre>
<h4>Los métodos que retornarán los datos</h4>
<p>Estos métodos se apoyarán en los anteriores para obtener los valores, darles un formato de salida y devolverlos. Hay uno por tipo de dato y tipo de salida (normal, lista o diccionario).</p>
<p>Además, a los métodos que requieran de un separador (los que devuelven listas y diccionarios) les haremos una sobrecarga que permita indicar un separador distinto. De esta forma podremos reaccionar ante posibles conflictos entre nuestros separadores por defecto y los valores que contengan las AppSettings.</p>
<pre class="brush:c-sharp">
public static string GetAsString(string key)
{
	string value = Get(key);

	return value;
}

public static int GetAsInt(string key)
{
	string value = Get(key);

	return ToInt(value);
}

public static bool GetAsBool(string key)
{
	string value = Get(key);

	return ToBool(value);
}

public static DateTime GetAsDateTime(string key)
{
	string value = Get(key);

	return ToDateTime(value);
}

public static List&lt;string&gt; GetAsStringList(string key, char sep)
{
	string value = Get(key);
	List&lt;string&gt; list = new List&lt;string&gt;();

	foreach (string s in value.Split(new char[] { sep }))
	{
		list.Add(s.Trim());
	}

	return list;
}

public static List&lt;string&gt; GetAsStringList(string key)
{
	return GetAsStringList(key, '|');
}

public static List&lt;int&gt; GetAsIntList(string key, char sep)
{
	string value = Get(key);
	List&lt;int&gt; list = new List&lt;int&gt;();

	foreach (string s in value.Split(new char[] { sep }))
	{
		list.Add(ToInt(s.Trim()));
	}

	return list;
}

public static List&lt;int&gt; GetAsIntList(string key)
{
	return GetAsIntList(key, '|');
}

public static List&lt;bool&gt; GetAsBoolList(string key, char sep)
{
	string value = Get(key);
	List&lt;bool&gt; list = new List&lt;bool&gt;();

	foreach (string s in value.Split(new char[] { sep }))
	{
		list.Add(ToBool(s.Trim()));
	}

	return list;
}

public static List&lt;bool&gt; GetAsBoolList(string key)
{
	return GetAsBoolList(key, '|');
}

public static List&lt;DateTime&gt; GetAsDateTimeList(string key, char sep)
{
	string value = Get(key);
	List&lt;DateTime&gt; list = new List&lt;DateTime&gt;();

	foreach (string s in value.Split(new char[] { sep }))
	{
		list.Add(ToDateTime(s.Trim()));
	}

	return list;
}

public static List&lt;DateTime&gt; GetAsDateTimeList(string key)
{
	return GetAsDateTimeList(key, '|');
}

public static Dictionary&lt;string, string&gt; GetAsStringDict(string key, char itemSep, char valueSep)
{
	string raw = Get(key);
	Dictionary&lt;string, string&gt; dict = new Dictionary&lt;string, string&gt;();

	foreach(string i in raw.Split(itemSep))
	{
		string item = i.Trim();

		string[] value = item.Split(valueSep);
		value[0] = value[0].Trim();
		value[1] = value[1].Trim();

		if (!dict.ContainsKey(value[0]))
		{
			dict.Add(value[0], value[1]);
		}
	}

	return dict;
}

public static Dictionary&lt;string, string&gt; GetAsStringDict(string key)
{
	return GetAsStringDict(key, ';', '|');
}

public static Dictionary&lt;string, int&gt; GetAsIntDict(string key, char itemSep, char valueSep)
{
	string raw = Get(key);
	Dictionary&lt;string, int&gt; dict = new Dictionary&lt;string, int&gt;();

	foreach (string i in raw.Split(itemSep))
	{
		string item = i.Trim();

		string[] value = item.Split(valueSep);
		value[0] = value[0].Trim();
		value[1] = value[1].Trim();

		if (!dict.ContainsKey(value[0]))
		{
			dict.Add(value[0], ToInt(value[1]));
		}
	}

	return dict;
}

public static Dictionary&lt;string, int&gt; GetAsIntDict(string key)
{
	return GetAsIntDict(key, ';', '|');
}

public static Dictionary&lt;string, bool&gt; GetAsBoolDict(string key, char itemSep, char valueSep)
{
	string raw = Get(key);
	Dictionary&lt;string, bool&gt; dict = new Dictionary&lt;string, bool&gt;();

	foreach (string i in raw.Split(itemSep))
	{
		string item = i.Trim();

		string[] value = item.Split(valueSep);
		value[0] = value[0].Trim();
		value[1] = value[1].Trim();

		if (!dict.ContainsKey(value[0]))
		{
			dict.Add(value[0], ToBool(value[1]));
		}
	}

	return dict;
}

public static Dictionary&lt;string, bool&gt; GetAsBoolDict(string key)
{
	return GetAsBoolDict(key, ';', '|');
}

public static Dictionary&lt;string, DateTime&gt; GetAsDateTimeDict(string key, char itemSep, char valueSep)
{
	string raw = Get(key);
	Dictionary&lt;string, DateTime&gt; dict = new Dictionary&lt;string, DateTime&gt;();

	foreach (string i in raw.Split(itemSep))
	{
		string item = i.Trim();

		string[] value = item.Split(valueSep);
		value[0] = value[0].Trim();
		value[1] = value[1].Trim();

		if (!dict.ContainsKey(value[0]))
		{
			dict.Add(value[0], ToDateTime(value[1]));
		}
	}

	return dict;
}

public static Dictionary&lt;string, DateTime&gt; GetAsDateTimeDict(string key)
{
	return GetAsDateTimeDict(key, ';', '|');
}
</pre>
<h3>¡Hemos terminado!</h3>
<p>Ahora ya tenemos una clase que, además de ser fácilmente utilizable desde cualquier parte del programa, nos proporciona los valores de AppSettings en el formato que necesitemos. Además hemos extendido la funcionalidad respecto al api de asp.Net por que también es capaz de obtener los datos en forma de listas y diccionarios.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.juanmasantoyo.es/index.php/2010/02/08/clase-para-acceso-avanzado-a-las-appsettings-del-webconfig/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

