<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-6494419861240446187</id><updated>2012-01-30T02:31:54.745-08:00</updated><category term='Ingeniería de software'/><category term='Redes'/><category term='Lenguajes .NET'/><category term='Windows'/><category term='Linux'/><title type='text'>Programación .NET y Cisco en la consola.</title><subtitle type='html'>Tutoriales y código acerca de la plataforma .NET y de Redes con Cisco</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://xomalli.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://xomalli.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Martín Márquez</name><uri>http://www.blogger.com/profile/10939957618126542300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_j4WRR9G9bfY/SV2_nw3UxeI/AAAAAAAAAAM/nT3SYp94IHo/s1600-R/photo.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>55</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-6494419861240446187.post-1005959977362143214</id><published>2012-01-30T00:58:00.000-08:00</published><updated>2012-01-30T02:31:54.798-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Redes'/><title type='text'>Subnetting en redes IPV4 parte II, IPv4 de los números de hosts</title><content type='html'>&lt;p align="justify"&gt;Para sacar los números de host en una red con subneteo utilizamos los bits del último octeto, aquellos que no hayan sido utilizados para la subnet, por lo tanto estos bits serán utilizados para el número total de hosts.&lt;/p&gt;&lt;br /&gt;&lt;p align="justify"&gt;Por ejemplo de la subred &lt;i&gt;130.3.12.128&lt;/i&gt; necesitamos encontrar la IP número &lt;i&gt;20&lt;/i&gt; o bien la vigésima IP de esa subred, bien la configuración de los octetos para esta subred se encuentran de la siguiente forma:&lt;/p&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/subnet/subnet6.png" /&gt;&lt;/div&gt;&lt;br /&gt;&lt;p align="justify"&gt;Bien en el último octeto entonces buscaremos el número 20 de acuerdo con los valores en decimal de los bits. Por lo que la configuración en el último octeto quedaría con los siguientes bits encendidos de acuerdo a su representación numérica.&lt;/p&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/subnet/subnet7.png" /&gt;&lt;/div&gt;&lt;br /&gt;&lt;p align="justify"&gt;Se realiza la suma decimal de los tres bits encendidos en el último octeto, dos de ellos representando el número de IP más el bit encendido del campo de subred.&lt;br /&gt;&lt;br /&gt;&lt;tt&gt;128 + 16 + 4 = 148&lt;/tt&gt;&lt;br /&gt;&lt;br /&gt;Por lo que la vigésima IP de la subred &lt;i&gt;130.3.12.128&lt;/i&gt; sería entonces la &lt;br /&gt;&lt;br /&gt;&lt;tt&gt;130.3.12.148&lt;/tt&gt;&lt;br /&gt;&lt;br /&gt;Veamos ahora un segundo ejemplo, buscamos la última IP de host en la subred &lt;i&gt;400&lt;/i&gt; de la red &lt;i&gt;130.3.0.0/25&lt;/i&gt;, por lo que la configuración de los octetos de esta subred queda de la siguiente forma:&lt;/p&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/subnet/subnet8.png" /&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;Sumando la representación decimal de los bits encendidos del tercer octeto tenemos entonces:&lt;br /&gt;&lt;br /&gt;&lt;tt&gt;128 + 64 + 8 = 200&lt;/tt&gt;&lt;br /&gt;&lt;br /&gt;Por lo que la IP para subred &lt;i&gt;400&lt;/i&gt; es: &lt;i&gt;130.3.200.0&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;Ahora vamos a utilizar el último octeto para obtener la última IP de esta subred, sabemos bien que la configuración para todos los hosts de esta subred es poniendo todos los bits encendidos excepto el del último octeto el cual representaría la IP del Gateway.&lt;br /&gt;Por lo que la configuración del último host de esta subred en el último octeto queda de la siguiente forma:&lt;/p&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/subnet/subnet9.png" /&gt;&lt;/div&gt;&lt;br /&gt;&lt;p align="justify"&gt;Sumando su representación decimal&lt;br /&gt;&lt;br /&gt;&lt;tt&gt;64 + 32 + 16 + 8 + 4 + 2 = 126&lt;/tt&gt;&lt;br /&gt;&lt;br /&gt;Por lo que la IP para el último host de la subred 400 es: &lt;tt&gt;130.3.200.126&lt;/tt&gt;&lt;/p&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/subnet/subnet10.png" /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6494419861240446187-1005959977362143214?l=xomalli.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/1005959977362143214'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/1005959977362143214'/><link rel='alternate' type='text/html' href='http://xomalli.blogspot.com/2012/01/subnetting-en-redes-ipv4-parte-ii-la.html' title='Subnetting en redes IPV4 parte II, IPv4 de los números de hosts'/><author><name>Martín Márquez</name><uri>http://www.blogger.com/profile/10939957618126542300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_j4WRR9G9bfY/SV2_nw3UxeI/AAAAAAAAAAM/nT3SYp94IHo/s1600-R/photo.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-6494419861240446187.post-4256887716736972567</id><published>2011-12-31T17:52:00.000-08:00</published><updated>2012-01-15T04:36:17.984-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Redes'/><title type='text'>Subnetting en redes IP v4 Parte I</title><content type='html'>&lt;p align="justify"&gt;Una  dirección IPv4 (IPv4 address) tiene una longitud de 32 bits que se considera única para cada host, esta dirección se escribe en formato binario de izquierda a derecha donde se considera que el bit más significativo es el bit más hacia la izquierda, una IPv4 tiene dos partes, la parte de red (netid) y la parte de host (hostid), originalmente el espacio de direcciones IP fue dividido en tres clases diferentes clase A, clase B y clase C, cada clase se distingue por los primeros bits iniciales o bits de prefijo, como en la siguiente tabla:&lt;/p&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/subnet/subnet1.png" /&gt;&lt;/div&gt;&lt;br/&gt;&lt;br /&gt;&lt;p align="justify"&gt;La clase A tiene bit de prefijo en 0 y es seguido por 7 bits para la parte de red y 24 bits restantes para la parte de host, la clase B tiene dos bits de prefijo el primero en 1 y el segundo en 0 seguido de 14 bits para la parte de red y de 16 bits para la parte de host, la clase C tiene tres bits de prefijo el primero y el segundo en 1 y el tercero en 0 por lo que tiene 21 bits para la parte de red y 8 bits para la parte de host, existen también las clases D y E las cuales se usa para multicasting y para experimentación respectivamente.&lt;br/&gt;&lt;br /&gt;En un principio este esquema pareció ser suficiente para el tamaño de las redes, pero conforme la Internet fue creciendo en número de redes y hosts, este esquema presento deficiencias, una de ellas fue el desperdicio y el agotamiento de direcciones, por lo que una de las soluciones a este problema fue el concepto de subneteo (subnetting) el cual nos permite tomar una dirección de red y crear subconjuntos de esa red o bien subredes esto se logra mediante los siguientes pasos:&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Por ejemplo si se nos pide subneteo en una red clase B y se nos da un mascara de 27 bits, la clase B tiene 16 bits para el campo de red y 16 bits para el campo de host.&lt;br /&gt;Se resta el número de mascara menos el número de bits del campo de red y el resultado es el número de bits que debemos de tomar de los octetos del campo de host.&lt;br /&gt;En este caso:&lt;/p&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/subnet/subnet2.png" /&gt;&lt;/div&gt;&lt;br/&gt;&lt;br /&gt;&lt;p align="justify"&gt;Se utilizan los 11 bits para el subneteo y los 5 bits restantes se utilizan para el campo de host. Por lo que quedaría de la siguiente forma:&lt;/p&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/subnet/subnet2a.png" /&gt;&lt;/div&gt;&lt;br/&gt;&lt;br /&gt;&lt;p align="justify"&gt;Bien ahora que ya tenemos identificados los bits de subred, vamos a poner en práctica como lo obtenemos las subredes en forma decimal.&lt;br/&gt;&lt;br /&gt;Supongamos que tenemos una red 130.3.0.0 con una subnet mask de 25 o &lt;i&gt;130.3.0.0/25&lt;/i&gt;&lt;/p&gt;&lt;br /&gt;&lt;p align="justify"&gt;Si necesitamos encontrar los números de subredes: 25 y 400 respectivamente por lo que en principio calculamos el número de bits que necesitaremos para la subred por lo que hacemos la resta:&lt;br/&gt;&lt;br /&gt;&lt;i&gt;25-16 = 9 bits para subneteo&lt;/i&gt;&lt;br/&gt;&lt;br /&gt;Esquematizamos los octetos de la red &lt;i&gt;130.3.0.0/25&lt;/i&gt;, para una mejor comprensión:&lt;/p&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/subnet/subnet3.png" /&gt;&lt;/div&gt;&lt;br/&gt;&lt;br /&gt;&lt;p align="justify"&gt;En la parte inferior entre el tercero y el cuarto octeto vemos en color verde el número de subredes correspondientes a cada bit de la parte de subred, para la representación del valor en decimal utilizamos los valores de la parte superior, por lo que la suma de cada bit encedido en la parte inferior nos proporcione como resultado el número de subred  y la suma de sus valores en la parte superior nos proporcione la representación decimal , así por ejemplo la subred número 25 será:&lt;/p&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/subnet/subnet4.png" /&gt;&lt;/div&gt;&lt;br/&gt;&lt;br /&gt;&lt;p align="justify"&gt;Hay que distinguir que para el número de subred sumamos los valores que nos den como resultado el número de subred que buscamos, sin importar que se encuentren en diferentes  octetos y que para la parte decimal su representación es únicamente la suma de  los valores de los bits que componen ese octeto.&lt;br/&gt;&lt;br /&gt;Encendemos los valores de subred del tercer octeto en 16 y 8 y el valor de 1 del cuarto octeto para que la suma de sus valores de subred tengamos el número de 25.&lt;br/&gt;&lt;br /&gt;&lt;i&gt;16 + 8 + 1 = 25&lt;/i&gt;&lt;br /&gt;Ahora entonces sumamos la parte superior del tercer octeto para obtener su representación decimal en este caso:&lt;br/&gt;&lt;br /&gt;&lt;i&gt;8 + 4 = 12&lt;/i&gt;&lt;br /&gt;Y para el último octeto la representación decimal del bit encendido nos da 128, por lo que juntando todos los octetos obtenemos que la subred 25 se represente por la dirección Ipv4:&lt;br/&gt;&lt;br /&gt;&lt;i&gt;130.3.12.128 / 25&lt;/i&gt;&lt;br /&gt;Ahora buscamos la representación decimal de la subred 400 utilizando el mismo método&lt;/p&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/subnet/subnet5.png" /&gt;&lt;/div&gt;&lt;br/&gt;&lt;br /&gt;&lt;p align="justify"&gt;En este caso como es un número par de subred, inferimos que el último octeto no tendrá valor por lo que nos concentramos en los bits del tercer octeto, prendemos el bit de subred 256, el bit 128 y por último el bit 16 de la suma obtenemos los bits de la subred 400.&lt;br/&gt;&lt;br /&gt;&lt;i&gt;256 + 128 + 16 = 400&lt;/i&gt;&lt;br /&gt;Ahora obtenemos la representación decimal de los bits prendidos en el tercer octeto.&lt;br/&gt;&lt;br /&gt;&lt;i&gt;128 + 64 + 8 = 200&lt;/i&gt;&lt;br /&gt;La subred 400 queda representada en formato decimal como:&lt;br/&gt;&lt;br /&gt;&lt;i&gt;130.3.200.0/25&lt;/i&gt;&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6494419861240446187-4256887716736972567?l=xomalli.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/4256887716736972567'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/4256887716736972567'/><link rel='alternate' type='text/html' href='http://xomalli.blogspot.com/2011/12/subnetting-en-redes-ip-v4-parte-i.html' title='Subnetting en redes IP v4 Parte I'/><author><name>Martín Márquez</name><uri>http://www.blogger.com/profile/10939957618126542300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_j4WRR9G9bfY/SV2_nw3UxeI/AAAAAAAAAAM/nT3SYp94IHo/s1600-R/photo.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-6494419861240446187.post-1900530856830504755</id><published>2011-12-27T20:19:00.000-08:00</published><updated>2011-12-28T10:43:21.716-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><title type='text'>Entendiendo Satellite Assemblies usando MonoDevelop - (parte 2)</title><content type='html'>&lt;p align="justify"&gt;En la &lt;a href="http://xomalli.blogspot.com/2011/12/entendiendo-satellite-assemblies-usando.html"&gt;primera parte&lt;/a&gt; de este tutorial, se mostró como crear Satellite Assemblies, ahora en este segunda parte se mostrará un listado donde se muestra el código que nos mostrará los pasos de como consumir los ensamblados satélite o ensamblados de recursos desde una aplicación GTK#.&lt;/p&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;using System;&lt;br /&gt;using Gtk;&lt;br /&gt;using System.IO;&lt;br /&gt;using System.Resources;&lt;br /&gt;using Gdk;&lt;br /&gt;using System.Reflection;&lt;br /&gt;&lt;br /&gt;namespace TestResource&lt;br /&gt;{&lt;br /&gt;class MainClass : Gtk.Window&lt;br /&gt;{&lt;br /&gt;DrawingArea darea = null;&lt;br /&gt;Label label1 = null;&lt;br /&gt;Button btnLoad = null;&lt;br /&gt;Pixmap pixmap;&lt;br /&gt;Pixbuf pngbuf;&lt;br /&gt;public MainClass():base("Test Resources"){&lt;br /&gt;BorderWidth = 8;&lt;br /&gt;this.DeleteEvent += new DeleteEventHandler(OnWindowDelete);&lt;br /&gt;Frame frame = new Frame("Load");&lt;br /&gt;Add(frame);&lt;br /&gt;VBox MainPanel = new VBox (false, 8);&lt;br /&gt;label1 = new Label("Query is: ");&lt;br /&gt;darea = new DrawingArea();&lt;br /&gt;btnLoad = new Button("Load resources");&lt;br /&gt;btnLoad.Clicked += AddResource_Clicked;&lt;br /&gt;darea.SetSizeRequest (200, 200);&lt;br /&gt;darea.ExposeEvent += Expose_Event;&lt;br /&gt;darea.ConfigureEvent += Configure_Event;&lt;br /&gt;MainPanel.Add(label1);&lt;br /&gt;MainPanel.PackStart(darea);&lt;br /&gt;MainPanel.Add(btnLoad);&lt;br /&gt;frame.Add (MainPanel);&lt;br /&gt;SetDefaultSize (320, 233);&lt;br /&gt;Resizable = false;&lt;br /&gt;ShowAll();&lt;br /&gt;}&lt;br /&gt;public void OnWindowDelete(object o, DeleteEventArgs args) {&lt;br /&gt;Application.Quit(); }&lt;br /&gt;  &lt;br /&gt;public static void Main (string[] args)&lt;br /&gt;{&lt;br /&gt;Application.Init();&lt;br /&gt;new MainClass();&lt;br /&gt;Application.Run();&lt;br /&gt;}&lt;br /&gt;  &lt;br /&gt;void PlacePixbuf (Gdk.Pixbuf buf)&lt;br /&gt;{&lt;br /&gt;pixmap.DrawPixbuf (darea.Style.BlackGC,buf, 0, 0, 0, 0,buf.Width,&lt;br /&gt;buf.Height,RgbDither.None, 0, 0);&lt;br /&gt;darea.QueueDrawArea (0, 0, buf.Width, buf.Height);&lt;br /&gt;}&lt;br /&gt;  &lt;br /&gt;void LoadResources(){&lt;br /&gt;try{&lt;br /&gt;//find the assembly&lt;br /&gt;string assem = "demo.resources.dll";&lt;br /&gt;Assembly assembly = Assembly.LoadFrom(assem);&lt;br /&gt;if(File.Exists(assem))&lt;br /&gt;{&lt;br /&gt; //Instance for resourcemanager&lt;br /&gt;ResourceManager rm = new ResourceManager("demo",assembly);&lt;br /&gt; //get the string for the resource&lt;br /&gt;label1.Text += rm.GetString("query1"); &lt;br /&gt; //get the image for the resource&lt;br /&gt;System.Drawing.Bitmap bitmap = (System.Drawing.Bitmap)rm.GetObject("pugme");&lt;br /&gt;bitmap.Save("pugme.png",System.Drawing.Imaging.ImageFormat.Png);&lt;br /&gt;pngbuf = new Pixbuf("pugme.png");&lt;br /&gt;}&lt;br /&gt;}catch(Exception e){&lt;br /&gt;Console.WriteLine(e.Message);&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;  &lt;br /&gt;void Configure_Event (object obj, ConfigureEventArgs args)&lt;br /&gt;{&lt;br /&gt;Gdk.EventConfigure ev = args.Event;&lt;br /&gt;Gdk.Window window = ev.Window;&lt;br /&gt;Gdk.Rectangle allocation = darea.Allocation;&lt;br /&gt;pixmap = new Gdk.Pixmap (window, allocation.Width,allocation.Height, -1);&lt;br /&gt;pixmap.DrawRectangle (darea.Style.WhiteGC, true, 0, 0,allocation.Width,&lt;br /&gt;allocation.Height);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;void Expose_Event (object obj, ExposeEventArgs args)&lt;br /&gt;{&lt;br /&gt;Gdk.Rectangle area = args.Event.Area;&lt;br /&gt;args.Event.Window.DrawDrawable (darea.Style.WhiteGC, &lt;br /&gt;pixmap,area.X, area.Y,area.X, area.Y,area.Width, area.Height);&lt;br /&gt;}&lt;br /&gt;  &lt;br /&gt;void AddResource_Clicked (object obj, EventArgs args)&lt;br /&gt;{&lt;br /&gt;LoadResources();&lt;br /&gt;PlacePixbuf (pngbuf);&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p align="justify"&gt;Toda esta funcionalidad se encuentra en el método &lt;tt&gt;LoadResources()&lt;/tt&gt; , este método comienza primeramente con la carga en tiempo de ejecución del ensamblado que contiene los recursos utilizando las líneas siguientes:&lt;/p&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;string assem = "demo.resources.dll";&lt;br /&gt;Assembly assembly = Assembly.LoadFrom(assem);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p align="justify"&gt;A continuación creamos una instancia de la clase &lt;a href="http://msdn.microsoft.com/en-us/library/system.resources.resourcemanager.aspx"&gt;ResourceManager&lt;/a&gt; en la cual se encuentran los métodos para obtener los recursos del ensamblado, en este ejemplo obtenemos un recurso de tipo cadena y otro de tipo imagen, con el código de las líneas siguientes&lt;/p&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;label1.Text += rm.GetString("query1"); &lt;br /&gt;System.Drawing.Bitmap bitmap = (System.Drawing.Bitmap)rm.GetObject("pugme");&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p align="justify"&gt;Por último únicamente se guarda la imagen en el directorio de la aplicación para crear un objeto &lt;i&gt;Pixbuf&lt;/i&gt; el cual se dibujará en un control &lt;i&gt;DrawingArea&lt;/i&gt;, esto ocurre en las siguientes líneas: &lt;/p&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;bitmap.Save("pugme.png",System.Drawing.Imaging.ImageFormat.Png);&lt;br /&gt;pngbuf = new Pixbuf("pugme.png");&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p align="justify"&gt;Los métodos presentados por este programa en GTK# aplican para cualquier otra aplicación .NET incluso si el lenguaje de programación utilizado no es C#.&lt;br /&gt;&lt;br /&gt;Compilamos la aplicación y ejecutamos la aplicación con los siguientes comandos desde una terminal:&lt;/p&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;tt&gt;$ mcs –pkg:gtk-sharp-2.0 –r:System.Drawing Main.cs&lt;/tt&gt;&lt;br /&gt;&lt;tt&gt;$ mono Main.exe&lt;/tt&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/monores2/testres3.png" /&gt;&lt;/div&gt;&lt;br&gt;&lt;br /&gt;&lt;div&gt;Al ejecutar la aplicación se mostrará como en la siguiente imagen:&lt;/div&gt;&lt;br&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/monores2/testres1.png" /&gt;&lt;/div&gt;&lt;br /&gt;&lt;p align="justify"&gt;Al presionar el botón &lt;i&gt;Load resources&lt;/i&gt; deberán de cargarse los recursos de cadena e imagen respectivamente, antes de ejecutar la aplicación es importante verificar que el ensamblado &lt;i&gt;demo.resources.dll&lt;/i&gt; se encuentre en el mismo directorio de la aplicación.&lt;br /&gt;&lt;br /&gt;El resultado final se mostrará como en la siguiente imagen:&lt;/p&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/monores2/testres2.png" /&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;Parte del código de este programa se derivo del ejemplo 4-8 del capítulo 4 del libro &lt;a href="http://books.google.com.mx/books/about/Mono.html?id=HyszoedfP3MC&amp;redir_esc=y"&gt;Mono: A Developer's Notebook&lt;/a&gt; de Niel M. Bornstein y Edd Dumbill&lt;/p&gt;&lt;br /&gt;&lt;h3&gt;&lt;a href="http://www.humansharp.com/Code/TestResource.zip"&gt;&lt;img src="http://www.humansharp.com/picture_library/dw.jpg" border="0"&gt;Descarga el código fuente&lt;/a&gt;&lt;/h3&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6494419861240446187-1900530856830504755?l=xomalli.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/1900530856830504755'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/1900530856830504755'/><link rel='alternate' type='text/html' href='http://xomalli.blogspot.com/2011/12/entendiendo-satellite-assemblies-usando_27.html' title='Entendiendo Satellite Assemblies usando MonoDevelop - (parte 2)'/><author><name>Martín Márquez</name><uri>http://www.blogger.com/profile/10939957618126542300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_j4WRR9G9bfY/SV2_nw3UxeI/AAAAAAAAAAM/nT3SYp94IHo/s1600-R/photo.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-6494419861240446187.post-4489791457115589970</id><published>2011-12-25T23:30:00.000-08:00</published><updated>2011-12-26T01:37:49.663-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><title type='text'>Entendiendo Satellite Assemblies usando MonoDevelop - (parte 1)</title><content type='html'>&lt;p align="justify"&gt;Una de las características más atractivas que .NET ofrece para el desarrollo de software es la capacidad de crear componentes en diferentes lenguajes de programación, esto es posible por que el objetivo de cada compilador existente para .NET es producir un assembly (ensamblado) el cual por definición es: La unidad funcional de distribución, versionamiento y de identidad de la plataforma .NET.&lt;br&gt;&lt;br /&gt;Además de clasificar los assemblies en Strong-Named o privados dependiendo de su instalación o en Single-File y Multi-File si contienen un archivo o varios, pueden también clasificarse en base a su contenido en donde tenemos a los ensamblados que contienen código MSIL y recursos (imágenes, traducciones o archivos de texto, etc) y a los Satellite assemblies (ensamblados satélite) que únicamente contienen recursos.&lt;br&gt;&lt;br /&gt;Para estos últimos ensamblados existen herramientas como Visual Studio o SharpDevelop que nos permiten hacerlo de forma automática, aunque también existe la opción de hacerlo de forma programática con las clases contenidas en el namespace &lt;i&gt;System.Resources.&lt;/i&gt;&lt;/p&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;b&gt;ResourceManager:&lt;/b&gt; Permite tener acceso a los archivos de recursos de forma programática.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;b&gt;ResourceReader:&lt;/b&gt; Lee los archivos binarios de recursos.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;b&gt;ResourceWriter:&lt;/b&gt; Escribe los archivos binarios de recursos.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;b&gt;ResXResourceReader:&lt;/b&gt; Lee los archivos XML de recursos.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;b&gt;ResXResourceWriter:&lt;/b&gt; Escribe los archivos XML de recursos.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;p align="justify"&gt;En el siguiente programa mostramos el uso de la clase &lt;a href="http://msdn.microsoft.com/en-us/library/system.resources.resourcewriter.aspx"&gt;ResourceWriter&lt;/a&gt; para crear un satellite asembly. Abrimos MonoDevelop y creamos una solución GTK#, utilizando el diseñador de la interfaz gráfica, creamos una GUI similar a como se muestra en la siguiente imagen:&lt;/p&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/monres1/mnresource1.png" /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br&gt;&lt;br /&gt;&lt;p align="justify"&gt;Construimos un manejador de evento para cada uno de los botones de manera que el código de la clase se vea como en el siguiente listado.&lt;/p&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;using System;&lt;br /&gt;using Gtk;&lt;br /&gt;using System.Resources;&lt;br /&gt;using System.Collections;&lt;br /&gt;using System.Drawing;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;public partial class MainWindow: Gtk.Window&lt;br /&gt;{       &lt;br /&gt;//This class as a global variable&lt;br /&gt;ResourceWriter rw = null;&lt;br /&gt;Hashtable _values = new Hashtable();&lt;br /&gt;Hashtable _imgValues = new Hashtable();&lt;br /&gt;public MainWindow (): base (Gtk.WindowType.Toplevel)&lt;br /&gt;{&lt;br /&gt;Build ();&lt;br /&gt;}&lt;br /&gt;        &lt;br /&gt;protected void OnDeleteEvent (object sender, DeleteEventArgs a)&lt;br /&gt;{&lt;br /&gt;Application.Quit ();&lt;br /&gt;a.RetVal = true;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;protected void OnBtnAddClicked (object sender, System.EventArgs e)&lt;br /&gt;{&lt;br /&gt;//we add values, if they have values&lt;br /&gt;if(!string.IsNullOrEmpty(txtName.Text) &amp;&amp;&lt;br /&gt;!string.IsNullOrEmpty(txtValue.Text))&lt;br /&gt;{&lt;br /&gt;if(chkIsImage.Active)&lt;br /&gt;        _imgValues.Add(txtName.Text,txtValue.Text);&lt;br /&gt;else&lt;br /&gt;        _values.Add (txtName.Text,txtValue.Text);&lt;br /&gt;lbMsg.Text = "Item added";&lt;br /&gt;Clear(false);&lt;br /&gt;}&lt;br /&gt;else&lt;br /&gt;lbError.Text = "Null values";                    &lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;protected void OnBtnBuildClicked (object sender, System.EventArgs e)&lt;br /&gt;{&lt;br /&gt;try&lt;br /&gt;{&lt;br /&gt;//Ok, we create the Object&lt;br /&gt;using(rw = new ResourceWriter("demo.resources")){&lt;br /&gt;//iterate for the strings&lt;br /&gt;foreach(DictionaryEntry entry in _values)&lt;br /&gt;rw.AddResource(entry.Key.ToString(),entry.Value.ToString());&lt;br /&gt;//iterate for the images&lt;br /&gt;foreach(DictionaryEntry entry in _imgValues)&lt;br /&gt;rw.AddResource(entry.Key.ToString(),new Bitmap(entry.Value.ToString()));&lt;br /&gt;//Generate&lt;br /&gt;rw.Generate();&lt;br /&gt;Clear(true);&lt;br /&gt;lbError.Text = string.Empty;&lt;br /&gt;lbMsg.Text = "Resources file generated";&lt;br /&gt;}&lt;br /&gt;}catch(Exception ex){&lt;br /&gt;        lbMsg.Text = string.Empty;&lt;br /&gt;        lbError.Text = ex.Message;&lt;br /&gt;}                              &lt;br /&gt;}&lt;br /&gt;        &lt;br /&gt;void Clear(bool clearMsg)&lt;br /&gt;{&lt;br /&gt;txtName.Text = txtValue.Text = string.Empty;&lt;br /&gt;chkIsImage.Active = false;&lt;br /&gt;if(clearMsg)&lt;br /&gt;        lbMsg.Text = string.Empty;&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p align="justify"&gt;&lt;br /&gt;Al compilar y ejecutar el programa podemos ingresar uno a uno el nombre y el valor de la cadena o del archivo de imagen que contendrá nuestro archivo de recursos, en caso de las imágenes debemos habilitar el checkbox “Is image” además de que el archivo de imagen debe encontrarse físicamente en el mismo directorio que el programa, en las siguientes imágenes introduciremos un par de valores de prueba.&lt;/p&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/monres1/mnresource2.png" /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/monres1/mnresource3.png" /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br&gt;&lt;br /&gt;&lt;p align="justify"&gt;Después de ingresar el par de valores podemos generar físicamente el archivo de recursos con el botón &lt;i&gt;“Build Resource”&lt;/i&gt;, como en la siguiente imagen:&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/monres1/mnresource4.png" /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br&gt;&lt;br /&gt;La funcionalidad del botón &lt;i&gt;“Build Resource”&lt;/i&gt; es crear una instancia de la clase &lt;i&gt;ResourceWriter&lt;/i&gt;.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;rw = new ResourceWriter("demo.resources")&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Para después iterar en los valores de cada Hashtable,primero en el Hashtable de las cadenas en la cual utilizara el siguientel metodo:&lt;/p&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;rw.AddResource(entry.Key.ToString(),entry.Value.ToString());&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p align="justify"&gt;A continuación itera en el Hastable de las imágenes en donde utiliza el método anterior salvo con la diferencia de convertir el valor en un objeto &lt;a href="http://msdn.microsoft.com/en-us/library/system.drawing.bitmap.aspx"&gt;Bitmap.&lt;/a&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;rw.AddResource(entry.Key.ToString(),new Bitmap(entry.Value.ToString()));&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Por último se utiliza el siguiente método:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;rw.Generate();&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Para crear físicamente el archivo “demo.resources” el cuál se creará en el mismo directorio donde se ejecuta el programa, como en la siguiente imagen:&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/monres1/monresources5.png" /&gt;&lt;/div&gt;&lt;br /&gt;&lt;p align="justify"&gt;&lt;br /&gt;Ahora solo falta crear el Satellite Assembly, esto puede lograrse con el compilador de .NET o bien con el &lt;tt&gt;Assembly Linker&lt;/tt&gt;, para este tutorial utilizaremos el &lt;tt&gt;Assembly Linker&lt;/tt&gt;, la instrucción para crear el ensamblado es la siguiente:&lt;/p&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$ al /embed:demo.resources /out:demo.resources.dll&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p align="justify"&gt;Utilizamos la opción &lt;tt&gt;/embed&lt;/tt&gt; para incrustar el recurso en el ensamblado y la opción /out para nombrar al ensamblado resultado, este comando lo ejecutamos desde una terminal de consola como en la siguiente imagen:&lt;/p&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/monres1/monresources6.png" /&gt;&lt;/div&gt;&lt;br /&gt;&lt;p align="justify"&gt;Podemos observar que ahora el archivo &lt;i&gt;mono.resources.dll&lt;/i&gt; es un ensamblado .NET válido  mediante la herramienta MonoDis mediante el comando:&lt;/p&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$ monodis mono.resources.dll&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;Veremos el contenido del ensamblado, como se muestra en la siguiente imagen:&lt;/p&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/monres1/monresources7.png" /&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;Ahora ya tenemos listo el Satellite Assembly para que sea consumido por cualquier otra aplicación en .NET en la segunda parte mostraremos una aplicación para acceder al contenido del ensamblado.&lt;/p&gt;&lt;br /&gt;&lt;h3&gt;&lt;a href="http://www.humansharp.com/Code/MonResources.zip"&gt;&lt;img src="http://www.humansharp.com/picture_library/dw.jpg" border="0"&gt;Descarga el proyecto para MonoDevelop&lt;/a&gt;&lt;/h3&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6494419861240446187-4489791457115589970?l=xomalli.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/4489791457115589970'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/4489791457115589970'/><link rel='alternate' type='text/html' href='http://xomalli.blogspot.com/2011/12/entendiendo-satellite-assemblies-usando.html' title='Entendiendo Satellite Assemblies usando MonoDevelop - (parte 1)'/><author><name>Martín Márquez</name><uri>http://www.blogger.com/profile/10939957618126542300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_j4WRR9G9bfY/SV2_nw3UxeI/AAAAAAAAAAM/nT3SYp94IHo/s1600-R/photo.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-6494419861240446187.post-5464150310212755633</id><published>2011-11-17T20:16:00.000-08:00</published><updated>2011-11-17T20:58:36.184-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><title type='text'>Regular Expressions  con C#</title><content type='html'>&lt;p align="justify"&gt;Las expresiones regulares (regular expressions) han sido utilizadas con éxito desde hace tiempo como una  solución avanzada mucho más compleja y eficiente para el procesamiento y la validación de texto en herramientas como grep, sed, AWK, bash y en lenguajes de programación del tipo scripting como Perl, Python y PHP.&lt;/p&gt;&lt;br /&gt;&lt;p align="justify"&gt;Una expresión regular (regular expression o regexp) es un patrón de cadenas de caracteres formado por una combinación de caracteres especiales llamados metacaracteres o cuantificadores y de caracteres alfanuméricos llamados literales, este patrón representa un lenguaje regular o un conjunto regular de cadenas para tres operaciones básicas: adyacencia, repetición y alteración.&lt;/p&gt;&lt;br /&gt;&lt;p align="justify"&gt;En el sitio &lt;a href="http://www.regular-expressions.info/"&gt;http://www.regular-expressions.info/&lt;/a&gt; se da una mayor referencia acerca de los cuantificadores y su significado.&lt;/p&gt;&lt;br /&gt;&lt;p align="justify"&gt;Existen dos implementaciones de expresiones regulares POSIX y PERL, en el caso de  .NET el motor de expresiones regulares utiliza la implementación compatible con Perl 5.&lt;br /&gt;Las expresiones regulares en .NET se encuentran integradas como clases dentro del ensamblado System.Text.RegularExpressions estas clases utilizan un motor implementado como un autómata finito no determinístico (NFA) similar al que emplean Perl, Python y Emacs con algunas características propias de .NET.&lt;/p&gt;&lt;br /&gt;&lt;p align="justify"&gt;Para ejemplificar el uso de expresiones regulares en C#, mostraremos un programa sencillo que tenga una funcionalidad similar al comando grep o egrep, como sabemos este comando en su funcionamiento básico recibe como argumentos una expresión regular y uno o varios archivos en donde buscar e imprime las líneas que coincidan con esa expresión regular.&lt;br /&gt;El código del programa es el siguiente:&lt;/p&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;using System;&lt;br /&gt;using System.Text;&lt;br /&gt;using System.Text.RegularExpressions;&lt;br /&gt;using System.IO;&lt;br /&gt;&lt;br /&gt;namespace TestGrep&lt;br /&gt;{&lt;br /&gt;class MainClass&lt;br /&gt;{&lt;br /&gt;public static void Main (string[] args)&lt;br /&gt;{&lt;br /&gt;if(args.Length == 2){&lt;br /&gt;    string pattern = args[0];&lt;br /&gt; string file = args[1];&lt;br /&gt; Regex regexp = new Regex(@pattern,RegexOptions.Multiline);&lt;br /&gt; FileInfo fi = new FileInfo(file);&lt;br /&gt; if(File.Exists(fi.FullName))&lt;br /&gt; {&lt;br /&gt;  using(StreamReader sr = new StreamReader(file)){&lt;br /&gt;   string line;&lt;br /&gt;   while((line = sr.ReadLine())!= null){&lt;br /&gt;    Match m = regexp.Match(line);&lt;br /&gt;    if(m.Success)&lt;br /&gt;    Console.WriteLine("{0}",line);&lt;br /&gt;   }&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt; else&lt;br /&gt;  Console.WriteLine("File not found");&lt;br /&gt;}else&lt;br /&gt;Console.WriteLine("Usage: mono TestGrep [pattern] [file]");&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;Al ejecutar el programa podemos observar el resultado como se muestra en las siguientes imágenes probando con diferentes patrones con los archivos etc/password y /etc/group respectivamente.&lt;/p&gt;&lt;br /&gt;&lt;span&gt;&lt;b&gt;Probando con el archivo &lt;tt&gt;/etc/password&lt;/tt&gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/RegExp/fig1.png"&gt;&lt;/div&gt;&lt;br&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/RegExp/fig2.png"&gt;&lt;/div&gt;&lt;br&gt;&lt;br /&gt;&lt;span&gt;&lt;b&gt;Probando con el archivo &lt;tt&gt;/etc/group&lt;/tt&gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/RegExp/fig3.png"&gt;&lt;/div&gt;&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6494419861240446187-5464150310212755633?l=xomalli.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/5464150310212755633'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/5464150310212755633'/><link rel='alternate' type='text/html' href='http://xomalli.blogspot.com/2011/11/regular-expressions-con-c.html' title='Regular Expressions  con C#'/><author><name>Martín Márquez</name><uri>http://www.blogger.com/profile/10939957618126542300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_j4WRR9G9bfY/SV2_nw3UxeI/AAAAAAAAAAM/nT3SYp94IHo/s1600-R/photo.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-6494419861240446187.post-8031014659248503100</id><published>2011-11-12T19:36:00.000-08:00</published><updated>2011-11-15T22:12:30.451-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Lenguajes .NET'/><title type='text'>Utilizando JavaScript  desde código ASP.NET</title><content type='html'>&lt;p align="justify"&gt;Actualmente es difícil construir  una aplicación ASP.NET que no haga uso de las capacidades de JavaScript para realizar operaciones del lado del cliente o browser, operaciones que si fueran desarrolladas en su totalidad con la arquitectura ASP.NET serian  demasiado costosas,  basta recordar que ASP.NET es una arquitectura totalmente hecha para su uso del lado del servidor, por lo que hace uso de un mecanismo de Postback o de ida y vuelta entre los datos de la página solicitada por el cliente y por el servidor que proporciono la página, por lo que el mecanismo de &lt;i&gt;Postback&lt;/i&gt; hace uso de uno de los recursos más valiosos de una red: &lt;b&gt;el ancho de banda.&lt;/b&gt;&lt;/p&gt;&lt;br /&gt;&lt;p align="justify"&gt;Durante ese viaje pueden ocurrir eventos que retarden o interrumpan la respuesta del servidor, causando una pérdida o una retrasmisión de los datos por parte del usuario resultando en una forma ineficiente de comunicación ya que ASP.NET reconstruye la página completa con todo su contenido en cada solicitud.&lt;br /&gt;Para ayudar a no utilizar con frecuencia este mecanismo, hay que utilizar JavaScript en el cliente o browser como un complemento a las operaciones ASP.NET. Para utilizar JavaScript junto a  ASP .NET, existe la clase &lt;a href="http://msdn.microsoft.com/en-US/library/system.web.ui.clientscriptmanager_members %28v=VS.80%29.aspx"&gt;ClientScriptManager&lt;/a&gt; la cual se programa mediante la propiedad &lt;tt&gt;ClientScript&lt;/tt&gt; de la clase &lt;tt&gt;Page&lt;/tt&gt;, la cual expone métodos que permiten incrustar código JavaScript dentro de la página ASP.NET.&lt;br /&gt;Los métodos más comunes usados de esta clase son:&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;RegisterClientScriptBlock: Incrusta el código JavaScript al inicio del formulario después de la etiqueta &amp;lt;form&amp;gt;, genera dinámicamente el código JavaScript desde una cadena.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;RegisterStartupScript: Incrusta el código JavaScript en el final de la página,  antes del cierre del formulario o sea antes del cierre de la etiqueta &lt;tt&gt;&amp;lt;/form&amp;gt;&lt;/tt&gt; , por lo que se recomienda para operaciones con controles HTML o ASP.NET, ya que hace referencia a ellos una vez cargados.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;RegisterClientScriptInclude: sirve para ejecutar el código JavaScript que se guarda en un archivo externo (comúnmente con extensión .js) tiene dos cadenas como argumentos un nombre para identificar el script y el archivo que contiene el código JavaScript.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;p align="justify"&gt;Como ejemplo mostraremos una página ASP.NET que utiliza dos listas de usuarios (ListBox) y dos botones (HTML input) que se utilizan para mover los usuarios de una lista hacia otra.&lt;br /&gt;Los eventos son controlados mediante código JavaScript, esto sin utilizar código JavaScript incrustado en la página HTML, sino que el código JavaScript se genera desde código  ASP.NET.&lt;br /&gt;A continuación, el listado &lt;i&gt;Default.aspx&lt;/i&gt;:&lt;/p&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;span class="Special"&gt;&amp;lt;%&lt;/span&gt;@ &lt;span class="Identifier"&gt;Page Language=&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;&lt;/span&gt;&lt;span class="Constant"&gt;C#&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;&lt;/span&gt; &lt;span class="Identifier"&gt;Inherits=&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;&lt;/span&gt;&lt;span class="Constant"&gt;PostJavaScript.Default&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;&lt;/span&gt; &lt;span class="Special"&gt;%&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Comment"&gt;&amp;lt;!DOCTYPE html PUBLIC &amp;quot;-//W3C//DTD XHTML 1.0 Strict//EN&amp;quot; &amp;quot;&lt;br /&gt;&lt;a href="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"&gt;http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd&lt;/a&gt;&amp;quot;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Statement"&gt;html&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Statement"&gt;head&lt;/span&gt;&lt;span class="Identifier"&gt; runat=&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;server&amp;quot;&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="PreProc"&gt;        &lt;/span&gt;&lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Statement"&gt;title&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;span class="Title"&gt;Default&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="Statement"&gt;title&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="Statement"&gt;head&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Statement"&gt;body&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Statement"&gt;form&lt;/span&gt;&lt;span class="Identifier"&gt; &lt;/span&gt;&lt;span class="Type"&gt;id&lt;/span&gt;&lt;span class="Identifier"&gt;=&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;form1&amp;quot;&lt;/span&gt;&lt;span class="Identifier"&gt; runat=&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;server&amp;quot;&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;                &lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Statement"&gt;table&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Statement"&gt;tr&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Statement"&gt;td&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;Usuarios aceptados:&lt;span class="Identifier"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="Statement"&gt;td&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Statement"&gt;td&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="Statement"&gt;td&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Statement"&gt;td&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;Usuarios bloquedos:&lt;span class="Identifier"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="Statement"&gt;td&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="Statement"&gt;tr&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Statement"&gt;tr&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Statement"&gt;td&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;asp&lt;span class="Identifier"&gt;:ListBox &lt;/span&gt;&lt;span class="Type"&gt;ID&lt;/span&gt;&lt;span class="Identifier"&gt;=&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;ddlAcceptedContacts&amp;quot;&lt;/span&gt;&lt;span class="Identifier"&gt; runat=&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;server&amp;quot;&lt;/span&gt;&lt;span class="Identifier"&gt; SelectionMode=&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;Multiple&amp;quot;&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;asp&lt;span class="Identifier"&gt;:ListItem &lt;/span&gt;&lt;span class="Type"&gt;Value&lt;/span&gt;&lt;span class="Identifier"&gt;=&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;1&amp;quot;&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;Marvin Minsky&lt;span class="Identifier"&gt;&amp;lt;/&lt;/span&gt;asp&lt;span class="Identifier"&gt;:ListItem&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;asp&lt;span class="Identifier"&gt;:ListItem &lt;/span&gt;&lt;span class="Type"&gt;Value&lt;/span&gt;&lt;span class="Identifier"&gt;=&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;2&amp;quot;&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;John McCarthy&lt;span class="Identifier"&gt;&amp;lt;/&lt;/span&gt;asp&lt;span class="Identifier"&gt;:ListItem&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;asp&lt;span class="Identifier"&gt;:ListItem &lt;/span&gt;&lt;span class="Type"&gt;Value&lt;/span&gt;&lt;span class="Identifier"&gt;=&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;3&amp;quot;&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;Edsger Dijkstra&lt;span class="Identifier"&gt;&amp;lt;/&lt;/span&gt;asp&lt;span class="Identifier"&gt;:ListItem&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;asp&lt;span class="Identifier"&gt;:ListItem &lt;/span&gt;&lt;span class="Type"&gt;Value&lt;/span&gt;&lt;span class="Identifier"&gt;=&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;4&amp;quot;&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;Donald Knuth&lt;span class="Identifier"&gt;&amp;lt;/&lt;/span&gt;asp&lt;span class="Identifier"&gt;:ListItem&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;asp&lt;span class="Identifier"&gt;:ListItem &lt;/span&gt;&lt;span class="Type"&gt;Value&lt;/span&gt;&lt;span class="Identifier"&gt;=&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;5&amp;quot;&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;John Backus&lt;span class="Identifier"&gt;&amp;lt;/&lt;/span&gt;asp&lt;span class="Identifier"&gt;:ListItem&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;/&lt;/span&gt;asp&lt;span class="Identifier"&gt;:ListBox&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="Statement"&gt;td&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Statement"&gt;td&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Statement"&gt;input&lt;/span&gt;&lt;span class="Identifier"&gt; &lt;/span&gt;&lt;span class="Type"&gt;id&lt;/span&gt;&lt;span class="Identifier"&gt;=&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;btnAdd&amp;quot;&lt;/span&gt;&lt;span class="Identifier"&gt; &lt;/span&gt;&lt;span class="Type"&gt;type&lt;/span&gt;&lt;span class="Identifier"&gt;=&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;button&amp;quot;&lt;/span&gt;&lt;span class="Identifier"&gt; &lt;/span&gt;&lt;span class="Type"&gt;value&lt;/span&gt;&lt;span class="Identifier"&gt;=&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;Agregar&amp;quot;&lt;/span&gt;&lt;span class="Identifier"&gt; &lt;/span&gt;&lt;span class="Special"&gt;onclick=&amp;quot;&lt;/span&gt;&lt;span class="Special"&gt;addContact&lt;/span&gt;()&lt;span class="Special"&gt;&amp;quot;&lt;/span&gt;&lt;span class="Identifier"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Statement"&gt;br&lt;/span&gt;&lt;span class="Identifier"&gt; /&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Statement"&gt;input&lt;/span&gt;&lt;span class="Identifier"&gt; &lt;/span&gt;&lt;span class="Type"&gt;id&lt;/span&gt;&lt;span class="Identifier"&gt;=&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;btnRemove&amp;quot;&lt;/span&gt;&lt;span class="Identifier"&gt; &lt;/span&gt;&lt;span class="Type"&gt;type&lt;/span&gt;&lt;span class="Identifier"&gt;=&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;button&amp;quot;&lt;/span&gt;&lt;span class="Identifier"&gt; &lt;/span&gt;&lt;span class="Type"&gt;value&lt;/span&gt;&lt;span class="Identifier"&gt;=&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;Quitar&amp;quot;&lt;/span&gt;&lt;span class="Identifier"&gt; &lt;/span&gt;&lt;span class="Special"&gt;onclick=&amp;quot;&lt;/span&gt;&lt;span class="Special"&gt;removeContact&lt;/span&gt;()&lt;span class="Special"&gt;&amp;quot;&lt;/span&gt;&lt;span class="Identifier"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="Statement"&gt;td&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Statement"&gt;td&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;asp&lt;span class="Identifier"&gt;:ListBox &lt;/span&gt;&lt;span class="Type"&gt;ID&lt;/span&gt;&lt;span class="Identifier"&gt;=&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;ddlRemovedContacts&amp;quot;&lt;/span&gt;&lt;span class="Identifier"&gt; runat=&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;server&amp;quot;&lt;/span&gt;&lt;span class="Identifier"&gt; SelectionMode=&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;Multiple&amp;quot;&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;asp&lt;span class="Identifier"&gt;:ListItem &lt;/span&gt;&lt;span class="Type"&gt;Value&lt;/span&gt;&lt;span class="Identifier"&gt;=&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;1&amp;quot;&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;Niklaus Wirth&lt;span class="Identifier"&gt;&amp;lt;/&lt;/span&gt;asp&lt;span class="Identifier"&gt;:ListItem&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;asp&lt;span class="Identifier"&gt;:ListItem &lt;/span&gt;&lt;span class="Type"&gt;Value&lt;/span&gt;&lt;span class="Identifier"&gt;=&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;2&amp;quot;&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;Anders Hejlsberg&lt;span class="Identifier"&gt;&amp;lt;/&lt;/span&gt;asp&lt;span class="Identifier"&gt;:ListItem&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;/&lt;/span&gt;asp&lt;span class="Identifier"&gt;:ListBox&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="Statement"&gt;td&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="Statement"&gt;tr&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="Statement"&gt;table&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span class="Identifier"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="Statement"&gt;form&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="Statement"&gt;body&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="Statement"&gt;html&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p align="justify"&gt;El código ASPX/HTML de este ejemplo no crea funcionalidad alguna por lo que explicaremos la funcionalidad contenida en el código C#, en el listado &lt;i&gt;Default.aspx.cs&lt;/i&gt;.&lt;/p&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;using System;&lt;br /&gt;using System.Web;&lt;br /&gt;using System.Web.UI;&lt;br /&gt;&lt;br /&gt;namespace PostJavaScript&lt;br /&gt;{&lt;br /&gt;public partial class Default : System.Web.UI.Page&lt;br /&gt;{&lt;br /&gt;string FuncCopyItem(string name, string source, string destiny)&lt;br /&gt;{&lt;br /&gt;    string s = "function " + name + "() {" +&lt;br /&gt;" var control = document.getElementById(\"" + source + "\"); " +&lt;br /&gt;" var controlSelected = document.getElementById(\"" + destiny + "\"); " +&lt;br /&gt;"var selectedElements = 0; " +&lt;br /&gt;"if (control.options.selectedIndex == -1)" +&lt;br /&gt;" alert(\"lista vacia\"); " +&lt;br /&gt;" else { " +&lt;br /&gt;" var index = 0; " +&lt;br /&gt;" if (controlSelected.options.length &gt; 0) " +&lt;br /&gt;" selectedElements = controlSelected.options.length;" +&lt;br /&gt;" for (i = 0; i &lt; control.length; i++) { " +&lt;br /&gt;" if (control.options[i].selected == true) { " +&lt;br /&gt;"controlSelected.options[selectedElements + index] = " +&lt;br /&gt;"new Option(control.options[i].text, " +&lt;br /&gt;"control.options[i].value); " +&lt;br /&gt;" control.options[i] = null; " +&lt;br /&gt;" index++;" +&lt;br /&gt;" }" +&lt;br /&gt;" } " +&lt;br /&gt;" }" +&lt;br /&gt;" } ";&lt;br /&gt;    return s;&lt;br /&gt;}&lt;br /&gt;protected void Page_Load(object sender, EventArgs args)&lt;br /&gt;{&lt;br /&gt;    //en este ejemplo los controles ya han sido creados&lt;br /&gt;    //por eso registramos los scripts al final del formulario ya que&lt;br /&gt;    //usamos la propiedad ClientID&lt;br /&gt;    //con el parámetro true ponemos las etiquetas de JavaScript en la página&lt;br /&gt;    string ddl_one = ddlAcceptedContacts.ClientID;&lt;br /&gt;    string ddl_two = ddlRemovedContacts.ClientID;&lt;br /&gt;    string sc1 = FuncCopyItem("addContact", ddl_one,ddl_two );&lt;br /&gt;    string sc2 = FuncCopyItem("removeContact", ddl_two, ddl_one);&lt;br /&gt;    ClientScriptManager cs = Page.ClientScript;&lt;br /&gt;    cs.RegisterStartupScript(this.GetType(), "addContact", sc1, true);&lt;br /&gt;    cs.RegisterStartupScript(this.GetType(), "removeContact", sc2, true);&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p align="justify"&gt;Primero creamos el código JavaScript que tendra la funcionalidad para agregar los elementos de una lista hacia la otra, esto se logra con la función &lt;tt&gt;FuncCopyItem(string name, string source, string destiny)&lt;/tt&gt; esta función recibe tres argumentos el nombre de la función JavaScript que se creará en el código HTML al solicitar la página y con la cuál se identificaran los eventos de los controles , el control ListBox fuente de donde inicialmente se tomarán los items y por último el control ListBox destino a donde se pondrán los items.&lt;br /&gt;Con la siguiente línea de código:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;ClientScriptManager cs = Page.ClientScript;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Obtenemos el objeto &lt;tt&gt;ClientScriptManager&lt;/tt&gt; de la página, con él cual utilizaremos el metódo &lt;tt&gt;cs.RegisterStartupScript&lt;/tt&gt; con sus parámetros correspondientes, algo importante por lo cuál usamos este metódo es por que para construir el código JavaScript utilizamos la propiedad &lt;tt&gt;ClientID&lt;/tt&gt; del control ListBox, es decir el control debe existir obligatoriamente de lo contrario, cuando ASP .NET contruya la página contruirá el código JavaScript con estos parámetros nulos lo que causará un error no en la página ASP.NET sino en el código JavaScript cuando se llame para ejecutarse.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;span&gt;&lt;b&gt;La vista del proyecto en MonoDevelop&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/testjs/postJavaScript1.jpg"&gt;&lt;/div&gt;&lt;br&gt;&lt;br /&gt;&lt;span&gt;&lt;b&gt;Ejecutando el proyecto en Internet Explorer 9.0&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/testjs/postJavaScript2.jpg"&gt;&lt;/div&gt;&lt;br&gt;&lt;br /&gt;&lt;span&gt;&lt;b&gt;Ejecutando el proyecto en Firefox&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/testjs/postJavaScript3.jpg"&gt;&lt;/div&gt;&lt;br&gt;&lt;br /&gt;&lt;span&gt;&lt;b&gt;Mostrado el código JavaScript en la página generada por ASP.NET&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/testjs/postJavaScript4.jpg"&gt;&lt;/div&gt;&lt;br&gt;&lt;br /&gt;&lt;h3&gt;&lt;a href="http://www.humansharp.com/Code/PostJavaScript.zip"&gt;&lt;img src="http://www.humansharp.com/picture_library/dw.jpg" border="0"&gt;Descarga el proyecto para MonoDevelop&lt;/a&gt;&lt;/h3&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6494419861240446187-8031014659248503100?l=xomalli.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/8031014659248503100'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/8031014659248503100'/><link rel='alternate' type='text/html' href='http://xomalli.blogspot.com/2011/11/utilizando-javascript-desde-codigo.html' title='Utilizando JavaScript  desde código ASP.NET'/><author><name>Martín Márquez</name><uri>http://www.blogger.com/profile/10939957618126542300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_j4WRR9G9bfY/SV2_nw3UxeI/AAAAAAAAAAM/nT3SYp94IHo/s1600-R/photo.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-6494419861240446187.post-4596489928290257148</id><published>2011-09-08T14:13:00.000-07:00</published><updated>2011-09-08T14:43:55.929-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Redes'/><title type='text'>Ruteo Inter-VLAN en un Router Cisco utilizando Router-on-a-stick</title><content type='html'>&lt;p align="justify"&gt;Una VLAN es técnicamente un dominio de broadcast diferente, por lo que de forma predeterminada no pueden comunicarse entre sí, salvo se usen diferentes técnicas de ruteo inter-vlan cada una de los cuales tiene sus ventajas y sus desventajas, a continuación mostraré un ejemplo de una técnica llamada "Router-on-a-stick", que en resumen consiste en configurar una interfaz física de un Router para operar como un enlace troncal en el puerto de un switch, el Router efectua el ruteo intervlan de forma interna mediante el uso de subinterfaces, una subinterfaz es una interfaz virtual(vía software) que se crea en una interfaz física, por lo que se asocia cada subinterfaz con un número de VLAN, asi que podemos tener varias subinterfaces creadas en una misma interfaz física, lo cual presenta ventajas y desventajas que enumeramos a continuación.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;div&gt;Ventajas&lt;/div&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Fácil de implementar solo se requiere crear una subinterfaz por cada VLAN en el Router.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Mucho más económica que tener un Router por VLAN.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Mucho mejor latencia que tener un Router por VLAN.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;div&gt;Desventajas&lt;/div&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Los Routers son más lentos que los switches para ruteo inter-VLAN, lo ideal es tener un switch multicapa.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Si se necesita incrementar el número de puertos, entre más puertos requiera un Router más costoso resulta.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Estamos expuestos al buen funcionamiento de una sola interfaz física en el Router, esto es un único punto de fallo.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p align="justify"&gt;&lt;br /&gt;A continuación ejemplificaremos esta técnica con una práctica, los dispositivos son:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;4 PC's&lt;/li&gt;&lt;br /&gt;&lt;li&gt;2 switches&lt;/li&gt;&lt;br /&gt;&lt;li&gt;1 router&lt;/li&gt;&lt;br /&gt;&lt;li&gt;1 access point&lt;/li&gt;&lt;br /&gt;&lt;li&gt;1 laptop&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;span&gt;Al colocarlos en el WorkSpace del Packet Tracer debe ver más o menos como en la siguiente imagen:&lt;/span&gt;&lt;br&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/routeronstick/ronstick1.png"&gt;&lt;/div&gt;&lt;br&gt;&lt;br /&gt;Para la creación de las VLAN es conveniente el empleo de VTP para no teclear doblemente la configuración,asi que utilizamos el switch 1 (SW1,el que va unido al Router)  como servidor y el switch 2 (SW2 el que tiene el access point) como cliente, empezamos la configuración en el SW1, con los siguientes comandos.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;/* Creamos las VLAN's*/&lt;br /&gt;&lt;br /&gt;Switch&gt; en&lt;br /&gt;Switch# host SW1&lt;br /&gt;&lt;br /&gt;/*Configuramos como gateway la IP de la interfaz del Router*/&lt;br /&gt;&lt;br /&gt;SW1#ip default-gateway [ip]&lt;br /&gt;SW1# vlan database&lt;br /&gt;SW1 (vlan) # vlan 20 name marketing&lt;br /&gt;SW1 (vlan) # vlan 30 name accounting&lt;br /&gt;SW1 (vlan) # exit&lt;br /&gt;&lt;br /&gt;/*Modo servidor VTP*/&lt;br /&gt;&lt;br /&gt;SW1# conf t&lt;br /&gt;SW1 (config)# vtp mode server&lt;br /&gt;SW1 (config)# vtp domain [name]&lt;br /&gt;&lt;br /&gt;/*Configuramos las interfaces para acceso a las vlan*/&lt;br /&gt;&lt;br /&gt;SW1# conf t&lt;br /&gt;SW1 (config)# int fa/[número de interfaz]&lt;br /&gt;SW1 (config-if)#switchport access vlan [número de vlan]&lt;br /&gt;&lt;br /&gt;/*para deshabilitar el trunking */&lt;br /&gt;SW1 (config-if)#switchport mode access&lt;br /&gt;SW1 (config-if)#exit&lt;br /&gt;&lt;br /&gt;/*para crear los troncales*/&lt;br /&gt;SW1# int fa[0/número de puerto]&lt;br /&gt;&lt;br /&gt;/*la hacemos troncal */&lt;br /&gt;SW1 (config-if)# switchport mode trunk&lt;br /&gt;SW1 (config-if)# switchport trunk allowed &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p align="justify"&gt;En el SW2 tecleamos los mismos comandos para crear las troncales, la variante es la forma en que obtenemos las VLAN's creadas en el SW1 por VTP.&lt;/p&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Switch&gt; en&lt;br /&gt;Switch# host SW2&lt;br /&gt;/*Configuramos como gateway la IP de la interfaz del Router*/&lt;br /&gt;&lt;br /&gt;SW2#ip default-gateway [ip]&lt;br /&gt;SW2# conf t&lt;br /&gt;SW2 (config)# vtp mode client&lt;br /&gt;&lt;br /&gt;/*Aquí el dominio debe ser el mismo que el switch 1*/&lt;br /&gt;&lt;br /&gt;SW2 (config)# vtp domain [name] &lt;br /&gt;&lt;br /&gt;/*Para mostrar las VLAN's*/&lt;br /&gt;&lt;br /&gt;SW2# show vtp status&lt;br /&gt;&lt;br /&gt;/*Se configuran los puertos asociados a las VLAN's con los comandos del SW1, &lt;br /&gt;cambiando el número de puertos.*/&lt;br /&gt;&lt;br /&gt;/*Configurar la interfaz física.*/&lt;br /&gt;&lt;br /&gt;Router&gt;en&lt;br /&gt;Router#host RTRA&lt;br /&gt;RTRA# conf t&lt;br /&gt;RTRA (config)# int fa0/0&lt;br /&gt;RTRA (config-if)#ip address [ip] [subnet]&lt;br /&gt;&lt;br /&gt;/*Al activar la interfaz física se levantan las subinterfaces*/&lt;br /&gt;&lt;br /&gt;RTRA (config-if)# no shutdown&lt;br /&gt;RTRA (config-if)# exit&lt;br /&gt;&lt;br /&gt;/*Ahora viene la creación de subinterfaces en el Router.*/&lt;br /&gt;&lt;br /&gt;RTRA (config)# interface f0/0.[vlan id]&lt;br /&gt;RTRA (config-subif)# encapsulation dot1q [vlan id]&lt;br /&gt;RTRA (config-subif)# ip address 192.168.[vlan id].1 255.255.255.0&lt;br /&gt;RTRA (config-subif)# exit&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span&gt;En la configuración IP de cada PC, debe de ponerse como gateway la ip de cada subinterfaz asociada a la VLAN dentro de la cual se encuentre configurada la PC.&lt;br /&gt;Por ejemplo si una PC su ip es:192.168.20.2 y se encuentra en la VLAN 20 su gateway sera la IP 192.168.20.1 la cual se asigno a una subinterfaz asociada con la VLAN 20, como se muestra en las siguientes imágenes:&lt;/span&gt;&lt;br/&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/routeronstick/ronstick2.png"&gt;&lt;/div&gt;&lt;br&gt;&lt;br /&gt;&lt;span&gt;Igualmente si una PC su IP 192.168.30.2 es perteneciendo a la VLAN 30, entonces su gateway es la IP 192.168.30.1 que se asigno a la subinterfaz asociada con la VLAN 30&lt;/span&gt;&lt;br/&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/routeronstick/ronstick3.png"&gt;&lt;/div&gt;&lt;br&gt;&lt;br /&gt;&lt;span&gt;Aquí se muestra la comunicación inter-VLAN's.&lt;/span&gt;&lt;br&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/routeronstick/ronstick4.png"&gt;&lt;/div&gt;&lt;br&gt;&lt;br /&gt;&lt;h3&gt;&lt;a href="http://www.humansharp.com/PacketTracer/routeronstick.pkt"&gt;&lt;img src="http://www.humansharp.com/picture_library/dw.jpg" border="0"&gt;Descarga el archivo para packet tracer 5.3.2&lt;/a&gt;&lt;/h3&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6494419861240446187-4596489928290257148?l=xomalli.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/4596489928290257148'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/4596489928290257148'/><link rel='alternate' type='text/html' href='http://xomalli.blogspot.com/2011/09/ruteo-inter-vlan-con-router-on-stick.html' title='Ruteo Inter-VLAN en un Router Cisco utilizando Router-on-a-stick'/><author><name>Martín Márquez</name><uri>http://www.blogger.com/profile/10939957618126542300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_j4WRR9G9bfY/SV2_nw3UxeI/AAAAAAAAAAM/nT3SYp94IHo/s1600-R/photo.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-6494419861240446187.post-8609725190283792985</id><published>2011-09-07T13:24:00.000-07:00</published><updated>2011-09-07T15:44:22.760-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Redes'/><title type='text'>Instalando Cisco Packet Tracer en OpenSuSe x64.</title><content type='html'>&lt;p align="justify"&gt;&lt;a href="http://www.cisco.com/web/learning/netacad/course_catalog/PacketTracer.html"&gt;Cisco packet tracer&lt;/a&gt; es un simulador para dispositivos de redes en donde se realizan la prácticas de Cisco Networking Academy.&lt;br /&gt;Este simulador existe para los sistemas operativos Linux Fedora y Ubuntu, en formato .deb y .rpm que se descarga como un archivo ejecutable con extensión &lt;i&gt;.bin&lt;/i&gt;.&lt;br /&gt;Como no existe una versión de &lt;b&gt;Packet Tracer&lt;/b&gt; de 64 bits,una de las dependencias para la instalación, es la libreria &lt;a href="http://www.libpng.org/pub/png/libpng.html"&gt;ligpng&lt;/a&gt; de 32 bits, aunque la version de 64 bits de esta biblioteca se encuentra instalada de forma predeterminada &lt;b&gt;Packet Tracer&lt;/b&gt; solicitara la versión de 32 bits,  por lo cual es necesario instalar la bibloteca &lt;a href="http://www.libpng.org/pub/png/libpng.html"&gt;ligpng[X.X]-32bits&lt;/a&gt;, en el caso de los usuarios de Suse, esto se realiza con Yast.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;span&gt;Como se muestra en la siguiente imagen:&lt;/span&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/packetTracer/packet1.png"&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;En este caso decidí instalarlo en su formato .rpm, una vez descargado procedí  a instalarlo con los siguientes comandos:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$chmod +rx [PacketTracer532_i386_no_tutorials_installer-rpm.bin]&lt;br /&gt;$su&lt;br /&gt;#./[PacketTracer532_i386_no_tutorials_installer-rpm.bin]&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p align="justify"&gt;&lt;br /&gt;Un problema que sucede con frecuencia cuando ejecutamos el programa, es la horrible visualización de las fuentes, esto debido a las siguientes razones:&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;Cisco decidió utilizar sus propias bibliotecas QT para la ejecucción del programa, esto tiene sentido desde el punto de vista de que es un programa multiplaforma, por lo que evita que el usuario instale esa dependencia por separado, por ejemplo en el caso de Windows donde no se provee de forma predeterminada con tal requerimiento.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;La fuente predeterminada para los menus del programa es &lt;i&gt;tahoma&lt;/i&gt;, la cuál es una fuente no génerica, si no se encuentra disponible la fuente de los menus se ven de una forma ilegible.&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;/p&gt;&lt;p align="justify"&gt;&lt;br /&gt;Para solucionar el primer punto, hay que instalar el paquete de desarrollo de QT en mí caso fue el &lt;tt&gt;libqt4-dev&lt;/tt&gt;. Con lo cuál se arreglaran las fuentes de todo el workspace en especial la de los dispositivos de red.&lt;/p&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;sudo zypper in libqt4-dev&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span&gt;Los menús de &lt;b&gt;Packet Tracer&lt;/b&gt; de una forma ilegible&lt;/span&gt;&lt;br&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/packetTracer/packet2.png"&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;p align="justify"&gt;Para solucionar el segundo punto hay que cambiar la fuente de los menús, siguiendo los siguientes pasos:&lt;/p&gt;&lt;br /&gt;&lt;span&gt;Ir a al submenú &lt;tt&gt;&lt;i&gt;preferences&lt;/i&gt;&lt;/tt&gt; en el menú &lt;tt&gt;&lt;i&gt;options&lt;/i&gt;&lt;/tt&gt; del menú principal, ahi se abrirá una ventana con una serie de pestañas, elegir entonces la pestaña &lt;tt&gt;&lt;i&gt;font&lt;/i&gt;&lt;/tt&gt;, ahi en la sección &lt;tt&gt;&lt;i&gt;General Interface&lt;/i&gt;&lt;/tt&gt; ubicamos el valor de &lt;tt&gt;&lt;i&gt;File Menu&lt;/i&gt;&lt;/tt&gt; como se muestra en la siguiente imagen. &lt;/span&gt;&lt;br/&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/packetTracer/packet3.png"&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;span&gt;Cambiamos la fuente de &lt;i&gt;Tahoma&lt;/i&gt; por una fuente más génerica, en mí caso elegí &lt;i&gt;Arial&lt;/i&gt; &lt;/span&gt;&lt;br/&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/packetTracer/packet4.png"&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;span&gt;Podemos apreciar el cambio en la legibilidad de la fuente de los menús del menú principal.&lt;/span&gt;&lt;br/&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/packetTracer/packet5.png"&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Enlaces adicionales donde se encuentra más información al respecto:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://pvradu.blogspot.com/2010/04/packet-tracer-52-font-problem.html"&gt;Packet Tracer 5.2 font problem&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://sonniesedge.co.uk/2010/02/03/fuckin-ugly-fonts-on-ubuntu-version-of-packet-tracer/"&gt;Fixing fugly fonts on Ubuntu version of Packet Tracer&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6494419861240446187-8609725190283792985?l=xomalli.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/8609725190283792985'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/8609725190283792985'/><link rel='alternate' type='text/html' href='http://xomalli.blogspot.com/2011/09/instalando-cisco-packet-tracer-en.html' title='Instalando Cisco Packet Tracer en OpenSuSe x64.'/><author><name>Martín Márquez</name><uri>http://www.blogger.com/profile/10939957618126542300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_j4WRR9G9bfY/SV2_nw3UxeI/AAAAAAAAAAM/nT3SYp94IHo/s1600-R/photo.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-6494419861240446187.post-4060222458298723888</id><published>2011-07-30T14:03:00.000-07:00</published><updated>2011-08-03T10:05:41.425-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><title type='text'>Entendiendo Logging en Aplicaciones .NET  con Log4net</title><content type='html'>&lt;p align="justify"&gt;&lt;br /&gt;Esta entrada se relaciona con esta &lt;a href="http://xomalli.blogspot.com/2011/05/entendiendo-logging-en-aplicaciones.html"&gt;entrada anterior&lt;/a&gt;, que trata también sobre el tema de Logging.&lt;br /&gt;Log4net es opción altamente recomendable para la implementación del logging en las aplicaciones desarrolladas para .NET. Sobre todo cuando se necesita una solución más configurable y robusta que la proporcionada por las clases del ensamblado System.Diagnostics, que en comparación con log4net están en un nivel elemental, si necesitamos  una herramienta  que soporte diferentes fuentes de persistencia,   que no afecte el desempeño de las aplicaciones y que sea transportable  entre la implementación .NET  de Microsoft y la del proyecto Mono.&lt;/p&gt;&lt;br /&gt;&lt;p align="justify"&gt;Log4net es un Framework open source creado por la &lt;a href=”http://www.apache.org/”&gt;fundación Apache&lt;/a&gt; basado en la implementación de los servicios de logging existentes en &lt;a href=”http://logging.apache.org/log4j/1.2/”&gt;log4j&lt;/a&gt;, un componente de logging usado durante años en los ecosistemas Java.&lt;br /&gt;La arquitectura de Log4net puede resumirse en tres clases principales cada una encargada de una responsabilidad dentro del Framework y que se detalla a continuación:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;b&gt;Logger&lt;/b&gt; Captura la información para la bitácora.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;b&gt;Appender&lt;/b&gt; Publica la información hacia diversas fuentes de logging configuradas en la aplicación. Al menos debe definirse un Appender, el Appender predeterminado es  el &lt;tt&gt;ConsoleAppender&lt;/tt&gt; cual dirige su salida hacia una terminal de Consola.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;b&gt;Layout&lt;/b&gt; Se utiliza para darle formato haciendo legible cada salida de los  distintos  &lt;i&gt;Appenders&lt;/i&gt;.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;Para más información consultar http://logging.apache.org/log4j/1.2/manual.html aunque es para log4j la arquitectura es idéntica a log4net.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p align="justify"&gt;Como ejemplo del uso de log4net vamos a crear dos programas un cliente y un servidor los cuales se comunicarán entre sí, la clase ServerProgram es un servidor TCP que escucha en el puerto 6060 y la clase Program que es el cliente que al conectarse con el servidor, le solicita al usuario el nombre de un archivo de texto el cuál sera leído y cada línea de texto será enviada hacia el servidor. El programa cliente implementa todo el código básico para el manejo del logging con log4net.&lt;/p&gt;&lt;br /&gt;&lt;span&gt;Listado de la clase ServerProgram&lt;/span&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;using System.Net;&lt;br /&gt;using System.Net.Sockets;&lt;br /&gt;using System.IO;&lt;br /&gt;using System.Threading;&lt;br /&gt;using System;&lt;br /&gt;&lt;br /&gt;namespace Samples&lt;br /&gt;{&lt;br /&gt;public class ServerProgram&lt;br /&gt;{&lt;br /&gt;public ServerProgram()&lt;br /&gt;{&lt;br /&gt;try&lt;br /&gt;{&lt;br /&gt;    TcpListener listener = new TcpListener(IPAddress.Loopback, 6060);&lt;br /&gt;    listener.Start();&lt;br /&gt;    Console.WriteLine("Waiting....");&lt;br /&gt;    TcpClient tcpClient = listener.AcceptTcpClient();&lt;br /&gt;    NetworkStream stream = tcpClient.GetStream();&lt;br /&gt;    Console.WriteLine("Recibiendo....");&lt;br /&gt;    using (StreamReader sr = new StreamReader(stream))&lt;br /&gt;    {&lt;br /&gt;        Console.WriteLine(sr.ReadToEnd());&lt;br /&gt;    }&lt;br /&gt;    tcpClient.Close();&lt;br /&gt;    listener.Stop();&lt;br /&gt;}&lt;br /&gt;catch (Exception ex)&lt;br /&gt;{&lt;br /&gt;    Console.WriteLine(ex.Message);&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public static void Main(string[] args)&lt;br /&gt;{&lt;br /&gt;new ServerProgram();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span&gt;Listado de la clase Program (cliente)&lt;/span&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;using System;&lt;br /&gt;using System.Net.Sockets;&lt;br /&gt;using System.IO;&lt;br /&gt;using System.Net;&lt;br /&gt;using log4net;&lt;br /&gt;using log4net.Config;&lt;br /&gt;using log4net.Appender;&lt;br /&gt;using System.Configuration;&lt;br /&gt;&lt;br /&gt;namespace Samples&lt;br /&gt;{&lt;br /&gt;class Program&lt;br /&gt;{&lt;br /&gt;static readonly log4net.ILog log = &lt;br /&gt;log4net.LogManager.GetLogger(&lt;br /&gt;System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);&lt;br /&gt;public Program()&lt;br /&gt;{&lt;br /&gt;try&lt;br /&gt;{&lt;br /&gt;Console.Write("Puerto &gt; ");&lt;br /&gt;int thePort = Convert.ToInt32(Console.ReadLine());&lt;br /&gt;Console.Write("File Name &gt;");&lt;br /&gt;string FileName = Console.ReadLine();&lt;br /&gt;string s = null;&lt;br /&gt;TcpClient c = new TcpClient("127.0.0.1", thePort);&lt;br /&gt;NetworkStream stream = c.GetStream();&lt;br /&gt;using (StreamWriter writer = new StreamWriter(stream))&lt;br /&gt;{&lt;br /&gt;    Console.WriteLine("Leyendo archivo");&lt;br /&gt;&lt;br /&gt;    using (FileStream fs = new FileStream(FileName, FileMode.Open))&lt;br /&gt;    {&lt;br /&gt;&lt;br /&gt;        using (StreamReader sr = new StreamReader(fs))&lt;br /&gt;        {&lt;br /&gt;            while ((s = sr.ReadLine()) != null)&lt;br /&gt;            {&lt;br /&gt;                writer.WriteLine(s);&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;stream.Close();&lt;br /&gt;c.Close();&lt;br /&gt;}&lt;br /&gt;catch (FormatException ex)&lt;br /&gt;{&lt;br /&gt;    log.Error(ex.Message, ex);&lt;br /&gt;    throw ex;&lt;br /&gt;}&lt;br /&gt;catch (SocketException ex)&lt;br /&gt;{&lt;br /&gt;    log.Error(ex.Message, ex);&lt;br /&gt;    throw ex;&lt;br /&gt;}&lt;br /&gt;catch (IOException ex)&lt;br /&gt;{&lt;br /&gt;    log.Error(ex.Message, ex);&lt;br /&gt;    throw ex;&lt;br /&gt;}&lt;br /&gt;catch (Exception ex)&lt;br /&gt;{&lt;br /&gt;    log.Error(ex.Message, ex);&lt;br /&gt;    throw ex;&lt;br /&gt;}}&lt;br /&gt;public static void Main(string[] args) {&lt;br /&gt;    try&lt;br /&gt;    {&lt;br /&gt;log.Info("Ejecutando la aplicación en " + DateTime.Now.ToLongTimeString());&lt;br /&gt;        XmlConfigurator.Configure();&lt;br /&gt;        new Program();&lt;br /&gt;log.Info("Cerrando aplicación en " + DateTime.Now.ToLongTimeString());&lt;br /&gt;    }&lt;br /&gt;    catch (ConfigurationException ex)&lt;br /&gt;    {&lt;br /&gt;        Console.WriteLine("No se pudo cargar el logger",ex);&lt;br /&gt;    }&lt;br /&gt;    catch (Exception) {&lt;br /&gt;        Console.WriteLine("Hubo un error, ver el log");&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span&gt;El archivo de configuración &lt;i&gt;App.config&lt;/i&gt; en donde van las opciones de configuración de &lt;b&gt;Log4net&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;span class="Comment"&gt;&amp;lt;?&lt;/span&gt;&lt;span class="Type"&gt;xml&lt;/span&gt;&lt;span class="Type"&gt; &lt;/span&gt;&lt;span class="Type"&gt;version&lt;/span&gt;=&lt;span class="Constant"&gt;&amp;quot;1.0&amp;quot;&lt;/span&gt;&lt;span class="Type"&gt; &lt;/span&gt;&lt;span class="Type"&gt;encoding&lt;/span&gt;=&lt;span class="Constant"&gt;&amp;quot;utf-8&amp;quot;&lt;/span&gt;&lt;span class="Type"&gt; &lt;/span&gt;&lt;span class="Comment"&gt;?&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Identifier"&gt;configuration&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Identifier"&gt;configSections&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Identifier"&gt;section&lt;/span&gt;&lt;span class="Identifier"&gt; &lt;/span&gt;&lt;span class="Type"&gt;name&lt;/span&gt;=&lt;span class="Constant"&gt;&amp;quot;log4net&amp;quot;&lt;/span&gt;&lt;span class="Identifier"&gt; &lt;/span&gt;&lt;span class="Type"&gt;type&lt;/span&gt;=&lt;span class="Constant"&gt;&amp;quot;log4net.Config.Log4NetConfigurationSectionHandler,log4net&amp;quot;&lt;/span&gt;&lt;span class="Identifier"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;/configSections&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Identifier"&gt;log4net&lt;/span&gt;&lt;span class="Identifier"&gt; &lt;/span&gt;&lt;span class="Type"&gt;debug&lt;/span&gt;=&lt;span class="Constant"&gt;&amp;quot;false&amp;quot;&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Identifier"&gt;appender&lt;/span&gt;&lt;span class="Identifier"&gt; &lt;/span&gt;&lt;span class="Type"&gt;name&lt;/span&gt;=&lt;span class="Constant"&gt;&amp;quot;FileAppender&amp;quot;&lt;/span&gt;&lt;span class="Identifier"&gt; &lt;/span&gt;&lt;span class="Type"&gt;type&lt;/span&gt;=&lt;span class="Constant"&gt;&amp;quot;log4net.Appender.FileAppender&amp;quot;&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Identifier"&gt;file&lt;/span&gt;&lt;span class="Identifier"&gt; &lt;/span&gt;&lt;span class="Type"&gt;value&lt;/span&gt;=&lt;span class="Constant"&gt;&amp;quot;log.txt&amp;quot;&lt;/span&gt;&lt;span class="Identifier"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Identifier"&gt;appendToFile&lt;/span&gt;&lt;span class="Identifier"&gt; &lt;/span&gt;&lt;span class="Type"&gt;value&lt;/span&gt;=&lt;span class="Constant"&gt;&amp;quot;true&amp;quot;&lt;/span&gt;&lt;span class="Identifier"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Identifier"&gt;layout&lt;/span&gt;&lt;span class="Identifier"&gt; &lt;/span&gt;&lt;span class="Type"&gt;type&lt;/span&gt;=&lt;span class="Constant"&gt;&amp;quot;log4net.Layout.PatternLayout&amp;quot;&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Identifier"&gt;conversionPattern&lt;/span&gt;&lt;span class="Identifier"&gt; &lt;/span&gt;&lt;span class="Type"&gt;value&lt;/span&gt;=&lt;span class="Constant"&gt;&amp;quot;[%date{dd-MM-yyyy HH:mm:ss}] [%level] %message %newline&amp;quot;&lt;/span&gt;&lt;span class="Identifier"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;/layout&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;/appender&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Identifier"&gt;root&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Identifier"&gt;priority&lt;/span&gt;&lt;span class="Identifier"&gt; &lt;/span&gt;&lt;span class="Type"&gt;value&lt;/span&gt;=&lt;span class="Constant"&gt;&amp;quot;ALL&amp;quot;&lt;/span&gt;&lt;span class="Identifier"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Identifier"&gt;appender-ref&lt;/span&gt;&lt;span class="Identifier"&gt; &lt;/span&gt;&lt;span class="Type"&gt;ref&lt;/span&gt;=&lt;span class="Constant"&gt;&amp;quot;FileAppender&amp;quot;&lt;/span&gt;&lt;span class="Identifier"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;/root&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;/log4net&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;/configuration&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span&gt;En el archivo de configuración utilizamos el &lt;i&gt;&lt;/i&gt; declarado en la siguiente sección&lt;/span&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&amp;lt;appender name=&amp;quot;FileAppender&amp;quot; type=&amp;quot;log4net.Appender.FileAppender&amp;quot;&amp;gt;&lt;br /&gt;&amp;lt;file value=&amp;quot;log.txt&amp;quot;/&amp;gt;&lt;br /&gt;&amp;lt;appendToFile value=&amp;quot;true&amp;quot;/&amp;gt;&lt;br /&gt;&amp;lt;layout type=&amp;quot;log4net.Layout.PatternLayout&amp;quot;&amp;gt;&lt;br /&gt;&amp;lt;conversionPattern value=&amp;quot;[%date{dd-MM-yyyy HH:mm:ss}] [%level] %message %newline&amp;quot;/&amp;gt;&lt;br /&gt;&amp;lt;/layout&amp;gt;&lt;br /&gt;&amp;lt;/appender&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span&gt;Declaración del componente principal para implementar los métodos del Logger.&lt;/span&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;static readonly log4net.ILog log = log4net.LogManager.GetLogger(&lt;br /&gt;System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span&gt;carga la configuración del archivo de configuración para &lt;b&gt;Log4net&lt;/b&gt;.&lt;/span&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;XmlConfigurator.Configure();&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span&gt;Escribir una excepción al log.&lt;/span&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;log.Error(ex.Message, ex);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span&gt;Escribir información al log&lt;/span&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;log.Info("Ejecutando la aplicación en " + DateTime.Now.ToLongTimeString());&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span&gt;Compilando los programas:&lt;/span&gt;&lt;br&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/log4net/log1.png"&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;span&gt;Ejecutando el servidor&lt;/span&gt;&lt;br&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/log4net/log3.png"&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;span&gt;Ejecutando el cliente&lt;/span&gt;&lt;br&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/log4net/log2.png"&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;span&gt;Generando excepción de formato&lt;/span&gt;&lt;br&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/log4net/log4.png"&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;span&gt;Generando excepción de comunicación&lt;/span&gt;&lt;br&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/log4net/log5.png"&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;span&gt;Revisando el archivo de log, creado por log4net&lt;/span&gt;&lt;br&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/log4net/log6.png"&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6494419861240446187-4060222458298723888?l=xomalli.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/4060222458298723888'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/4060222458298723888'/><link rel='alternate' type='text/html' href='http://xomalli.blogspot.com/2011/07/entendiendo-logging-en-aplicaciones-net.html' title='Entendiendo Logging en Aplicaciones .NET  con Log4net'/><author><name>Martín Márquez</name><uri>http://www.blogger.com/profile/10939957618126542300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_j4WRR9G9bfY/SV2_nw3UxeI/AAAAAAAAAAM/nT3SYp94IHo/s1600-R/photo.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-6494419861240446187.post-8865975566319395365</id><published>2011-06-29T14:51:00.000-07:00</published><updated>2011-06-29T15:43:26.753-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><title type='text'>File Upload con ASP.NET en Linux y Apache con HtmlInputFile (Html Control) y en IIS y Windows con FileUpload (Web Control).</title><content type='html'>&lt;p align="justify"&gt;&lt;br /&gt;Una de las operaciones más frecuentes de las aplicaciones web (Web applications) es la carga de archivos (file upload), que es la acción donde el usuario puede seleccionar un archivo de su computadora y mediante el uso de un formulario en una página web puede transferir el archivo desde el sistema de archivos local hacia el sistema de archivos del servidor donde se encuentre la página web. &lt;br /&gt;ASP .NET tiene dos formas de hacer esta funcionalidad, una   mediante un control &lt;a href="http://msdn.microsoft.com/en-us/library/system.web.ui.htmlcontrols.htmlinputfile&lt;br /&gt;%28v=vs.71%29.aspx"&gt;HtmlInputFile&lt;/a&gt; la cual se ha soportado desde el Framework 1.1 y la otra mediante un control &lt;a href="http://msdn.microsoft.com/en-&lt;br /&gt;us/library/ysf0192b%28v=VS.80%29.aspx"&gt;FileUpload&lt;/a&gt; la cual se soporta a partir del Framework 2.0.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p align="justify"&gt;&lt;br /&gt;A continuación mostramos el listado de un programa en ASP.NET como ejemplo de la implementación de publicación de documentos utilizando el control &lt;a href="http://msdn.microsoft.com/en-us/library/system.web.ui.htmlcontrols.htmlinputfile%28v=vs.71%29.aspx"&gt;HtmlInputFile&lt;/a&gt;.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;    &lt;div&gt;&lt;b&gt;Listado 1.0 ASP.NET upload con un control&lt;/b&gt; &lt;a href="http://msdn.microsoft.com/en-us/library/system.web.ui.htmlcontrols.htmlinputfile%28v=vs.71%29.aspx"&gt;HtmlInputFile&lt;/a&gt;&lt;br /&gt;    &lt;/div&gt;&lt;br /&gt;    &lt;!--listado 1.0--&gt;&lt;br /&gt;    &lt;pre&gt;&lt;br /&gt;&lt;span class="Special"&gt;&amp;lt;%&lt;/span&gt;@ &lt;span class="Identifier"&gt;Page Language=&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;&lt;/span&gt;&lt;span class="Constant"&gt;C#&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;&lt;/span&gt; &lt;span class="Identifier"&gt;AutoEventWireup=&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;&lt;/span&gt;&lt;span class="Constant"&gt;true&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;&lt;/span&gt;&lt;span class="Special"&gt;%&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Comment"&gt;&amp;lt;!DOCTYPE html PUBLIC &amp;quot;-//W3C//DTD XHTML 1.0 Transitional//EN&amp;quot; &lt;br /&gt;&amp;quot;&lt;a href="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&lt;/a&gt;&amp;quot;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Statement"&gt;script&lt;/span&gt;&lt;span class="Identifier"&gt; runat=&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;server&amp;quot;&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="Statement"&gt;protected&lt;/span&gt;&lt;span class="Special"&gt; void Page_Load&lt;/span&gt;(&lt;span class="Type"&gt;object&lt;/span&gt;&lt;span class="Special"&gt; sender, EventArgs e&lt;/span&gt;)&lt;br /&gt;&lt;span class="Identifier"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class="Comment"&gt;//Version 1.1&lt;/span&gt;&lt;br /&gt;&lt;span class="Statement"&gt;protected&lt;/span&gt;&lt;span class="Special"&gt; void btnPublish_click&lt;/span&gt;(&lt;span class="Type"&gt;object&lt;/span&gt;&lt;span class="Special"&gt; sender, EventArgs args&lt;/span&gt;)&lt;span class="Special"&gt; &lt;/span&gt;&lt;span class="Identifier"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span class="Statement"&gt;try&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span class="Type"&gt;string&lt;/span&gt;&lt;span class="Special"&gt; publishPath = ConfigurationSettings.AppSettings&lt;/span&gt;&lt;span class="Identifier"&gt;[&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;publishPath&amp;quot;&lt;/span&gt;&lt;span class="Identifier"&gt;]&lt;/span&gt;&lt;span class="Special"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class="Statement"&gt;if&lt;/span&gt;(&lt;span class="Special"&gt;publishPath == &lt;/span&gt;&lt;span class="Statement"&gt;null&lt;/span&gt;)&lt;br /&gt;&lt;span class="Special"&gt;  sspublishPath = &lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;/home/martin/public_html/Downloads/&amp;quot;&lt;/span&gt;&lt;span class="Special"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class="Statement"&gt;if&lt;/span&gt;&lt;span class="Special"&gt; &lt;/span&gt;((&lt;span class="Special"&gt;htmlinputFile.PostedFile != &lt;/span&gt;&lt;span class="Statement"&gt;null&lt;/span&gt;)&lt;span class="Special"&gt; &amp;amp;&amp;amp; &lt;/span&gt;(&lt;span class="Special"&gt;htmlinputFile.PostedFile.ContentLength &amp;gt; &lt;/span&gt;0))&lt;br /&gt;&lt;span class="Identifier"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span class="Special"&gt;    publish&lt;/span&gt;(&lt;span class="Special"&gt;htmlinputFile, publishPath&lt;/span&gt;)&lt;span class="Special"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class="Special"&gt;    lblmsg.ForeColor = System.Drawing.Color.Black;&lt;/span&gt;&lt;br /&gt;&lt;span class="Special"&gt;    lblmsg.Text = &lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;Archivo públicado con éxito&amp;quot;&lt;/span&gt;&lt;span class="Special"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class="Statement"&gt;else&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span class="Special"&gt;    lblmsg.ForeColor = System.Drawing.Color.Red;&lt;/span&gt;&lt;br /&gt;&lt;span class="Special"&gt;    lblmsg.Text = &lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;Falta archivo para publicar&amp;quot;&lt;/span&gt;&lt;span class="Special"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class="Statement"&gt;catch&lt;/span&gt;&lt;span class="Special"&gt; &lt;/span&gt;(&lt;span class="Special"&gt;Exception ex&lt;/span&gt;)&lt;span class="Special"&gt; &lt;/span&gt;&lt;span class="Identifier"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span class="Special"&gt;lblmsg.ForeColor = System.Drawing.Color.Red;&lt;/span&gt;&lt;br /&gt;&lt;span class="Special"&gt;lblmsg.Text = ex.Message;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="Statement"&gt;public&lt;/span&gt;&lt;span class="Special"&gt; void publish&lt;/span&gt;(&lt;span class="Special"&gt;System.Web.UI.HtmlControls.HtmlInputFile inputFile,&lt;/span&gt;&lt;br /&gt;&lt;span class="Type"&gt;string&lt;/span&gt;&lt;span class="Special"&gt; publishPath&lt;/span&gt;)&lt;br /&gt;&lt;span class="Identifier"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span class="Special"&gt;System.IO.FileInfo fi = &lt;/span&gt;&lt;span class="Statement"&gt;new&lt;/span&gt;&lt;span class="Special"&gt; System.IO.FileInfo&lt;/span&gt;(&lt;span class="Special"&gt;inputFile.PostedFile.FileName&lt;/span&gt;)&lt;span class="Special"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class="Type"&gt;string&lt;/span&gt;&lt;span class="Special"&gt; theFile = publishPath + fi.Name;&lt;/span&gt;&lt;br /&gt;&lt;span class="Special"&gt;inputFile.PostedFile.SaveAs&lt;/span&gt;(&lt;span class="Special"&gt;theFile&lt;/span&gt;)&lt;span class="Special"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="Statement"&gt;script&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Statement"&gt;html&lt;/span&gt;&lt;span class="Identifier"&gt; xmlns=&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;&lt;a href="http://www.w3.org/1999/xhtml"&gt;http://www.w3.org/1999/xhtml&lt;/a&gt;&amp;quot;&lt;/span&gt;&lt;span class="Identifier"&gt; &amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Statement"&gt;head&lt;/span&gt;&lt;span class="Identifier"&gt; runat=&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;server&amp;quot;&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Statement"&gt;title&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="Statement"&gt;title&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="Statement"&gt;head&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Statement"&gt;body&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Statement"&gt;form&lt;/span&gt;&lt;span class="Identifier"&gt; &lt;/span&gt;&lt;span class="Type"&gt;id&lt;/span&gt;&lt;span class="Identifier"&gt;=&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;form1&amp;quot;&lt;/span&gt;&lt;span class="Identifier"&gt; runat=&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;server&amp;quot;&lt;/span&gt;&lt;span class="Identifier"&gt; &lt;/span&gt;&lt;span class="Type"&gt;enctype&lt;/span&gt;&lt;span class="Identifier"&gt;=&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;multipart/form-data&amp;quot;&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Statement"&gt;div&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Statement"&gt;table&lt;/span&gt;&lt;span class="Identifier"&gt; &lt;/span&gt;&lt;span class="Type"&gt;width&lt;/span&gt;&lt;span class="Identifier"&gt;=&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;33%&amp;quot;&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Statement"&gt;tr&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Statement"&gt;td&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;        1-. Seleccione el archivo&lt;span class="Identifier"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="Statement"&gt;td&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="Statement"&gt;tr&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Statement"&gt;tr&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Statement"&gt;td&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Statement"&gt;input&lt;/span&gt;&lt;span class="Identifier"&gt; &lt;/span&gt;&lt;span class="Type"&gt;id&lt;/span&gt;&lt;span class="Identifier"&gt;=&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;htmlinputFile&amp;quot;&lt;/span&gt;&lt;span class="Identifier"&gt; &lt;/span&gt;&lt;span class="Type"&gt;maxlength&lt;/span&gt;&lt;span class="Identifier"&gt;=&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;5120&amp;quot;&lt;/span&gt;&lt;span class="Identifier"&gt; &lt;/span&gt;&lt;span class="Type"&gt;name&lt;/span&gt;&lt;span class="Identifier"&gt;=&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;htmlinputFile&amp;quot;&lt;/span&gt;&lt;span class="Identifier"&gt; &lt;/span&gt;&lt;span class="Type"&gt;size&lt;/span&gt;&lt;span class="Identifier"&gt;=&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;48&amp;quot;&lt;/span&gt;&lt;span class="Identifier"&gt; &lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;            &lt;/span&gt;&lt;span class="Type"&gt;type&lt;/span&gt;&lt;span class="Identifier"&gt;=&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;file&amp;quot;&lt;/span&gt;&lt;span class="Identifier"&gt; runat=&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;server&amp;quot;&lt;/span&gt;&lt;span class="Identifier"&gt; /&amp;gt;&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="Statement"&gt;td&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="Statement"&gt;tr&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Statement"&gt;tr&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Statement"&gt;td&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;        2-. Pulse el botón publicar&lt;span class="Identifier"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="Statement"&gt;td&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="Statement"&gt;tr&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Statement"&gt;tr&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Statement"&gt;td&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;asp&lt;span class="Identifier"&gt;:Button &lt;/span&gt;&lt;span class="Type"&gt;ID&lt;/span&gt;&lt;span class="Identifier"&gt;=&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;btnPublish&amp;quot;&lt;/span&gt;&lt;span class="Identifier"&gt; runat=&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;server&amp;quot;&lt;/span&gt;&lt;span class="Identifier"&gt; &lt;/span&gt;&lt;span class="Type"&gt;Text&lt;/span&gt;&lt;span class="Identifier"&gt;=&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;Publicar&amp;quot;&lt;/span&gt;&lt;span class="Identifier"&gt; &lt;/span&gt;&lt;span class="Special"&gt;&lt;br /&gt;OnClick=&amp;quot;&lt;/span&gt;&lt;span class="Special"&gt;btnPublish_click&lt;/span&gt;&lt;span class="Special"&gt;&amp;quot;&lt;/span&gt;&lt;span class="Identifier"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="Identifier"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="Statement"&gt;td&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="Statement"&gt;tr&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="Statement"&gt;table&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Statement"&gt;br&lt;/span&gt;&lt;span class="Identifier"&gt; /&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;asp&lt;span class="Identifier"&gt;:&lt;/span&gt;&lt;span class="Type"&gt;Label&lt;/span&gt;&lt;span class="Identifier"&gt; &lt;/span&gt;&lt;span class="Type"&gt;ID&lt;/span&gt;&lt;span class="Identifier"&gt;=&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;lblmsg&amp;quot;&lt;/span&gt;&lt;span class="Identifier"&gt; runat=&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;server&amp;quot;&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;lt;/&lt;/span&gt;asp&lt;span class="Identifier"&gt;:Label&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="Statement"&gt;div&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="Statement"&gt;form&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="Statement"&gt;body&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="Statement"&gt;html&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p align="justify"&gt;&lt;br /&gt;Como muestra de la  implementación ASP.NET con el control &lt;a href="http://msdn.microsoft.com/en-us/library/ysf0192b%28v=VS.80%29.aspx"&gt;FileUpload&lt;/a&gt;, presentamos el siguiente listado.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;div&gt;&lt;b&gt;Listado 2.0 ASP.NET Upload con un control&lt;/b&gt; &lt;a href="http://msdn.microsoft.com/en-us/library/ysf0192b%28v=VS.80%29.aspx"&gt;FileUpload&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;span class="Special"&gt;&amp;lt;%&lt;/span&gt;@ &lt;span class="Identifier"&gt;Page Language=&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;&lt;/span&gt;&lt;span class="Constant"&gt;C#&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;&lt;/span&gt; &lt;span class="Identifier"&gt;AutoEventWireup=&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;&lt;/span&gt;&lt;span class="Constant"&gt;true&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;&lt;/span&gt;&lt;span class="Special"&gt;%&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Comment"&gt;&amp;lt;!DOCTYPE html PUBLIC &amp;quot;-//W3C//DTD XHTML 1.0 Transitional//EN&amp;quot; &lt;br /&gt;&amp;quot;&lt;a href="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&lt;/a&gt;&amp;quot;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Statement"&gt;script&lt;/span&gt;&lt;span class="Identifier"&gt; runat=&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;server&amp;quot;&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Statement"&gt;protected&lt;/span&gt;&lt;span class="Special"&gt; void Page_Load&lt;/span&gt;(&lt;span class="Type"&gt;object&lt;/span&gt;&lt;span class="Special"&gt; sender, EventArgs e&lt;/span&gt;)&lt;br /&gt;&lt;span class="Identifier"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class="Comment"&gt;//Version 2.0 or above&lt;/span&gt;&lt;br /&gt;&lt;span class="Statement"&gt;public&lt;/span&gt;&lt;span class="Special"&gt; void btnPublish_Click&lt;/span&gt;(&lt;span class="Type"&gt;object&lt;/span&gt;&lt;span class="Special"&gt; sender,EventArgs args&lt;/span&gt;)&lt;span class="Special"&gt; &lt;/span&gt;&lt;span class="Identifier"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span class="Statement"&gt;try&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span class="Type"&gt;string&lt;/span&gt;&lt;span class="Special"&gt; publishPath = System.Configuration.ConfigurationManager.AppSettings&lt;/span&gt;&lt;span class="Identifier"&gt;[&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;publishPath&amp;quot;&lt;/span&gt;&lt;span class="Identifier"&gt;]&lt;/span&gt;&lt;span class="Special"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class="Statement"&gt;if&lt;/span&gt;&lt;span class="Special"&gt; &lt;/span&gt;(&lt;span class="Special"&gt;fupInputFile.HasFile &amp;amp;&amp;amp; &lt;/span&gt;(&lt;span class="Special"&gt;fupInputFile.PostedFile.ContentLength &amp;gt; &lt;/span&gt;0))&lt;br /&gt;&lt;span class="Identifier"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span class="Special"&gt;    Publish&lt;/span&gt;(&lt;span class="Special"&gt;fupInputFile, publishPath&lt;/span&gt;)&lt;span class="Special"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class="Special"&gt;    lblmsg.ForeColor = System.Drawing.Color.Black;&lt;/span&gt;&lt;br /&gt;&lt;span class="Special"&gt;    lblmsg.Text = &lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;Archivo públicado con éxito&amp;quot;&lt;/span&gt;&lt;span class="Special"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class="Statement"&gt;else&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span class="Special"&gt;    lblmsg.ForeColor = System.Drawing.Color.Red;&lt;/span&gt;&lt;br /&gt;&lt;span class="Special"&gt;    lblmsg.Text = &lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;Falta archivo para publicar&amp;quot;&lt;/span&gt;&lt;span class="Special"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class="Statement"&gt;catch&lt;/span&gt;&lt;span class="Special"&gt; &lt;/span&gt;(&lt;span class="Special"&gt;Exception ex&lt;/span&gt;)&lt;span class="Special"&gt; &lt;/span&gt;&lt;span class="Identifier"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span class="Special"&gt;lblmsg.ForeColor = System.Drawing.Color.Red;&lt;/span&gt;&lt;br /&gt;&lt;span class="Special"&gt;lblmsg.Text = ex.Message;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class="Statement"&gt;public&lt;/span&gt;&lt;span class="Special"&gt; void Publish&lt;/span&gt;(&lt;span class="Special"&gt;FileUpload inputFile,&lt;/span&gt;&lt;br /&gt;&lt;span class="Type"&gt;string&lt;/span&gt;&lt;span class="Special"&gt; publishPath&lt;/span&gt;)&lt;span class="Special"&gt; &lt;/span&gt;&lt;span class="Identifier"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span class="Special"&gt;System.IO.FileInfo fi = &lt;/span&gt;&lt;span class="Statement"&gt;new&lt;/span&gt;&lt;span class="Special"&gt; System.IO.FileInfo&lt;/span&gt;(&lt;span class="Special"&gt;inputFile.PostedFile.FileName&lt;/span&gt;)&lt;span class="Special"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class="Type"&gt;string&lt;/span&gt;&lt;span class="Special"&gt; theFile = publishPath + fi.Name;&lt;/span&gt;&lt;br /&gt;&lt;span class="Special"&gt;inputFile.PostedFile.SaveAs&lt;/span&gt;(&lt;span class="Special"&gt;theFile&lt;/span&gt;)&lt;span class="Special"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="Statement"&gt;script&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Statement"&gt;html&lt;/span&gt;&lt;span class="Identifier"&gt; xmlns=&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;&lt;a href="http://www.w3.org/1999/xhtml"&gt;http://www.w3.org/1999/xhtml&lt;/a&gt;&amp;quot;&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Statement"&gt;head&lt;/span&gt;&lt;span class="Identifier"&gt; runat=&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;server&amp;quot;&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Statement"&gt;title&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="Statement"&gt;title&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="Statement"&gt;head&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Statement"&gt;body&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Statement"&gt;form&lt;/span&gt;&lt;span class="Identifier"&gt; &lt;/span&gt;&lt;span class="Type"&gt;id&lt;/span&gt;&lt;span class="Identifier"&gt;=&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;form1&amp;quot;&lt;/span&gt;&lt;span class="Identifier"&gt; runat=&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;server&amp;quot;&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Statement"&gt;div&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Statement"&gt;table&lt;/span&gt;&lt;span class="Identifier"&gt; &lt;/span&gt;&lt;span class="Type"&gt;style&lt;/span&gt;&lt;span class="Identifier"&gt;=&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;width:100%;&amp;quot;&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Statement"&gt;tr&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Statement"&gt;td&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;        1-. Seleccione el archivo&lt;span class="Identifier"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="Statement"&gt;td&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="Statement"&gt;tr&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Statement"&gt;tr&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Statement"&gt;td&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;asp&lt;span class="Identifier"&gt;:FileUpload &lt;/span&gt;&lt;span class="Type"&gt;ID&lt;/span&gt;&lt;span class="Identifier"&gt;=&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;fupInputFile&amp;quot;&lt;/span&gt;&lt;span class="Identifier"&gt; runat=&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;server&amp;quot;&lt;/span&gt;&lt;span class="Identifier"&gt; &lt;/span&gt;&lt;span class="Type"&gt;Width&lt;/span&gt;&lt;span class="Identifier"&gt;=&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;522&amp;quot;&lt;/span&gt;&lt;span class="Identifier"&gt; /&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="Identifier"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="Statement"&gt;td&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="Statement"&gt;tr&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Statement"&gt;tr&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Statement"&gt;td&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;        2-. Pulse el botón publicar&lt;span class="Identifier"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="Statement"&gt;td&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="Statement"&gt;tr&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Statement"&gt;tr&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Statement"&gt;td&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;asp&lt;span class="Identifier"&gt;:Button &lt;/span&gt;&lt;span class="Type"&gt;ID&lt;/span&gt;&lt;span class="Identifier"&gt;=&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;btnPublish&amp;quot;&lt;/span&gt;&lt;span class="Identifier"&gt; runat=&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;server&amp;quot;&lt;/span&gt;&lt;span class="Identifier"&gt; &lt;/span&gt;&lt;span class="Type"&gt;Text&lt;/span&gt;&lt;span class="Identifier"&gt;=&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;Publicar&amp;quot;&lt;/span&gt;&lt;span class="Identifier"&gt; &lt;/span&gt;&lt;span class="Special"&gt;&lt;br /&gt;OnClick=&amp;quot;&lt;/span&gt;&lt;span class="Special"&gt;btnPublish_Click&lt;/span&gt;&lt;span class="Special"&gt;&amp;quot;&lt;/span&gt;&lt;span class="Identifier"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="Identifier"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="Statement"&gt;td&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="Statement"&gt;tr&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="Statement"&gt;table&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Statement"&gt;br&lt;/span&gt;&lt;span class="Identifier"&gt; /&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;asp&lt;span class="Identifier"&gt;:&lt;/span&gt;&lt;span class="Type"&gt;Label&lt;/span&gt;&lt;span class="Identifier"&gt; &lt;/span&gt;&lt;span class="Type"&gt;ID&lt;/span&gt;&lt;span class="Identifier"&gt;=&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;lblmsg&amp;quot;&lt;/span&gt;&lt;span class="Identifier"&gt; runat=&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;server&amp;quot;&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;lt;/&lt;/span&gt;asp&lt;span class="Identifier"&gt;:Label&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="Statement"&gt;div&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="Statement"&gt;form&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="Statement"&gt;body&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="Statement"&gt;html&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p align="justify"&gt;Para ambos casos el archivo de configuración &lt;i&gt;web.config&lt;/i&gt; es el mismo, lo que cambia en ambos casos es el valor de la llave &lt;i&gt;publishPath&lt;/i&gt; dentro de las etiquetas &lt;pre&gt;&amp;lt;appSettings&amp;gt;&lt;/pre&gt;, ya que para el &lt;b&gt;listado 1.0&lt;/b&gt; que lo ejecutaremos en Linux utilizando &lt;a href="http://www.apache.org/"&gt;Apache&lt;/a&gt; y &lt;a href="http://www.mono-project.com/Main_Page"&gt;Mono&lt;/a&gt;. &lt;br /&gt;Por lo que el valor se establece en &lt;i&gt;/home/martin/public_html/Downloads&lt;/i&gt; como se muestra en el &lt;i&gt;web.config&lt;/i&gt; a continuación:&lt;/p&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;span class="Comment"&gt;&amp;lt;?&lt;/span&gt;&lt;span class="Type"&gt;xml&lt;/span&gt;&lt;span class="Type"&gt; &lt;/span&gt;&lt;span class="Type"&gt;version&lt;/span&gt;=&lt;span class="Constant"&gt;&amp;quot;1.0&amp;quot;&lt;/span&gt;&lt;span class="Comment"&gt;?&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Identifier"&gt;configuration&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Identifier"&gt;appSettings&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Identifier"&gt;add&lt;/span&gt;&lt;span class="Identifier"&gt; &lt;/span&gt;&lt;span class="Type"&gt;key&lt;/span&gt;=&lt;span class="Constant"&gt;&amp;quot;publishPath&amp;quot;&lt;/span&gt;&lt;span class="Identifier"&gt; &lt;/span&gt;&lt;span class="Type"&gt;value&lt;/span&gt;=&lt;span class="Constant"&gt;&amp;quot;/home/martin/public_html/Downloads/&amp;quot;&lt;/span&gt;&lt;span class="Identifier"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span class="Identifier"&gt;&amp;lt;/appSettings&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Identifier"&gt;connectionStrings&lt;/span&gt;&lt;span class="Identifier"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Identifier"&gt;system&lt;/span&gt;&lt;span class="Comment"&gt;.&lt;/span&gt;&lt;span class="Identifier"&gt;web&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;                &lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Identifier"&gt;compilation&lt;/span&gt;&lt;span class="Identifier"&gt; &lt;/span&gt;&lt;span class="Type"&gt;debug&lt;/span&gt;=&lt;span class="Constant"&gt;&amp;quot;true&amp;quot;&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;                &lt;span class="Identifier"&gt;&amp;lt;/compilation&amp;gt;&lt;/span&gt;&lt;br /&gt;                &lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Identifier"&gt;authentication&lt;/span&gt;&lt;span class="Identifier"&gt; &lt;/span&gt;&lt;span class="Type"&gt;mode&lt;/span&gt;=&lt;span class="Constant"&gt;&amp;quot;Windows&amp;quot;&lt;/span&gt;&lt;span class="Identifier"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span class="Identifier"&gt;&amp;lt;/system&lt;/span&gt;&lt;span class="Comment"&gt;.&lt;/span&gt;&lt;span class="Identifier"&gt;web&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;/configuration&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;   &lt;br /&gt;&lt;div&gt;En el caso del &lt;b&gt;listado 2.0&lt;/b&gt; lo ejecutaremos en IIS 7.0 y Windows. Por lo que el valor se establece como se muestra en el &lt;i&gt;web.config&lt;/i&gt; a continuación:&lt;/div&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;span class="Comment"&gt;&amp;lt;?&lt;/span&gt;&lt;span class="Type"&gt;xml&lt;/span&gt;&lt;span class="Type"&gt; &lt;/span&gt;&lt;span class="Type"&gt;version&lt;/span&gt;=&lt;span class="Constant"&gt;&amp;quot;1.0&amp;quot;&lt;/span&gt;&lt;span class="Comment"&gt;?&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Identifier"&gt;configuration&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Identifier"&gt;appSettings&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Identifier"&gt;add&lt;/span&gt;&lt;span class="Identifier"&gt; &lt;/span&gt;&lt;span class="Type"&gt;key&lt;/span&gt;=&lt;span class="Constant"&gt;&amp;quot;publishPath&amp;quot;&lt;/span&gt;&lt;span class="Identifier"&gt; &lt;/span&gt;&lt;span class="Type"&gt;value&lt;/span&gt;=&lt;span class="Constant"&gt;&amp;quot;C:\inetpub\Downloads\&amp;quot;&lt;/span&gt;&lt;span class="Identifier"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span class="Identifier"&gt;&amp;lt;/appSettings&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Identifier"&gt;connectionStrings&lt;/span&gt;&lt;span class="Identifier"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Identifier"&gt;system&lt;/span&gt;&lt;span class="Comment"&gt;.&lt;/span&gt;&lt;span class="Identifier"&gt;web&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;                &lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Identifier"&gt;compilation&lt;/span&gt;&lt;span class="Identifier"&gt; &lt;/span&gt;&lt;span class="Type"&gt;debug&lt;/span&gt;=&lt;span class="Constant"&gt;&amp;quot;true&amp;quot;&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;                &lt;span class="Identifier"&gt;&amp;lt;/compilation&amp;gt;&lt;/span&gt;&lt;br /&gt;                &lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Identifier"&gt;authentication&lt;/span&gt;&lt;span class="Identifier"&gt; &lt;/span&gt;&lt;span class="Type"&gt;mode&lt;/span&gt;=&lt;span class="Constant"&gt;&amp;quot;Windows&amp;quot;&lt;/span&gt;&lt;span class="Identifier"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span class="Identifier"&gt;&amp;lt;/system&lt;/span&gt;&lt;span class="Comment"&gt;.&lt;/span&gt;&lt;span class="Identifier"&gt;web&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;/configuration&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div&gt;Para asignar el valor de la variable &lt;i&gt;publishPath&lt;/i&gt; en el &lt;b&gt;listado 1.0&lt;/b&gt; con la siguiente línea:&lt;/div&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;string publishPath = ConfigurationSettings.AppSettings["publishPath"];&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div&gt;y para el &lt;b&gt;listado 2.0&lt;/b&gt; se asigna con la siguiente línea:&lt;/div&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;string publishPath = System.Configuration.ConfigurationManager.AppSettings["publishPath"];&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p align="justify"&gt;Antes de ejecutar la página en Linux  debemos  habilitar con los permisos de escritura al directorio donde se guardaran los archivos, para hacerlo en Linux siga los siguientes pasos:&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;El directorio donde se subiran los archivos debe tener los permisos de escritura para el grupo www.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Si estamos como usuarios normales, cambiamos a una cuenta con privilegios de superusuario y establecemos y establecemos el grupo del directorio (en este ejemplo /home/martin/public_html/Downloads) como www con el siguiente comando:&lt;br /&gt;&lt;pre&gt;# chgrp www Downloads&lt;/pre&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Ponemos permisos de escritura para el grupo con el siguiente comando:&lt;br /&gt;&lt;pre&gt;# chmod 775 Downloads&lt;/pre&gt;&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;div&gt;Estos comandos se muestran a continuación en la siguiente imagen.&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/upload/fig6.png"&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;Ahora configuramos la &lt;i&gt;Web Application&lt;/i&gt; dentro del archivo &lt;i&gt;httpd.conf&lt;/i&gt; del servidor Apache como se muestra en la siguiente imagen:&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/upload/fig9.png"&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;Para consultar como crear una aplicación Web en Apache revisar el siguiente documento: &lt;a href="http://www.humansharp.com/docs/EntendiendoADOMono3.pdf"&gt;ASP.NET con Mono&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;p align="justify"&gt;Igualmente antes de ejecutar la página en Windows debemos de habilitar con los permisos necesarios el directorio del servidor donde vamos a guardar los documentos, en este ejemplo la ruta configurada como directorio de publicación es &lt;i&gt;C:\inetpub\wwwroot\dowloads&lt;/i&gt;, por lo que debemos seguir los siguientes pasos:&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;Hacer click derecho sobre el directorio, en la ventana &lt;i&gt;Properties&lt;/i&gt; seleccionar al usuario IIS_IUSRS (el cuál es el usuario anónimo de IIS), presionar el botón “Edit”  para abrir la ventana &lt;i&gt;Permissions&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/upload/fig3.png"&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;En la ventana de &lt;i&gt;Permissions&lt;/i&gt; en la lista inferior &lt;i&gt;Permissions for IIS_IUSRS&lt;/i&gt; seleccionar la casilla con el permiso &lt;i&gt;Write&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/upload/fig4.png"&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;Creamos la &lt;i&gt;Web Application&lt;/i&gt; de forma que se muestre en IIS 7.0 como en la siguiente imagen:&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/upload/fig10.png"&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Al ejecutar la página ASP.NET desde FireFox en Linux se mostrará como en las siguientes imágenes:&lt;br /&gt; &lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/upload/fig7.png"&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/upload/fig8.png"&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Al ejecutar la página ASP.NET desde Internet Explorer en Windows se verá como en las siguientes imágenes:&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/upload/fig1.png"&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/upload/fig2.png"&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p align="justify"&gt;&lt;br /&gt;Un error frecuente tanto para la implementación con HtmlInputFile y FileUpload, es tratar de subir un archivo que tenga un tamaño mayor al máximo permitido por la petición al servidor Web &lt;i&gt;(Request)&lt;/i&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/upload/fig5.png"&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Para solucionar este error solo hay que agregar la siguiente línea al archivo de configuración, donde definimos el tamaño máximo en Kb del archivo que necesitamos publicar. Por ejemplo en el siguiente web.config se definió un tamaño máximo aproximado a 5 mbs (5120 kb).&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;span class="Comment"&gt;&amp;lt;?&lt;/span&gt;&lt;span class="Type"&gt;xml&lt;/span&gt;&lt;span class="Type"&gt; &lt;/span&gt;&lt;span class="Type"&gt;version&lt;/span&gt;=&lt;span class="Constant"&gt;&amp;quot;1.0&amp;quot;&lt;/span&gt;&lt;span class="Comment"&gt;?&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Identifier"&gt;configuration&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Identifier"&gt;appSettings&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Identifier"&gt;add&lt;/span&gt;&lt;span class="Identifier"&gt; &lt;/span&gt;&lt;span class="Type"&gt;key&lt;/span&gt;=&lt;span class="Constant"&gt;&amp;quot;publishPath&amp;quot;&lt;/span&gt;&lt;span class="Identifier"&gt; &lt;/span&gt;&lt;span class="Type"&gt;value&lt;/span&gt;=&lt;span class="Constant"&gt;&amp;quot;C:\inetpub\Downloads\&amp;quot;&lt;/span&gt;&lt;span class="Identifier"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span class="Identifier"&gt;&amp;lt;/appSettings&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Identifier"&gt;connectionStrings&lt;/span&gt;&lt;span class="Identifier"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Identifier"&gt;system&lt;/span&gt;&lt;span class="Comment"&gt;.&lt;/span&gt;&lt;span class="Identifier"&gt;web&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;                &lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Identifier"&gt;compilation&lt;/span&gt;&lt;span class="Identifier"&gt; &lt;/span&gt;&lt;span class="Type"&gt;debug&lt;/span&gt;=&lt;span class="Constant"&gt;&amp;quot;true&amp;quot;&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;                &lt;span class="Identifier"&gt;&amp;lt;/compilation&amp;gt;&lt;/span&gt;&lt;br /&gt;                &lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Identifier"&gt;authentication&lt;/span&gt;&lt;span class="Identifier"&gt; &lt;/span&gt;&lt;span class="Type"&gt;mode&lt;/span&gt;=&lt;span class="Constant"&gt;&amp;quot;Windows&amp;quot;&lt;/span&gt;&lt;span class="Identifier"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;                &lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Identifier"&gt;httpRuntime&lt;/span&gt;&lt;span class="Identifier"&gt; &lt;/span&gt;&lt;span class="Type"&gt;maxRequestLength&lt;/span&gt;=&lt;span class="Constant"&gt;&amp;quot;5120&amp;quot;&lt;/span&gt;&lt;span class="Identifier"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span class="Identifier"&gt;&amp;lt;/system&lt;/span&gt;&lt;span class="Comment"&gt;.&lt;/span&gt;&lt;span class="Identifier"&gt;web&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;&amp;lt;/configuration&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Para más información sobre este error consultar este enlace: &lt;a href="http://www.vishwamohan.com/post/2006/12/30/Error-SystemWebHttpException-Maximum-request-length-exceeded.aspx"&gt;HttpException Maximum Request Length.&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;h3&gt;&lt;a href="http://www.humansharp.com/Code/Publish.zip"&gt;&lt;img src="http://www.humansharp.com/picture_library/dw.jpg" border="0"&gt;Descarga el código fuente del ASP.NET con HtmlInputFile (Framework 1.1)&lt;/a&gt;&lt;/h3&gt;&lt;br /&gt;&lt;h3&gt;&lt;a href="http://www.humansharp.com/Code/PublishFile2.zip"&gt;&lt;img src="http://www.humansharp.com/picture_library/dw.jpg" border="0"&gt;Descarga el código fuente del ASP.NET con FileUpload (Framework 2.0)&lt;/a&gt;&lt;/h3&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6494419861240446187-8865975566319395365?l=xomalli.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/8865975566319395365'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/8865975566319395365'/><link rel='alternate' type='text/html' href='http://xomalli.blogspot.com/2011/06/file-upload-con-aspnet-en-linux-y.html' title='File Upload con ASP.NET en Linux y Apache con HtmlInputFile (Html Control) y en IIS y Windows con FileUpload (Web Control).'/><author><name>Martín Márquez</name><uri>http://www.blogger.com/profile/10939957618126542300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_j4WRR9G9bfY/SV2_nw3UxeI/AAAAAAAAAAM/nT3SYp94IHo/s1600-R/photo.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-6494419861240446187.post-2266065519724119333</id><published>2011-06-25T19:46:00.001-07:00</published><updated>2011-06-25T21:36:23.884-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Windows'/><title type='text'>Utilizando Windows Management Instrumentation (WMI) con Microsoft .NET</title><content type='html'>&lt;p align="justify"&gt;Para las aplicaciones que necesiten implementar una solución de un inventario total o parcial del hardware de la computadora, existe  una interfaz de programación llamada &lt;a href="http://msdn.microsoft.com/en-us/library/aa394582%28v=vs.85%29.aspx"&gt;WMI&lt;/a&gt; (Windows Management Instrumentation) a la cual puede accederse mediante lenguajes scripting como VBScript, Perl,Power Shell o cualquier lenguaje diseñado para el .NET Framework   que haga  uso de  los ensamblados System.Management y System.Management.Instrumentation respectivamente.&lt;/p&gt;&lt;br /&gt;&lt;p align="justify"&gt;Windows Management Instrumentation &lt;b&gt;(WMI)&lt;/b&gt; es un conjunto de extensiones del Modelo de drivers de Windows &lt;b&gt;WDM (Windows Driver Model)&lt;/b&gt; que es un modelo uniforme de clases que representan los valores del hardware y sistema operativo de la computadora,&lt;b&gt;WMI&lt;/b&gt; es además la implementación Microsoft de &lt;b&gt;Web-Based Enterprise Management (WBEM)&lt;/b&gt; un estándar de la industria que agrupa  tecnologías desarrolladas para unificar la administración de los ambientes de computo, por lo que &lt;b&gt;WMI&lt;/b&gt; es compatible con &lt;b&gt;WBEM&lt;/b&gt; y provee el soporte para el &lt;b&gt;Common Information Model (CIM)&lt;/b&gt; que es el modelo que describe los objetos de administración.&lt;/p&gt;&lt;br /&gt;&lt;p align="justify"&gt;Un inventario de hardware con WMI se realiza mediante búsquedas en el repositorio o base de datos de WMI  utilizando un lenguaje de consultas conocido como &lt;b&gt;WQL (WMI Query Language)&lt;/b&gt; para encontrar los valores de ciertas propiedades del Hardware. WQL es un subconjunto de SQL.&lt;/p&gt;&lt;br /&gt;&lt;p align="justify"&gt;WMI trabaja dentro del contexto de un ensamblado, siendo el predeterminado root\cli que controla las propiedades y métodos que están disponibles en &lt;b&gt;WMI&lt;/b&gt;, la seguridad para el &lt;b&gt;WMI&lt;/b&gt; se configura a través del control &lt;b&gt;WMI&lt;/b&gt; (wmimgmt.msc), de forma predeterminada los usuarios tienen permisos para consultar el proveedor &lt;b&gt;WMI&lt;/b&gt; en una computadora local mediante el comando &lt;i&gt;WMIC&lt;/i&gt;, desde la línea de comandos del command prompt.&lt;/p&gt;&lt;br /&gt;&lt;div&gt;A continuación el listado de un programa de consola que imprime información del hardware del equipo.&lt;/div&gt;&lt;br /&gt;&lt;div&gt;1-.Una clase PC que será el objeto de transporte&lt;/div&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;using System;&lt;br /&gt;using System.Collections.Generic;&lt;br /&gt;using System.Text;&lt;br /&gt;&lt;br /&gt;namespace PCProperties.Lib&lt;br /&gt;{&lt;br /&gt;public class PC&lt;br /&gt;{&lt;br /&gt;    public string RamMemory { set; get; }&lt;br /&gt;    public string Processor { set; get; }&lt;br /&gt;    public string IPAddress { set; get; }&lt;br /&gt;    public string MacAddress { set; get; }&lt;br /&gt;    public string OperatingSystem { set; get; }&lt;br /&gt;    public string OperatingSystemVersion { set; get; }&lt;br /&gt;    public string OperatingArch { set; get; }&lt;br /&gt;    public string HardDisk { set; get; }&lt;br /&gt;    public string Monitor { set; get; }&lt;br /&gt;    public string MonitorType { set; get; }&lt;br /&gt;    public string CdRom { set; get; }&lt;br /&gt;    public string ProcessorSpeed { set; get; }&lt;br /&gt;    &lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div&gt;2-.Una clase &lt;i&gt;PCManager&lt;/i&gt; que obtendrá algunos de los valores del Hardware para este ejemplo, mediante consultas WQL del repositorio &lt;b&gt;WMI&lt;/b&gt; similar a las consultas SQL para en base de datos.&lt;/div&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;using System;&lt;br /&gt;using System.Collections;&lt;br /&gt;using System.Text;&lt;br /&gt;using System.Management;&lt;br /&gt;using System.Management.Instrumentation;&lt;br /&gt;using System.Runtime.InteropServices;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;namespace PCProperties.Lib&lt;br /&gt;{&lt;br /&gt;public class PCManager&lt;br /&gt;{&lt;br /&gt;static ManagementObjectSearcher searcher = null;&lt;br /&gt;PC pcomputer = null;&lt;br /&gt;&lt;br /&gt;public PCManager() {&lt;br /&gt;searcher = new ManagementObjectSearcher();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public PC Select() {&lt;br /&gt;pcomputer = new PC();&lt;br /&gt;searcher.Query = new ObjectQuery("Select * from Win32_DesktopMonitor");&lt;br /&gt;ManagementObjectCollection coll = searcher.Get();&lt;br /&gt;&lt;br /&gt;foreach (ManagementObject objmng in coll)&lt;br /&gt;{&lt;br /&gt;pcomputer.Monitor = objmng["MonitorManufacturer"].ToString();&lt;br /&gt;pcomputer.MonitorType = objmng["Name"].ToString();&lt;br /&gt;}            &lt;br /&gt;searcher.Query = new ObjectQuery("Select * from Win32_OperatingSystem");&lt;br /&gt;coll = searcher.Get();&lt;br /&gt;foreach (ManagementObject objmng in coll)&lt;br /&gt;{&lt;br /&gt;pcomputer.RamMemory = objmng["TotalVisibleMemorySize"].ToString() + "Mb";&lt;br /&gt;pcomputer.OperatingSystem = objmng["Name"].ToString();&lt;br /&gt;pcomputer.OperatingSystemVersion = objmng["Version"].ToString();&lt;br /&gt;}&lt;br /&gt;searcher.Query = new ObjectQuery("Select * from Win32_DiskDrive");&lt;br /&gt;coll = searcher.Get();&lt;br /&gt;foreach (ManagementObject objmng in coll)&lt;br /&gt;pcomputer.HardDisk = (Convert.ToDouble(objmng["Size"]) &lt;br /&gt;    / 1024000).ToString() + "Mb";&lt;br /&gt;searcher.Query = new ObjectQuery("Select * from Win32_CDROMDrive");&lt;br /&gt;coll = searcher.Get();&lt;br /&gt;foreach (ManagementObject objmng in coll)&lt;br /&gt;pcomputer.CdRom = objmng["Name"].ToString();&lt;br /&gt;searcher.Query = new ObjectQuery("Select * from Win32_Processor");&lt;br /&gt;coll = searcher.Get();&lt;br /&gt;foreach (ManagementObject objmng in coll)&lt;br /&gt;{&lt;br /&gt;pcomputer.ProcessorSpeed = objmng["MaxClockSpeed"].ToString();&lt;br /&gt;pcomputer.Processor = objmng["Name"].ToString();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;searcher.Query = new ObjectQuery("Select * from Win32_NetworkAdapterConfiguration");&lt;br /&gt;coll = searcher.Get();&lt;br /&gt;foreach (ManagementObject objmng in coll)&lt;br /&gt;{&lt;br /&gt;if (string.IsNullOrEmpty(pcomputer.MacAddress) &amp;&amp;&lt;br /&gt;string.IsNullOrEmpty(pcomputer.IPAddress))&lt;br /&gt;{&lt;br /&gt;pcomputer.MacAddress = objmng["MacAddress"].ToString();&lt;br /&gt;pcomputer.IPAddress = ((string[])(objmng["IPAddress"]))[0];&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;return pcomputer;&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div&gt;3-.Finalmente el programa de consola principal que despliega información del equipo.&lt;/div&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;using System;&lt;br /&gt;using System.Collections.Generic;&lt;br /&gt;using System.Text;&lt;br /&gt;using System.Collections;&lt;br /&gt;using PCProperties.Lib;&lt;br /&gt;&lt;br /&gt;namespace PCProperties&lt;br /&gt;{&lt;br /&gt;class Program&lt;br /&gt;{&lt;br /&gt;static void Main(string[] args)&lt;br /&gt;{&lt;br /&gt;PC pc = new PCManager().Select();&lt;br /&gt;Console.WriteLine("\n Propiedades del equipo");&lt;br /&gt;Console.WriteLine("===============================\n");&lt;br /&gt;Console.WriteLine(" Memoria RAM\t[ {0} ]", pc.RamMemory);&lt;br /&gt;Console.WriteLine(" Procesador\t[ {0} ]", pc.Processor);&lt;br /&gt;Console.WriteLine(" IP:\t[ {0} ]", pc.IPAddress);&lt;br /&gt;Console.WriteLine(" SO:\t[ {0} ]\n", pc.OperatingSystem);&lt;br /&gt;Console.WriteLine(" Disco:\t[ {0} ]", pc.HardDisk);&lt;br /&gt;Console.WriteLine(" Monitor:\t[ {0} ]", pc.Monitor);&lt;br /&gt;Console.WriteLine(" Tipo Monitor:\t[ {0} ]", pc.MonitorType);&lt;br /&gt;Console.WriteLine(" Cdrom:\t[ {0} ]", pc.CdRom);&lt;br /&gt;Console.WriteLine(" Velocidad del procesador:\t[ {0} ]", pc.ProcessorSpeed);&lt;br /&gt;&lt;br /&gt;Console.ReadLine();&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div&gt;El resultado de la ejecución del programa se muestra en la siguiente imagen:&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/wmi/fig1.png"&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;Los puntos claves del programa utilizados por la clase &lt;i&gt;PCManager&lt;/i&gt; son &lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;Utilizar los ensamblados &lt;i&gt;System.Management&lt;/i&gt; y &lt;i&gt;System.Management.Instrumentation&lt;/i&gt;.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Crear una instancia de la clase &lt;a href="http://msdn.microsoft.com/en-us/library/system.management.managementobjectsearcher.aspx"&gt;ManagementObjectSearcher&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Encapsular cada consulta dentro de la clase &lt;i&gt;ObjectQuery&lt;/i&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Obtener los resultados de la búsqueda en una colección de &lt;a href=""&gt;ManagementObject&lt;/a&gt; representada por la clase  &lt;a href="http://msdn.microsoft.com/en-us/library/system.management.managementobjectcollection.aspx"&gt;ManagementObjectCollection&lt;/a&gt;, para iterar dentro de la colección e imprimir los valores.&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;div&gt;También se puede mostrar información desde una página ASP.NET como en el siguiente listado:&lt;/div&gt;&lt;br /&gt;&lt;div style="background:whitesmoke"&gt;&lt;br /&gt;&lt;font face="monospace"&gt;&lt;br /&gt;&lt;font color="#6a5acd"&gt;&amp;lt;%&lt;/font&gt;@ &lt;font color="#008080"&gt;Page&lt;/font&gt;&amp;nbsp;&lt;font color="#008080"&gt;Language&lt;/font&gt;=&lt;font color="#ff00ff"&gt;&amp;quot;&lt;/font&gt;&lt;font color="#ff00ff"&gt;C#&lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;quot;&lt;/font&gt;&amp;nbsp;&lt;font color="#008080"&gt;AutoEventWireup&lt;/font&gt;=&lt;font color="#ff00ff"&gt;&amp;quot;&lt;/font&gt;&lt;font color="#ff00ff"&gt;true&lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;quot;&lt;/font&gt;&amp;nbsp;&lt;font color="#6a5acd"&gt;%&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&lt;font color="#6a5acd"&gt;&amp;lt;%&lt;/font&gt;@ &lt;font color="#804040"&gt;&lt;b&gt;Import&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#008080"&gt;Namespace&lt;/font&gt;=&lt;font color="#ff00ff"&gt;&amp;quot;&lt;/font&gt;&lt;font color="#ff00ff"&gt;PCProperties.Lib&lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;quot;&lt;/font&gt;&lt;font color="#6a5acd"&gt;%&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&lt;font color="#0000ff"&gt;&amp;lt;!DOCTYPE html PUBLIC &amp;quot;-//W3C//DTD XHTML 1.0 Transitional//EN&amp;quot; &lt;/font&gt;&lt;br&gt;&lt;br /&gt;&lt;font color="#0000ff"&gt;&amp;quot;&lt;a href="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&lt;/a&gt;&amp;quot;&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&lt;br&gt;&lt;br /&gt;&lt;font color="#008080"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#804040"&gt;&lt;b&gt;script&lt;/b&gt;&lt;/font&gt;&lt;font color="#008080"&gt;&amp;nbsp;runat=&lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;quot;server&amp;quot;&lt;/font&gt;&lt;font color="#008080"&gt;&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&lt;font color="#6a5acd"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#804040"&gt;&lt;b&gt;protected&lt;/b&gt;&lt;/font&gt;&lt;font color="#6a5acd"&gt;&amp;nbsp;PC pc = &lt;/font&gt;&lt;font color="#804040"&gt;&lt;b&gt;null&lt;/b&gt;&lt;/font&gt;&lt;font color="#6a5acd"&gt;;&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&lt;font color="#804040"&gt;&lt;b&gt;protected&lt;/b&gt;&lt;/font&gt;&lt;font color="#6a5acd"&gt;&amp;nbsp;void Page_Load&lt;/font&gt;(&lt;font color="#2e8b57"&gt;&lt;b&gt;object&lt;/b&gt;&lt;/font&gt;&lt;font color="#6a5acd"&gt;&amp;nbsp;sender, EventArgs e&lt;/font&gt;)&lt;br&gt;&lt;br /&gt;&lt;font color="#008080"&gt;{&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&lt;font color="#6a5acd"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&lt;font color="#6a5acd"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#804040"&gt;&lt;b&gt;try&lt;/b&gt;&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&lt;font color="#6a5acd"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#008080"&gt;{&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&lt;font color="#6a5acd"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;pc = &lt;/font&gt;&lt;font color="#804040"&gt;&lt;b&gt;new&lt;/b&gt;&lt;/font&gt;&lt;font color="#6a5acd"&gt;&amp;nbsp;PCManager&lt;/font&gt;()&lt;font color="#6a5acd"&gt;.Select&lt;/font&gt;()&lt;font color="#6a5acd"&gt;;&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&lt;font color="#6a5acd"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#008080"&gt;}&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&lt;font color="#6a5acd"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#804040"&gt;&lt;b&gt;catch&lt;/b&gt;&lt;/font&gt;&lt;font color="#6a5acd"&gt;&amp;nbsp;&lt;/font&gt;(&lt;font color="#6a5acd"&gt;Exception ex&lt;/font&gt;)&lt;font color="#6a5acd"&gt;&amp;nbsp;&lt;/font&gt;&lt;font color="#008080"&gt;{&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&lt;font color="#6a5acd"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;lblStatus.Text = ex.Message;&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&lt;font color="#6a5acd"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#008080"&gt;}&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&lt;font color="#008080"&gt;}&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&lt;font color="#008080"&gt;&amp;lt;/&lt;/font&gt;&lt;font color="#804040"&gt;&lt;b&gt;script&lt;/b&gt;&lt;/font&gt;&lt;font color="#008080"&gt;&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&lt;br&gt;&lt;br /&gt;&lt;font color="#008080"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#804040"&gt;&lt;b&gt;html&lt;/b&gt;&lt;/font&gt;&lt;font color="#008080"&gt;&amp;nbsp;xmlns=&lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;quot;&lt;a href="http://www.w3.org/1999/xhtml"&gt;http://www.w3.org/1999/xhtml&lt;/a&gt;&amp;quot;&lt;/font&gt;&lt;font color="#008080"&gt;&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&lt;font color="#008080"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#804040"&gt;&lt;b&gt;head&lt;/b&gt;&lt;/font&gt;&lt;font color="#008080"&gt;&amp;nbsp;runat=&lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;quot;server&amp;quot;&lt;/font&gt;&lt;font color="#008080"&gt;&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&lt;font color="#008080"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#804040"&gt;&lt;b&gt;title&lt;/b&gt;&lt;/font&gt;&lt;font color="#008080"&gt;&amp;gt;&lt;/font&gt;&lt;font color="#008080"&gt;&amp;lt;/&lt;/font&gt;&lt;font color="#804040"&gt;&lt;b&gt;title&lt;/b&gt;&lt;/font&gt;&lt;font color="#008080"&gt;&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&lt;font color="#008080"&gt;&amp;lt;/&lt;/font&gt;&lt;font color="#804040"&gt;&lt;b&gt;head&lt;/b&gt;&lt;/font&gt;&lt;font color="#008080"&gt;&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&lt;font color="#008080"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#804040"&gt;&lt;b&gt;body&lt;/b&gt;&lt;/font&gt;&lt;font color="#008080"&gt;&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&lt;font color="#008080"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#804040"&gt;&lt;b&gt;form&lt;/b&gt;&lt;/font&gt;&lt;font color="#008080"&gt;&amp;nbsp;&lt;/font&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;id&lt;/b&gt;&lt;/font&gt;&lt;font color="#008080"&gt;=&lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;quot;form1&amp;quot;&lt;/font&gt;&lt;font color="#008080"&gt;&amp;nbsp;runat=&lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;quot;server&amp;quot;&lt;/font&gt;&lt;font color="#008080"&gt;&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&lt;font color="#008080"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#804040"&gt;&lt;b&gt;div&lt;/b&gt;&lt;/font&gt;&lt;font color="#008080"&gt;&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&lt;br&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#008080"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#804040"&gt;&lt;b&gt;table&lt;/b&gt;&lt;/font&gt;&lt;font color="#008080"&gt;&amp;nbsp;&lt;/font&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;width&lt;/b&gt;&lt;/font&gt;&lt;font color="#008080"&gt;=&lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;quot;66%&amp;quot;&lt;/font&gt;&lt;font color="#008080"&gt;&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#008080"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#804040"&gt;&lt;b&gt;tr&lt;/b&gt;&lt;/font&gt;&lt;font color="#008080"&gt;&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#008080"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#804040"&gt;&lt;b&gt;td&lt;/b&gt;&lt;/font&gt;&lt;font color="#008080"&gt;&amp;nbsp;&lt;/font&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;width&lt;/b&gt;&lt;/font&gt;&lt;font color="#008080"&gt;=&lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;quot;28%&amp;quot;&lt;/font&gt;&lt;font color="#008080"&gt;&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Memoria Ram&lt;font color="#008080"&gt;&amp;lt;/&lt;/font&gt;&lt;font color="#804040"&gt;&lt;b&gt;td&lt;/b&gt;&lt;/font&gt;&lt;font color="#008080"&gt;&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#008080"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#804040"&gt;&lt;b&gt;td&lt;/b&gt;&lt;/font&gt;&lt;font color="#008080"&gt;&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#6a5acd"&gt;&amp;amp;nbsp;&lt;/font&gt;&lt;font color="#6a5acd"&gt;&amp;lt;%&lt;/font&gt;=&lt;font color="#008080"&gt;pc&lt;/font&gt;.&lt;font color="#008080"&gt;RamMemory&lt;/font&gt;&lt;font color="#6a5acd"&gt;%&amp;gt;&lt;/font&gt;&lt;font color="#008080"&gt;&amp;lt;/&lt;/font&gt;&lt;font color="#804040"&gt;&lt;b&gt;td&lt;/b&gt;&lt;/font&gt;&lt;font color="#008080"&gt;&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#008080"&gt;&amp;lt;/&lt;/font&gt;&lt;font color="#804040"&gt;&lt;b&gt;tr&lt;/b&gt;&lt;/font&gt;&lt;font color="#008080"&gt;&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#008080"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#804040"&gt;&lt;b&gt;tr&lt;/b&gt;&lt;/font&gt;&lt;font color="#008080"&gt;&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#008080"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#804040"&gt;&lt;b&gt;td&lt;/b&gt;&lt;/font&gt;&lt;font color="#008080"&gt;&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Procesador&lt;font color="#008080"&gt;&amp;lt;/&lt;/font&gt;&lt;font color="#804040"&gt;&lt;b&gt;td&lt;/b&gt;&lt;/font&gt;&lt;font color="#008080"&gt;&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#008080"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#804040"&gt;&lt;b&gt;td&lt;/b&gt;&lt;/font&gt;&lt;font color="#008080"&gt;&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#6a5acd"&gt;&amp;amp;nbsp;&lt;/font&gt;&lt;font color="#6a5acd"&gt;&amp;lt;%&lt;/font&gt;=&lt;font color="#008080"&gt;pc&lt;/font&gt;.&lt;font color="#008080"&gt;Processor&lt;/font&gt;&lt;font color="#6a5acd"&gt;%&amp;gt;&lt;/font&gt;&lt;font color="#008080"&gt;&amp;lt;/&lt;/font&gt;&lt;font color="#804040"&gt;&lt;b&gt;td&lt;/b&gt;&lt;/font&gt;&lt;font color="#008080"&gt;&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#008080"&gt;&amp;lt;/&lt;/font&gt;&lt;font color="#804040"&gt;&lt;b&gt;tr&lt;/b&gt;&lt;/font&gt;&lt;font color="#008080"&gt;&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#008080"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#804040"&gt;&lt;b&gt;tr&lt;/b&gt;&lt;/font&gt;&lt;font color="#008080"&gt;&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#008080"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#804040"&gt;&lt;b&gt;td&lt;/b&gt;&lt;/font&gt;&lt;font color="#008080"&gt;&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;IP&lt;font color="#008080"&gt;&amp;lt;/&lt;/font&gt;&lt;font color="#804040"&gt;&lt;b&gt;td&lt;/b&gt;&lt;/font&gt;&lt;font color="#008080"&gt;&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#008080"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#804040"&gt;&lt;b&gt;td&lt;/b&gt;&lt;/font&gt;&lt;font color="#008080"&gt;&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#6a5acd"&gt;&amp;amp;nbsp;&lt;/font&gt;&lt;font color="#6a5acd"&gt;&amp;lt;%&lt;/font&gt;=&lt;font color="#008080"&gt;pc&lt;/font&gt;.&lt;font color="#008080"&gt;IPAddress&lt;/font&gt;&lt;font color="#6a5acd"&gt;%&amp;gt;&lt;/font&gt;&lt;font color="#008080"&gt;&amp;lt;/&lt;/font&gt;&lt;font color="#804040"&gt;&lt;b&gt;td&lt;/b&gt;&lt;/font&gt;&lt;font color="#008080"&gt;&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#008080"&gt;&amp;lt;/&lt;/font&gt;&lt;font color="#804040"&gt;&lt;b&gt;tr&lt;/b&gt;&lt;/font&gt;&lt;font color="#008080"&gt;&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#008080"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#804040"&gt;&lt;b&gt;tr&lt;/b&gt;&lt;/font&gt;&lt;font color="#008080"&gt;&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#008080"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#804040"&gt;&lt;b&gt;td&lt;/b&gt;&lt;/font&gt;&lt;font color="#008080"&gt;&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;SO&lt;font color="#008080"&gt;&amp;lt;/&lt;/font&gt;&lt;font color="#804040"&gt;&lt;b&gt;td&lt;/b&gt;&lt;/font&gt;&lt;font color="#008080"&gt;&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#008080"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#804040"&gt;&lt;b&gt;td&lt;/b&gt;&lt;/font&gt;&lt;font color="#008080"&gt;&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#6a5acd"&gt;&amp;amp;nbsp;&lt;/font&gt;&lt;font color="#6a5acd"&gt;&amp;lt;%&lt;/font&gt;=&lt;font color="#008080"&gt;pc&lt;/font&gt;.&lt;font color="#008080"&gt;OperatingSystem&lt;/font&gt;&lt;font color="#6a5acd"&gt;%&amp;gt;&lt;/font&gt;&lt;font color="#008080"&gt;&amp;lt;/&lt;/font&gt;&lt;font color="#804040"&gt;&lt;b&gt;td&lt;/b&gt;&lt;/font&gt;&lt;font color="#008080"&gt;&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#008080"&gt;&amp;lt;/&lt;/font&gt;&lt;font color="#804040"&gt;&lt;b&gt;tr&lt;/b&gt;&lt;/font&gt;&lt;font color="#008080"&gt;&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#008080"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#804040"&gt;&lt;b&gt;tr&lt;/b&gt;&lt;/font&gt;&lt;font color="#008080"&gt;&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#008080"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#804040"&gt;&lt;b&gt;td&lt;/b&gt;&lt;/font&gt;&lt;font color="#008080"&gt;&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Disco duro&lt;font color="#008080"&gt;&amp;lt;/&lt;/font&gt;&lt;font color="#804040"&gt;&lt;b&gt;td&lt;/b&gt;&lt;/font&gt;&lt;font color="#008080"&gt;&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#008080"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#804040"&gt;&lt;b&gt;td&lt;/b&gt;&lt;/font&gt;&lt;font color="#008080"&gt;&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#6a5acd"&gt;&amp;amp;nbsp;&lt;/font&gt;&lt;font color="#6a5acd"&gt;&amp;lt;%&lt;/font&gt;=&lt;font color="#008080"&gt;pc&lt;/font&gt;.&lt;font color="#008080"&gt;HardDisk&lt;/font&gt;&lt;font color="#6a5acd"&gt;%&amp;gt;&lt;/font&gt;&lt;font color="#008080"&gt;&amp;lt;/&lt;/font&gt;&lt;font color="#804040"&gt;&lt;b&gt;td&lt;/b&gt;&lt;/font&gt;&lt;font color="#008080"&gt;&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#008080"&gt;&amp;lt;/&lt;/font&gt;&lt;font color="#804040"&gt;&lt;b&gt;tr&lt;/b&gt;&lt;/font&gt;&lt;font color="#008080"&gt;&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#008080"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#804040"&gt;&lt;b&gt;tr&lt;/b&gt;&lt;/font&gt;&lt;font color="#008080"&gt;&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#008080"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#804040"&gt;&lt;b&gt;td&lt;/b&gt;&lt;/font&gt;&lt;font color="#008080"&gt;&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Monitor&lt;font color="#008080"&gt;&amp;lt;/&lt;/font&gt;&lt;font color="#804040"&gt;&lt;b&gt;td&lt;/b&gt;&lt;/font&gt;&lt;font color="#008080"&gt;&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#008080"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#804040"&gt;&lt;b&gt;td&lt;/b&gt;&lt;/font&gt;&lt;font color="#008080"&gt;&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#6a5acd"&gt;&amp;amp;nbsp;&lt;/font&gt;&lt;font color="#6a5acd"&gt;&amp;lt;%&lt;/font&gt;=&lt;font color="#008080"&gt;pc&lt;/font&gt;.&lt;font color="#008080"&gt;Monitor&lt;/font&gt;&amp;nbsp;&lt;font color="#6a5acd"&gt;%&amp;gt;&lt;/font&gt;&lt;font color="#008080"&gt;&amp;lt;/&lt;/font&gt;&lt;font color="#804040"&gt;&lt;b&gt;td&lt;/b&gt;&lt;/font&gt;&lt;font color="#008080"&gt;&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#008080"&gt;&amp;lt;/&lt;/font&gt;&lt;font color="#804040"&gt;&lt;b&gt;tr&lt;/b&gt;&lt;/font&gt;&lt;font color="#008080"&gt;&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#008080"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#804040"&gt;&lt;b&gt;tr&lt;/b&gt;&lt;/font&gt;&lt;font color="#008080"&gt;&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#008080"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#804040"&gt;&lt;b&gt;td&lt;/b&gt;&lt;/font&gt;&lt;font color="#008080"&gt;&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Tipo de Monitor&lt;font color="#008080"&gt;&amp;lt;/&lt;/font&gt;&lt;font color="#804040"&gt;&lt;b&gt;td&lt;/b&gt;&lt;/font&gt;&lt;font color="#008080"&gt;&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#008080"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#804040"&gt;&lt;b&gt;td&lt;/b&gt;&lt;/font&gt;&lt;font color="#008080"&gt;&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#6a5acd"&gt;&amp;amp;nbsp;&lt;/font&gt;&lt;font color="#6a5acd"&gt;&amp;lt;%&lt;/font&gt;=&lt;font color="#008080"&gt;pc&lt;/font&gt;.&lt;font color="#008080"&gt;MonitorType&lt;/font&gt;&lt;font color="#6a5acd"&gt;%&amp;gt;&lt;/font&gt;&lt;font color="#008080"&gt;&amp;lt;/&lt;/font&gt;&lt;font color="#804040"&gt;&lt;b&gt;td&lt;/b&gt;&lt;/font&gt;&lt;font color="#008080"&gt;&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#008080"&gt;&amp;lt;/&lt;/font&gt;&lt;font color="#804040"&gt;&lt;b&gt;tr&lt;/b&gt;&lt;/font&gt;&lt;font color="#008080"&gt;&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#008080"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#804040"&gt;&lt;b&gt;tr&lt;/b&gt;&lt;/font&gt;&lt;font color="#008080"&gt;&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#008080"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#804040"&gt;&lt;b&gt;td&lt;/b&gt;&lt;/font&gt;&lt;font color="#008080"&gt;&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Cdrom&lt;font color="#008080"&gt;&amp;lt;/&lt;/font&gt;&lt;font color="#804040"&gt;&lt;b&gt;td&lt;/b&gt;&lt;/font&gt;&lt;font color="#008080"&gt;&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#008080"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#804040"&gt;&lt;b&gt;td&lt;/b&gt;&lt;/font&gt;&lt;font color="#008080"&gt;&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#6a5acd"&gt;&amp;amp;nbsp;&lt;/font&gt;&lt;font color="#6a5acd"&gt;&amp;lt;%&lt;/font&gt;=&lt;font color="#008080"&gt;pc&lt;/font&gt;.&lt;font color="#008080"&gt;CdRom&lt;/font&gt;&lt;font color="#6a5acd"&gt;%&amp;gt;&lt;/font&gt;&lt;font color="#008080"&gt;&amp;lt;/&lt;/font&gt;&lt;font color="#804040"&gt;&lt;b&gt;td&lt;/b&gt;&lt;/font&gt;&lt;font color="#008080"&gt;&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#008080"&gt;&amp;lt;/&lt;/font&gt;&lt;font color="#804040"&gt;&lt;b&gt;tr&lt;/b&gt;&lt;/font&gt;&lt;font color="#008080"&gt;&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#008080"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#804040"&gt;&lt;b&gt;tr&lt;/b&gt;&lt;/font&gt;&lt;font color="#008080"&gt;&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#008080"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#804040"&gt;&lt;b&gt;td&lt;/b&gt;&lt;/font&gt;&lt;font color="#008080"&gt;&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Velocidad del procesador&lt;font color="#008080"&gt;&amp;lt;/&lt;/font&gt;&lt;font color="#804040"&gt;&lt;b&gt;td&lt;/b&gt;&lt;/font&gt;&lt;font color="#008080"&gt;&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#008080"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#804040"&gt;&lt;b&gt;td&lt;/b&gt;&lt;/font&gt;&lt;font color="#008080"&gt;&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#6a5acd"&gt;&amp;amp;nbsp;&lt;/font&gt;&lt;font color="#6a5acd"&gt;&amp;lt;%&lt;/font&gt;=&lt;font color="#008080"&gt;pc&lt;/font&gt;.&lt;font color="#008080"&gt;ProcessorSpeed&lt;/font&gt;&amp;nbsp;&lt;font color="#6a5acd"&gt;%&amp;gt;&lt;/font&gt;&lt;font color="#008080"&gt;&amp;lt;/&lt;/font&gt;&lt;font color="#804040"&gt;&lt;b&gt;td&lt;/b&gt;&lt;/font&gt;&lt;font color="#008080"&gt;&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#008080"&gt;&amp;lt;/&lt;/font&gt;&lt;font color="#804040"&gt;&lt;b&gt;tr&lt;/b&gt;&lt;/font&gt;&lt;font color="#008080"&gt;&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#008080"&gt;&amp;lt;/&lt;/font&gt;&lt;font color="#804040"&gt;&lt;b&gt;table&lt;/b&gt;&lt;/font&gt;&lt;font color="#008080"&gt;&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&lt;br&gt;&lt;br /&gt;&lt;font color="#008080"&gt;&amp;lt;/&lt;/font&gt;&lt;font color="#804040"&gt;&lt;b&gt;div&lt;/b&gt;&lt;/font&gt;&lt;font color="#008080"&gt;&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&lt;font color="#008080"&gt;&amp;lt;&lt;/font&gt;asp&lt;font color="#008080"&gt;:&lt;/font&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;Label&lt;/b&gt;&lt;/font&gt;&lt;font color="#008080"&gt;&amp;nbsp;&lt;/font&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;ID&lt;/b&gt;&lt;/font&gt;&lt;font color="#008080"&gt;=&lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;quot;lblStatus&amp;quot;&lt;/font&gt;&lt;font color="#008080"&gt;&amp;nbsp;runat=&lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;quot;server&amp;quot;&lt;/font&gt;&lt;font color="#008080"&gt;&amp;gt;&lt;/font&gt;&lt;font color="#008080"&gt;&amp;lt;/&lt;/font&gt;asp&lt;font color="#008080"&gt;:Label&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&lt;font color="#008080"&gt;&amp;lt;/&lt;/font&gt;&lt;font color="#804040"&gt;&lt;b&gt;form&lt;/b&gt;&lt;/font&gt;&lt;font color="#008080"&gt;&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&lt;font color="#008080"&gt;&amp;lt;/&lt;/font&gt;&lt;font color="#804040"&gt;&lt;b&gt;body&lt;/b&gt;&lt;/font&gt;&lt;font color="#008080"&gt;&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&lt;font color="#008080"&gt;&amp;lt;/&lt;/font&gt;&lt;font color="#804040"&gt;&lt;b&gt;html&lt;/b&gt;&lt;/font&gt;&lt;font color="#008080"&gt;&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&lt;/font&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;El resultado de la ejecucción de la página:&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/wmi/fig2.png"&gt;&lt;/div&gt;&lt;br /&gt;&lt;h3&gt;&lt;a href="http://www.humansharp.com/Code/PCProperties.zip"&gt;&lt;img src="http://www.humansharp.com/picture_library/dw.jpg" border="0"&gt;&amp;nbsp; Descarga el código fuente&lt;/a&gt;&lt;/h3&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6494419861240446187-2266065519724119333?l=xomalli.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/2266065519724119333'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/2266065519724119333'/><link rel='alternate' type='text/html' href='http://xomalli.blogspot.com/2011/06/utilizando-windows-management.html' title='Utilizando Windows Management Instrumentation (WMI) con Microsoft .NET'/><author><name>Martín Márquez</name><uri>http://www.blogger.com/profile/10939957618126542300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_j4WRR9G9bfY/SV2_nw3UxeI/AAAAAAAAAAM/nT3SYp94IHo/s1600-R/photo.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-6494419861240446187.post-1735274002651712105</id><published>2011-05-31T17:23:00.000-07:00</published><updated>2011-05-31T17:52:36.164-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Windows'/><title type='text'>Entendiendo Logging en Aplicaciones para .NET Framework</title><content type='html'>&lt;p align="justify"&gt;El &lt;b&gt;logging&lt;/b&gt; es un proceso recomendado durante la etapa de pruebas e indispensable durante la etapa de liberación o puesta en producción de aplicaciones de software, &lt;b&gt;logging&lt;/b&gt; se refiere a la utilización de una bitácora, registro o log, donde guardemos la información de los diferentes eventos que genero la aplicación entre el tiempo de arranque  y durante el tiempo de ejecución.&lt;br /&gt;El registro o log debe proporcionarnos toda información necesaria para realizar con la aplicación las siguientes actividades:&lt;br /&gt;&lt;br&gt;&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;Mantener el rastro de todos sus estados (recording)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Depurar (debugging)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Auditar (audit)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Diagnosticar su estado actual (tracing)&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br&gt;&lt;br /&gt;Un factor importante a considerar durante el &lt;b&gt;logging&lt;/b&gt; es el performance de la aplicación ya que es un hecho que se incrementará el tiempo de las operaciones de escritura, sobre todo si el &lt;b&gt;logging&lt;/b&gt; es requerido para una auditoría, este incremento en el performance se explica de la siguiente manera: &lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p align="justify"&gt;&lt;br /&gt;&lt;i&gt;Si una operación del proceso de negocio emplea 5 segundos para ejecutarse y producir un resultado, con el &lt;b&gt;logging&lt;/b&gt; necesitará 2 o 3 segundos adicionales para registrarse en el log, por lo que ahora el tiempo es de 7 u 8 segundos para el total de la operación.&lt;/i&gt;&lt;br /&gt;&lt;br&gt;&lt;br /&gt;El siguiente fragmento de código ilustra este factor:&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;try&lt;br /&gt;{&lt;br /&gt;//operación de negocio 5 segs.&lt;br /&gt;var output = BussinessObject.ExecuteOperation();&lt;br /&gt;//registro en el log 3 segs.&lt;br /&gt;Logger.WriteLine(output);&lt;br /&gt;//El tiempo  total de la transacción es de 8 segs.&lt;br /&gt;&lt;br /&gt;}catch(Exception e){&lt;br /&gt;&lt;br /&gt;//No está incluído dentro de la transacción.&lt;br /&gt;Logger.WriteLine(e.Message);&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p align="justify"&gt;&lt;br /&gt;Hay muchas formas de implementar &lt;b&gt;logging&lt;/b&gt; en las aplicaciones, esto varía dependiendo del tipo de aplicación y del requerimiento a satisfacer la forma más sencilla es mediante el uso de las clases contenidas en el ensamblado &lt;a href="http://msdn.microsoft.com/en-us/library/15t15zda.aspx"&gt;System.Diagnostics.&lt;/a&gt; específicamente con las implementaciones derivadas de la clase  &lt;i&gt;TraceListener&lt;/i&gt; las cuales son responsables de desplegar o de guardar los mensajes generados por las clases &lt;i&gt;Trace&lt;/i&gt; y &lt;i&gt;Debug&lt;/i&gt;, hay tres implementaciones de esta clase:&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;&lt;b&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.diagnostics.textwritertracelistener.aspx"&gt;TextWriterTraceListener&lt;/a&gt;&lt;/b&gt; escribe mensajes a cualquier clase que se derive de &lt;a href="http://msdn.microsoft.com/en-us/library/system.io.stream.aspx"&gt;Stream&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;b&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.diagnostics.eventlogtracelistener.aspx"&gt;EventLogTraceListener&lt;/a&gt;&lt;/b&gt; escribe los mensajes a el Event Viewer de Windows.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;b&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.diagnostics.defaulttracelistener.aspx"&gt;DefaultTraceListener&lt;/a&gt;&lt;/b&gt; escribe los  mensajes a la ventana de salida (Output window).&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p align="justify"&gt;&lt;br /&gt;El siguiente listado muestra el uso de TextWriterTraceListener y EventLogTraceListener, la lógica del programa es simple, si el programa tiene permisos administrativos usará el event viewer como log, de lo contrario usará un archivo de texto, realizando un intercambio entre los &lt;i&gt;Tracelisteners&lt;/i&gt;: &lt;b&gt;EventLogTraceListener&lt;/b&gt; y &lt;b&gt;TextWriterTraceListener&lt;/b&gt; respectivamente.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;using System;&lt;br /&gt;using System.Diagnostics;&lt;br /&gt;using System.Threading;&lt;br /&gt;using System.Security.Principal;&lt;br /&gt;using System.IO;&lt;br /&gt;using System.Text;&lt;br /&gt;&lt;br /&gt;namespace ELtraceApp&lt;br /&gt;{&lt;br /&gt;class Program&lt;br /&gt;{&lt;br /&gt;public static void Main(string[] args)&lt;br /&gt;{&lt;br /&gt;try{&lt;br /&gt;&lt;br /&gt;WindowsPrincipal winprincipal = new WindowsPrincipal(WindowsIdentity.GetCurrent());&lt;br /&gt;//Válidamos que sea Administrator&lt;br /&gt;if (winprincipal.IsInRole(WindowsBuiltInRole.Administrator))&lt;br /&gt;{&lt;br /&gt;string logSource = "EventLogtraceApp";&lt;br /&gt;string logName = "Event Log Test App";&lt;br /&gt;if (!EventLog.SourceExists("EventLogtraceApp"))&lt;br /&gt;EventLog.CreateEventSource(logSource, logName);&lt;br /&gt;//quitamos el log de texto&lt;br /&gt;Trace.Listeners.Remove("myTextLogListener");&lt;br /&gt;Trace.Listeners.Add(new EventLogTraceListener("myEventLogListener"));&lt;br /&gt;}&lt;br /&gt;else{&lt;br /&gt;//quitamos el log eventviewer&lt;br /&gt;Trace.Listeners.Remove("myEventLogListener"); &lt;br /&gt;string fname = "log.txt";&lt;br /&gt;FileStream stream = new FileStream(fname,FileMode.OpenOrCreate &lt;br /&gt;| FileMode.Append,FileAccess.Write);                &lt;br /&gt;Trace.Listeners.Add(new TextWriterTraceListener(stream,"myTextLogListener"));&lt;br /&gt;}&lt;br /&gt;Console.WriteLine("Iniciar la aplicación...");&lt;br /&gt;PrintfLog("Iniciar la aplicación...");&lt;br /&gt;Console.WriteLine("Ejecutando la aplicación");&lt;br /&gt;PrintfLog("Ejecutando la aplicación....");&lt;br /&gt;Thread.Sleep(1000);&lt;br /&gt;Console.Write("Presione cualquier tecla para continuar. . . ");&lt;br /&gt;Console.ReadKey(true);&lt;br /&gt;PrintfLog("Saliendo de la aplicación...");&lt;br /&gt;Thread.Sleep(500);&lt;br /&gt;}catch(Exception e){&lt;br /&gt;Console.WriteLine(e.Message);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;static void PrintfLog(string msg){&lt;br /&gt;Trace.WriteLine(msg);&lt;br /&gt;Trace.Flush();&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div&gt;Al compilar el listado se debe de incluir la opción &lt;tt&gt;/d:TRACE&lt;/tt&gt; como se muestra en la siguiente imagen:&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/tracelistener/log1.png"&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;Al ejecutar el programa mostrará un resultado como en la siguiente imagen:&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/tracelistener/log2.png"&gt;&lt;/div&gt;&lt;br /&gt;&lt;p align="justify"&gt;Con el siguiente código el programa intercambia entre &lt;i&gt;Listeners&lt;/i&gt; dependiendo si pertenece al grupo con permisos de administración o no.&lt;/p&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;WindowsPrincipal winprincipal = new WindowsPrincipal(WindowsIdentity.GetCurrent());&lt;br /&gt;//Válidamos que sea Administrator&lt;br /&gt;if (winprincipal.IsInRole(WindowsBuiltInRole.Administrator))&lt;br /&gt;{&lt;br /&gt;string logSource = "EventLogtraceApp";&lt;br /&gt;string logName = "Event Log Test App";&lt;br /&gt;if (!EventLog.SourceExists("EventLogtraceApp"))&lt;br /&gt;EventLog.CreateEventSource(logSource, logName);&lt;br /&gt;//quitamos el log de texto&lt;br /&gt;Trace.Listeners.Remove("myTextLogListener");&lt;br /&gt;Trace.Listeners.Add(new EventLogTraceListener("myEventLogListener"));&lt;br /&gt;}&lt;br /&gt;else{&lt;br /&gt;//quitamos el log eventviewer&lt;br /&gt;Trace.Listeners.Remove("myEventLogListener"); &lt;br /&gt;string fname = "log.txt";&lt;br /&gt;FileStream stream = new FileStream(fname,FileMode.OpenOrCreate &lt;br /&gt;| FileMode.Append,FileAccess.Write);                &lt;br /&gt;Trace.Listeners.Add(new TextWriterTraceListener(stream,"myTextLogListener"));&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p align="justify"&gt;Si no pertenece al grupo de administradores utiliza como log un archivo de texto &lt;tt&gt;log.txt&lt;/tt&gt; caso contrario utiliza el Event Viewer (visor de eventos de Windows) como se muestra en la siguiente imagen:&lt;/p&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/tracelistener/log3.png"&gt;&lt;/div&gt;&lt;br /&gt;&lt;p align="justify"&gt;Lo más recomendable para el logging es la utilización de componentes como el &lt;a href="http://msdn.microsoft.com/en-us/library/ff647183.aspx"&gt;Logging Application Block&lt;/a&gt; de Microsoft o el &lt;a href="http://logging.apache.org/log4net/index.html"&gt;Log4net&lt;/a&gt; de la fundación Apache.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6494419861240446187-1735274002651712105?l=xomalli.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/1735274002651712105'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/1735274002651712105'/><link rel='alternate' type='text/html' href='http://xomalli.blogspot.com/2011/05/entendiendo-logging-en-aplicaciones.html' title='Entendiendo Logging en Aplicaciones para .NET Framework'/><author><name>Martín Márquez</name><uri>http://www.blogger.com/profile/10939957618126542300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_j4WRR9G9bfY/SV2_nw3UxeI/AAAAAAAAAAM/nT3SYp94IHo/s1600-R/photo.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-6494419861240446187.post-1018840923854870465</id><published>2011-05-31T15:00:00.000-07:00</published><updated>2011-05-31T15:10:01.876-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><title type='text'>Nuevo número de la revista de software libre Atix</title><content type='html'>&lt;p align="justify"&gt;Ha salido publicado un nuevo número de la revista de Software Libre Atix. Este es el número 19 de la publicación, el sitio de descarga con mirrors de varios países se encuentra en la siguiente dirección:&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;a href="http://revista.atixlibre.org/"&gt;Ir al sitio de la Revista de Software Libre Atix&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6494419861240446187-1018840923854870465?l=xomalli.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/1018840923854870465'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/1018840923854870465'/><link rel='alternate' type='text/html' href='http://xomalli.blogspot.com/2011/05/nuevo-numero-de-la-revista-de-software.html' title='Nuevo número de la revista de software libre Atix'/><author><name>Martín Márquez</name><uri>http://www.blogger.com/profile/10939957618126542300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_j4WRR9G9bfY/SV2_nw3UxeI/AAAAAAAAAAM/nT3SYp94IHo/s1600-R/photo.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-6494419861240446187.post-3601141489892785993</id><published>2011-04-24T13:57:00.000-07:00</published><updated>2011-04-24T14:55:44.651-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Lenguajes .NET'/><title type='text'>Uso de custom exceptions en aplicaciones GTK# con Monodevelop</title><content type='html'>&lt;p align="justify"&gt;Hace unos días publiqué una &lt;a href="http://xomalli.blogspot.com/2011/04/uso-de-custom-exceptions-excepciones.html"&gt;entrada&lt;/a&gt;  que mostraba el uso de excepciones personalizadas y como ejemplo de esa técnica un  proyecto de consola de &lt;b&gt;MonoDevelop&lt;/b&gt; que obtenía registros de una tabla en una base de datos &lt;b&gt;PostgreSQL&lt;/b&gt;, derivado de ese ejemplo hice una aplicación en GTK# la cual muestra los mismos conceptos pero ahora con un formulario gráfico, por lo que hice algunas modificaciones con respecto al proyecto de consola de manera que pueda entenderse de una mejor manera.&lt;br /&gt;Los pasos son:&lt;/p&gt;&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;Ejecutamos &lt;a href="http://monodevelop.com/"&gt;MonoDevelop&lt;/a&gt; y creamos un proyecto GTK# llamado &lt;b&gt;GtkPostException&lt;/b&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Descargamos y descomprimimos el código del ejemplo de excepciones de este &lt;a href=” http://www.humansharp.com/Code/PostException.zip”&gt;enlace.&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Con el botón derecho encima del icono de la solución agregamos las siguientes clases a la solución.&lt;/li&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Book.cs&lt;br /&gt;BooksDataManager.cs&lt;br /&gt;DataBaseException.cs&lt;br /&gt;Logger.cs&lt;br /&gt;RuntimeException.cs&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;li&gt;Una vez agregadas las clases a la solución verificamos y en su caso editamos para que cada clase se agrupe dentro del &lt;tt&gt;namespace GtkPostException&lt;/tt&gt;.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Creamos un formulario con dos controles &lt;tt&gt;label&lt;/tt&gt;, un control &lt;tt&gt;TextView&lt;/tt&gt; (en donde teclearemos la &lt;i&gt;Connection String&lt;/i&gt;), un control &lt;tt&gt;Treeview&lt;/tt&gt;donde mostramos el resultado de la consulta y un &lt;tt&gt;botón&lt;/tt&gt; de manera que el formulario tenga el aspecto visual de la siguiente imagen:&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/gtkexcep/gtkpostex1.png"&gt;&lt;/div&gt;&lt;br /&gt;&lt;li&gt;Cambiamos el código de la clase &lt;tt&gt;BooksDataManager&lt;/tt&gt; en el método &lt;tt&gt;SelectAll&lt;/tt&gt; para que reciba un parámetro &lt;tt&gt;string&lt;/tt&gt; con el valor de la &lt;tt&gt;Connection String&lt;/tt&gt; recibida desde la interfaz de usuario. Aquí el listado completo de la clase:&lt;/li&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;using System;&lt;br /&gt;using System.Collections.Generic;&lt;br /&gt;using System.Text;&lt;br /&gt;using System.Data;&lt;br /&gt;using System.Data.Common;&lt;br /&gt;using Npgsql;&lt;br /&gt;using System.Configuration;&lt;br /&gt;&lt;br /&gt;namespace GtkPostException&lt;br /&gt;{&lt;br /&gt;public static class BooksDataManager&lt;br /&gt;{&lt;br /&gt;static string connStr = null;&lt;br /&gt;static List&lt;Book&gt; books = null;&lt;br /&gt;&lt;br /&gt;public static List&lt;Book&gt; SelectAll(string connstr) {&lt;br /&gt;try&lt;br /&gt;{&lt;br /&gt;connStr = connstr;&lt;br /&gt;books = new List&lt;Book&gt;();&lt;br /&gt;string CommandText = "SELECT title,pubyear,numpages,authors FROM books";&lt;br /&gt;using (NpgsqlConnection conn = new NpgsqlConnection(connStr))&lt;br /&gt;{&lt;br /&gt;conn.Open();&lt;br /&gt;using (NpgsqlCommand cmd = new NpgsqlCommand(CommandText, conn))&lt;br /&gt;{&lt;br /&gt;using (NpgsqlDataReader reader = cmd.ExecuteReader(CommandBehavior.CloseConnection))&lt;br /&gt;{&lt;br /&gt;while (reader.Read())&lt;br /&gt;{&lt;br /&gt;books.Add(new Book&lt;br /&gt;{&lt;br /&gt;    Title = reader["title"].ToString(),&lt;br /&gt;    PubYear = Convert.ToInt32(reader["pubyear"]),&lt;br /&gt;    NumPages = Convert.ToInt32(reader["numpages"]),&lt;br /&gt;    Authors = reader["authors"].ToString()&lt;br /&gt;});&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;return books;&lt;br /&gt;}&lt;br /&gt;catch (NpgsqlException ex)&lt;br /&gt;{&lt;br /&gt;var dbex = new DataBaseException("Error en base de datos", ex);&lt;br /&gt;Logger.WriteLog(dbex);&lt;br /&gt;throw dbex;&lt;br /&gt;}&lt;br /&gt;catch (Exception ex)&lt;br /&gt;{&lt;br /&gt;var rex = new RuntimeException("Error grave consulte al administrador", ex);&lt;br /&gt;Logger.WriteLog(rex);&lt;br /&gt;throw rex;&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;li&gt;Agregamos al evento &lt;tt&gt;Clicked&lt;/tt&gt; del Botón el metodo &lt;tt&gt;ExecuteQuery&lt;/tt&gt;, cuyo código se muestra a continuación:&lt;/li&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;protected virtual void ExecuteQuery (object sender, System.EventArgs e)&lt;br /&gt;{&lt;br /&gt;try{&lt;br /&gt;AddColumns(GridOutput);&lt;br /&gt;GridOutput.Model = CreateModel();&lt;br /&gt;lbmsg.Text += "Consulta ejecutada";&lt;br /&gt;&lt;br /&gt;}catch(GtkPostException.DataBaseException ex){&lt;br /&gt;MessageBox(ex.Message);&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;catch(GtkPostException.RuntimeException ex){&lt;br /&gt;MessageBox(ex.Message); &lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;li&gt;El listado completo de la clase MainWindow se muestra a continuación:&lt;/li&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;using System;&lt;br /&gt;using Gtk;&lt;br /&gt;using GtkPostException;&lt;br /&gt;&lt;br /&gt;public partial class MainWindow : Gtk.Window&lt;br /&gt;{&lt;br /&gt;public MainWindow () : base(Gtk.WindowType.Toplevel)&lt;br /&gt;{&lt;br /&gt;Build ();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;protected void OnDeleteEvent (object sender, DeleteEventArgs a)&lt;br /&gt;{&lt;br /&gt;Application.Quit ();&lt;br /&gt;a.RetVal = true;&lt;br /&gt;}&lt;br /&gt;protected virtual void ExecuteQuery (object sender, System.EventArgs e)&lt;br /&gt;{&lt;br /&gt;try{&lt;br /&gt;AddColumns(GridOutput);&lt;br /&gt;GridOutput.Model = CreateModel();&lt;br /&gt;lbmsg.Text += "Consulta ejecutada";&lt;br /&gt;&lt;br /&gt;}catch(GtkPostException.DataBaseException ex){&lt;br /&gt;MessageBox(ex.Message);&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;catch(GtkPostException.RuntimeException ex){&lt;br /&gt;MessageBox(ex.Message); &lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;void MessageBox(string messageText){&lt;br /&gt;using(Dialog dialog = new MessageDialog(this,&lt;br /&gt;DialogFlags.Modal | DialogFlags.DestroyWithParent,&lt;br /&gt;    MessageType.Error,&lt;br /&gt;    ButtonsType.Ok,&lt;br /&gt;    messageText,"")){&lt;br /&gt;dialog.Run();&lt;br /&gt;dialog.Hide();&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;//Creamos los encabezados de las columnas&lt;br /&gt;void AddColumns (TreeView treeView) {&lt;br /&gt;CellRendererText rendererText = new CellRendererText ();&lt;br /&gt;string[] s = {"Titulo","Año","Páginas","Autores"};&lt;br /&gt;TreeViewColumn column;&lt;br /&gt;for(int i = 0;i &lt; s.Length;i++){&lt;br /&gt; column =  new TreeViewColumn (s[i], rendererText, "text", i);&lt;br /&gt; column.Resizable = true;&lt;br /&gt; column.MinWidth = 128;&lt;br /&gt; treeView.AppendColumn (column);  &lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;//Creamos el modelo de datos&lt;br /&gt;ListStore CreateModel(){&lt;br /&gt;ListStore store = new ListStore(typeof(string),&lt;br /&gt;    typeof(int),&lt;br /&gt;    typeof(int),&lt;br /&gt;    typeof(string));&lt;br /&gt;&lt;br /&gt;foreach(Book b in BooksDataManager.SelectAll(txtConnStr.Buffer.Text)){&lt;br /&gt;store.AppendValues(b.Title,b.PubYear,b.NumPages,b.Authors);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;return store;&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;p align="justify"&gt;Si se compila correctamente al ejecutar la aplicación veremos una pantalla como la siguiente imagen:&lt;br&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/gtkexcep/gtkpostex2.png"&gt;&lt;/div&gt;&lt;br /&gt;Al presionar el botón &lt;tt&gt;OK&lt;/tt&gt;  mostrará los registros de la tabla conforme a la consulta, como en la siguiente imagen.&lt;br /&gt;&lt;br&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/gtkexcep/gtkpostex3.png"&gt;&lt;/div&gt;&lt;br /&gt;Hasta aquí el flujo normal de la aplicación o &lt;i&gt;happy path&lt;/i&gt;,ahora vamos a ocasionar una excepción reemplazando el usuario &lt;i&gt;postgres&lt;/i&gt; por el usuario &lt;i&gt;sa&lt;/i&gt; el cual no existe en la base de datos hecho esto presionamos el botón para que se muestre la excepción personalizada en un cuadro de dialogo, esta excepción queda a nivel base de datos de ahí que lance una &lt;tt&gt;DataBaseException&lt;/tt&gt;.&lt;br /&gt;&lt;br&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/gtkexcep/gtkpostex4.png"&gt;&lt;/div&gt;&lt;br /&gt;Este tipo de excepciones son registradas por &lt;b&gt;PostgreSQL&lt;/b&gt; si el proceso del servidor se ejecutó desde una terminal como en la siguiente imagen:&lt;br /&gt;&lt;br&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/gtkexcep/gtkpostex6.png"&gt;&lt;/div&gt;&lt;br /&gt;Para generar la excepción a nivel aplicación en vez del valor de la &lt;tt&gt;Connection String&lt;/tt&gt; tecleamos cualquier cadena no válida con lo que al presionar el botón nos mostrará el mensaje referente a la clase &lt;tt&gt;RuntimeException &lt;/tt&gt; como en la siguiente imagen:&lt;br /&gt;&lt;br&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/gtkexcep/gtkpostex5.png"&gt;&lt;/div&gt;&lt;br /&gt;El detalle a nivel técnico de las excepciones originales se podrá consultar en el archivo &lt;tt&gt;log.txt&lt;/tt&gt; el cual por lo general no es accesible al usuario final sino únicamente al personal técnico.&lt;br /&gt;A continuación el enlace para descargar el ejercicio completo.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;h3&gt;&lt;a href="http://www.humansharp.com/Code/GtkPostException.zip"&gt;&lt;img src="http://www.humansharp.com/picture_library/dw.jpg" border="0"&gt;&amp;nbsp; Descarga el código fuente&lt;/a&gt;&lt;/h3&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6494419861240446187-3601141489892785993?l=xomalli.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/3601141489892785993'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/3601141489892785993'/><link rel='alternate' type='text/html' href='http://xomalli.blogspot.com/2011/04/uso-de-custom-exceptions-en.html' title='Uso de custom exceptions en aplicaciones GTK# con Monodevelop'/><author><name>Martín Márquez</name><uri>http://www.blogger.com/profile/10939957618126542300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_j4WRR9G9bfY/SV2_nw3UxeI/AAAAAAAAAAM/nT3SYp94IHo/s1600-R/photo.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-6494419861240446187.post-3022332145619116075</id><published>2011-04-23T13:52:00.001-07:00</published><updated>2011-04-23T14:11:33.408-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Lenguajes .NET'/><title type='text'>Uso de Custom Exceptions (excepciones personalizadas) en .NET parte II</title><content type='html'>&lt;p align="Justify"&gt;En la entrada &lt;a href="http://xomalli.blogspot.com/2011/04/uso-de-custom-exceptions-excepciones.html"&gt;anterior&lt;/a&gt; del blog, me olvide de publicar el archivo &lt;i&gt;App.config&lt;/i&gt; donde se encuentra la cadena de conexión (ConnectionString) y  se accede a su valor mediante la siguiente línea en la aplicación y se asigna a la variable &lt;tt&gt;connStr&lt;/tt&gt;.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;connStr = ConfigurationManager.ConnectionStrings["curry"].ConnectionString;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;El archivo es el siguiente:&lt;br /&gt;&lt;pre style='color:#181615;background-color:#ffffff;'&gt;&lt;br /&gt;&lt;span style='color:#0057ae;'&gt;&amp;lt;?&lt;/span&gt;xml version&lt;span style='color:#0057ae;'&gt;=&lt;/span&gt;&lt;span style='color:#bf0303;'&gt;&amp;quot;1.0&amp;quot;&lt;/span&gt; encoding&lt;span style='color:#0057ae;'&gt;=&lt;/span&gt;&lt;span style='color:#bf0303;'&gt;&amp;quot;utf-8&amp;quot;&lt;/span&gt; &lt;span style='color:#0057ae;'&gt;?&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#0057ae;'&gt;&amp;lt;&lt;/span&gt;configuration&lt;span style='color:#0057ae;'&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#0057ae;'&gt;&amp;lt;&lt;/span&gt;connectionStrings&lt;span style='color:#0057ae;'&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#0057ae;'&gt;&amp;lt;&lt;/span&gt;add connectionString&lt;span style='color:#0057ae;'&gt;=&lt;/span&gt;&lt;span style='color:#bf0303;'&gt;&amp;quot;Server=127.0.0.1;Port=5432;User Id=postgres;&lt;br /&gt;Password=Pa$$w0rd;DataBase=curry&amp;quot;&lt;/span&gt; name&lt;span style='color:#0057ae;'&gt;=&lt;/span&gt;&lt;span style='color:#bf0303;'&gt;&amp;quot;curry&amp;quot;&lt;/span&gt; providerName&lt;span style='color:#0057ae;'&gt;=&lt;/span&gt;&lt;span style='color:#bf0303;'&gt;&amp;quot;Npgsql&amp;quot;&lt;/span&gt;&lt;span style='color:#0057ae;'&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#0057ae;'&gt;&amp;lt;/&lt;/span&gt;connectionStrings&lt;span style='color:#0057ae;'&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#0057ae;'&gt;&amp;lt;/&lt;/span&gt;configuration&lt;span style='color:#0057ae;'&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;En caso de ser necesario y de tener algún incoveniente en construir la solución aqui dejo el enlace para descargar el código fuente.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;h3&gt;&lt;a href="http://www.humansharp.com/Code/PostException.zip"&gt;&lt;img src="http://www.humansharp.com/picture_library/dw.jpg" border="0"&gt;&amp;nbsp; Descarga el código fuente&lt;/a&gt;&lt;/h3&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6494419861240446187-3022332145619116075?l=xomalli.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/3022332145619116075'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/3022332145619116075'/><link rel='alternate' type='text/html' href='http://xomalli.blogspot.com/2011/04/uso-de-custom-exceptions-excepciones_23.html' title='Uso de Custom Exceptions (excepciones personalizadas) en .NET parte II'/><author><name>Martín Márquez</name><uri>http://www.blogger.com/profile/10939957618126542300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_j4WRR9G9bfY/SV2_nw3UxeI/AAAAAAAAAAM/nT3SYp94IHo/s1600-R/photo.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-6494419861240446187.post-1479006087796929896</id><published>2011-04-19T18:34:00.000-07:00</published><updated>2011-04-20T01:27:43.292-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Lenguajes .NET'/><title type='text'>Uso de Custom Exceptions (excepciones personalizadas) en .NET</title><content type='html'>&lt;p align="justify"&gt;Las excepciones (exceptions) son un mecanismo incorporado en .NET que ayuda a la detección de condiciones excepcionales en nuestras aplicaciones,  entiéndase por condiciones excepcionales aquellas situaciones  que están fuera de nuestro control y que no podemos prever como programadores, esto es distinto de los errores de código y de los errores de aplicación ya que estos si son prevenibles y manejables dentro del ciclo de desarrollo.&lt;br /&gt;Como ejemplos de condiciones excepcionales tenemos: &lt;br /&gt;&lt;ul&gt;&lt;br /&gt; &lt;li&gt;Conectarse a una base de datos que se encuentra offline.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Conectarse a una base de datos y tratar de ejecutar un store procedure que no existe.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Leer de un archivo en disco que no se encuentra en una determinada ruta.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Convertir una cadena de caracteres o alfanumérica hacia un tipo numérico.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Ejecutar una acción cuando ya no hay memoria disponible en el sistema operativo.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Cuando se hace referencia a un elemento no creado o que se encuentra fuera de los límites de un arreglo.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p align="justify"&gt;En .NET la técnica para el manejo de estas condiciones se conoce como &lt;b&gt;structured exception handling (SEH)&lt;/b&gt; (la traducción sería más o menos manejo estructurado de excepciones)  esta técnica a base de bloques es parte integral de .NET y aplicable a cualquier lenguaje que se ejecute en .NET,  en esencia  parte de dos clases &lt;a href="http://msdn.microsoft.com/en-us/library/system.applicationexception.aspx"&gt;ApplicationException&lt;/a&gt; y  &lt;a href="http://msdn.microsoft.com/en-us/library/system.systemexception.aspx"&gt;SystemException&lt;/a&gt; que heredan de la clase &lt;a href="http://msdn.microsoft.com/en-us/library/system.exception.aspx"&gt;System.Exception&lt;/a&gt; y que agrupan las excepciones en dos categorías,  la primera representa excepciones lanzadas por las aplicaciones y la segunda las del CLR, las clases para excepciones incluidas en .NET son derivadas de estas  clases que cubren los casos más comunes y  para su empleo se usa la combinación de cuatro palabras reservadas: &lt;i&gt;try,catch throw, finally&lt;/i&gt; como se detalla a continuación en los pasos siguientes: &lt;/p&gt;&lt;br /&gt;&lt;p align="justify"&gt;1-. Se pone dentro de un bloque try aquel código que podría tener un evento inesperado.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;try&lt;br /&gt;{&lt;br /&gt; Paso1();&lt;br /&gt; Paso2();&lt;br /&gt; Paso3();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p align="justify"&gt;2-.Al final del bloque &lt;i&gt;try&lt;/i&gt; puede ir acompañado o no de varios bloques &lt;i&gt;catch&lt;/i&gt;, típicamente aparece la palabra &lt;i&gt;catch&lt;/i&gt; con la clase que manejará el error si la palabra &lt;i&gt;catch&lt;/i&gt; no especifica una clase entonces atrapara todas las posibles excepciones, cuando se enumeran una a una las posibles condiciones de excepción es MUY IMPORTANTE la jerarquía de clases ya que cada bloque debe ir de la clase más específica a la clase más general, por ejemplo:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;catch(NpgsqlException ex){  //derivada de DbExeption&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;catch(DbException ex){  //derivada de ExternalException&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;catch(ExternalException ex){ //derivada de SystemException&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;catch(SystemException ex){ //derivada de Exception&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;catch(Exception ex){ //derivada de Exception&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p align="justify"&gt;&lt;br /&gt;3-. Dentro de cada uno de los bloques &lt;i&gt;catch&lt;/i&gt; se coloca el código para el manejo de la excepción como agregar nueva información a la excepción, establecer valores predeterminados de variables o lo más común aquí es tener un Log o bitácora para registrar la excepción, después hay que reenviar o arrojar la excepción a la clase que ejecuto ese código, hay dos alternativas a esto enviar la excepción tal cuál o bien enviar una excepción personalizada que sea de valor para las capas que llamaron la ejecución del código.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;catch(NpgsqlException ex){  //derivada de DbExeption&lt;br /&gt; EscribeBitacora(ex.Message); &lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p align="justify"&gt;&lt;br /&gt;4-. En el bloque &lt;i&gt;finally&lt;/i&gt; se coloca el código que siempre será ejecutado haya ocurrido o no una excepción, por lo general en este bloque  se coloca código de limpieza (cleanup) por ejemplo se cierran conexiones de red o a bases de datos, se liberan recursos utilizados o se cierran archivos abiertos entre otros usos.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;finally{&lt;br /&gt; CloseConnectionDB();&lt;br /&gt; CloseNetWorkConnection();&lt;br /&gt; CloseFileOpenToWrite();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p align="justify"&gt;&lt;br /&gt;Las excepciones no deben ocasionar que la aplicación se colapse por completo por lo que una buena estrategia de desarrollo es manejar las excepciones y responder al evento que las ocasiono. Aunque el uso clases predeterminadas dentro del Framework es adecuado presenta una desventaja por el tipo de mensaje predeterminado ya que para el usuario esa información no debe ser de su conocimiento y en la mayoría de los casos no le encuentra utilidad, por lo que es necesario envolver la excepción dentro una técnica para personalizar excepciones.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;div&gt;&lt;b&gt;La técnica para el uso personalizado de Excepciones&lt;/b&gt;&lt;/div&gt;&lt;br /&gt;&lt;p align="justify"&gt;.NET permite crear excepciones personalizadas que envuelven las excepciones originales por excepciones que tengan nuevas características como por ejemplo: mensajes más significativos para el usuario, traducciones o que pueden tener información adicional.&lt;br /&gt;Los pasos para crear una excepción personalizada son:&lt;/p&gt;&lt;br /&gt;&lt;p align="justify"&gt;&lt;br /&gt;1-. Crear una nueva clase con el sufijo &lt;i&gt;Exception&lt;/i&gt; como una buena práctica y recomendación las clases derivadas de &lt;i&gt;Exception&lt;/i&gt; utilizan el este sufijo.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;class RuntimeException&lt;br /&gt;{&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p align="justify"&gt;&lt;br /&gt;2-. Derivar esta clase de &lt;a href="http://msdn.microsoft.com/en-us/library/system.applicationexception.aspx"&gt;ApplicationException&lt;/a&gt;, aunque se podría derivar directamente de &lt;i&gt;Exception&lt;/i&gt;, no se considera una buena práctica.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;class RuntimeException : ApplicationException&lt;br /&gt;{&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p align="justify"&gt;&lt;br /&gt;3-. La clase debe de tener tres constructores dos adicionales al constructor predeterminado o vacio, como se muestra en el siguiente código:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public class RuntimeException : ApplicationException&lt;br /&gt; {&lt;br /&gt; public RuntimeException(string message): base(message){ }&lt;br /&gt; public RuntimeException(string message, Exception inner): base(message, inner){}&lt;br /&gt; }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p align="justify"&gt;&lt;br /&gt;Como ejemplo de estos conceptos vamos a crear una aplicación que se conecta a una base de datos PostgreSQL, lee y muestra los registros de una tabla llamada Books y donde hace uso de dos excepciones personalizadas: DataBaseException y RuntimeException.&lt;br /&gt;En &lt;b&gt;Monodevelop&lt;/b&gt; o en &lt;b&gt;Visual Studio&lt;/b&gt; creamos una aplicación de consola, como en las siguientes imágenes.&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/postexcep/postEx1.png"&gt;&lt;/div&gt;&lt;br /&gt;Creamos una base de datos en &lt;b&gt;PostgreSQL&lt;/b&gt; llamada curry y una tabla llamada &lt;i&gt;Books&lt;/i&gt; que tendrá los campos como en la siguiente imagen:&lt;br&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/postexcep/tbBooks.png"&gt;&lt;/div&gt;&lt;br /&gt;Aquí el Script de creación de la tabla&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;CREATE TABLE books&lt;br /&gt;(&lt;br /&gt;  book_id serial NOT NULL,&lt;br /&gt;  title character varying(512) NOT NULL,&lt;br /&gt;  pubyear smallint,&lt;br /&gt;  numpages smallint,&lt;br /&gt;  created timestamp without time zone DEFAULT now(),&lt;br /&gt;  authors character varying(256) NOT NULL,&lt;br /&gt;  CONSTRAINT books_pkey PRIMARY KEY (book_id),&lt;br /&gt;  CONSTRAINT books_title_key UNIQUE (title)&lt;br /&gt;)&lt;br /&gt;WITH (&lt;br /&gt;  OIDS=FALSE&lt;br /&gt;);&lt;br /&gt;ALTER TABLE books OWNER TO postgres;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Una vez creada la base de datos y el proyecto, creamos la siguiente clase de entidad.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;using System;&lt;br /&gt;using System.Collections.Generic;&lt;br /&gt;using System.Linq;&lt;br /&gt;using System.Text;&lt;br /&gt;&lt;br /&gt;namespace PostException&lt;br /&gt;{&lt;br /&gt;    public class Book&lt;br /&gt;    {&lt;br /&gt;        public string Title { set; get; }&lt;br /&gt;        public int PubYear { set; get; }&lt;br /&gt;        public int NumPages { set; get; }&lt;br /&gt;        public string Authors { set; get; }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Las clases derivadas y personalizadas que muestran con los constructores básicos del manejo de excepción.&lt;br /&gt;La clase que maneja las excepciones en base de datos&lt;br&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;using System;&lt;br /&gt;using System.Collections.Generic;&lt;br /&gt;using System.Linq;&lt;br /&gt;using System.Text;&lt;br /&gt;using System.Data.Common;&lt;br /&gt;using Npgsql;&lt;br /&gt;&lt;br /&gt;namespace PostException&lt;br /&gt;{&lt;br /&gt;public class DataBaseException : ApplicationException&lt;br /&gt;{&lt;br /&gt;public DataBaseException(string message) : base(message) { }&lt;br /&gt;public DataBaseException(string message, NpgsqlException inner):base(message,inner) { }&lt;br /&gt;public DataBaseException(string message, Exception inner):base(message,inner) { }&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;La clase que maneja las excepciones de la aplicación.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;using System;&lt;br /&gt;using System.Collections.Generic;&lt;br /&gt;using System.Linq;&lt;br /&gt;using System.Text;&lt;br /&gt;&lt;br /&gt;namespace PostException&lt;br /&gt;{&lt;br /&gt;public class RuntimeException : ApplicationException&lt;br /&gt;{&lt;br /&gt;public RuntimeException(string message): base(message){ }&lt;br /&gt;public RuntimeException(string message, Exception inner): base(message, inner){}&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;La clase de acceso a datos&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;using System;&lt;br /&gt;using System.Collections.Generic;&lt;br /&gt;using System.Linq;&lt;br /&gt;using System.Text;&lt;br /&gt;using System.Data;&lt;br /&gt;using System.Data.Common;&lt;br /&gt;using Npgsql;&lt;br /&gt;using System.Configuration;&lt;br /&gt;&lt;br /&gt;namespace PostException&lt;br /&gt;{&lt;br /&gt;public static class BooksDataManager&lt;br /&gt;{&lt;br /&gt;static string connStr = null;&lt;br /&gt;static List&lt;Book&gt; books = null;&lt;br /&gt;&lt;br /&gt;public static List&lt;Book&gt; SelectAll() {&lt;br /&gt;try&lt;br /&gt;{&lt;br /&gt;connStr = ConfigurationManager.ConnectionStrings["curry"].ConnectionString;&lt;br /&gt;books = new List&lt;Book&gt;();&lt;br /&gt;string CommandText = "SELECT title,pubyear,numpages,authors FROM books";&lt;br /&gt;using (NpgsqlConnection conn = new NpgsqlConnection(connStr))&lt;br /&gt;{&lt;br /&gt;conn.Open();&lt;br /&gt;using (NpgsqlCommand cmd = new NpgsqlCommand(CommandText, conn))&lt;br /&gt;{&lt;br /&gt;using (NpgsqlDataReader reader = &lt;br /&gt;cmd.ExecuteReader(CommandBehavior.CloseConnection))&lt;br /&gt;{&lt;br /&gt;while (reader.Read())&lt;br /&gt;{&lt;br /&gt;books.Add(new Book&lt;br /&gt;{&lt;br /&gt;    Title = reader["title"].ToString(),&lt;br /&gt;    PubYear = Convert.ToInt32(reader["pubyear"]),&lt;br /&gt;    NumPages = Convert.ToInt32(reader["numpages"]),&lt;br /&gt;    Authors = reader["authors"].ToString()&lt;br /&gt;});&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;return books;&lt;br /&gt;}&lt;br /&gt;catch (NpgsqlException ex)&lt;br /&gt;{&lt;br /&gt;var dbex = new DataBaseException("Error en base de datos", ex);&lt;br /&gt;Logger.WriteLog(dbex);&lt;br /&gt;throw dbex;&lt;br /&gt;}&lt;br /&gt;catch (Exception ex)&lt;br /&gt;{&lt;br /&gt;var rex = new RuntimeException("Error grave consulte al administrador", ex);&lt;br /&gt;Logger.WriteLog(rex);&lt;br /&gt;throw rex;&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;La clase logger que se encargara de registrar las excepciones.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;using System;&lt;br /&gt;using System.Collections.Generic;&lt;br /&gt;using System.Linq;&lt;br /&gt;using System.Text;&lt;br /&gt;using System.IO;&lt;br /&gt;using System.Data.Common;&lt;br /&gt;using Npgsql;&lt;br /&gt;&lt;br /&gt;namespace PostException&lt;br /&gt;{&lt;br /&gt;public class Logger&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt;public static void WriteLog(DataBaseException e)&lt;br /&gt;{&lt;br /&gt;Log(e.InnerException);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public static void WriteLog(RuntimeException e)&lt;br /&gt;{&lt;br /&gt;Log(e.InnerException);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;static void Log(Exception e) {&lt;br /&gt;try{&lt;br /&gt;using (StreamWriter writer = new StreamWriter(&lt;br /&gt;new FileStream("log.txt", FileMode.Append, FileAccess.Write, FileShare.ReadWrite)))&lt;br /&gt;{&lt;br /&gt;writer.WriteLine(string.Format("{0} | {1} | {2}", DateTime.Now,e.Source,e.Message));&lt;br /&gt;writer.Flush();&lt;br /&gt;writer.Close();&lt;br /&gt;}&lt;br /&gt;}catch(Exception ex){&lt;br /&gt;throw new RuntimeException("No se pudo cargar el log",ex);&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Por último la clase principal en donde usamos las excepciones personalizadas.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;using System;&lt;br /&gt;using System.Collections.Generic;&lt;br /&gt;using System.Linq;&lt;br /&gt;using System.Text;&lt;br /&gt;&lt;br /&gt;namespace PostException&lt;br /&gt;{&lt;br /&gt;class Program&lt;br /&gt;{&lt;br /&gt;static void Main(string[] args)&lt;br /&gt;{&lt;br /&gt;Console.WriteLine("Obteniendo la lista de libros");&lt;br /&gt;try {&lt;br /&gt;foreach (Book b in BooksDataManager.SelectAll()) {&lt;br /&gt;Console.WriteLine("{0}",b.Title);&lt;br /&gt;Console.WriteLine("{0}",b.Authors);&lt;br /&gt;Console.WriteLine("{0}",b.NumPages);&lt;br /&gt;Console.WriteLine("{0}",b.PubYear);&lt;br /&gt;Console.WriteLine("+-----------------------------------------+");&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;catch (DataBaseException dbex)&lt;br /&gt;{&lt;br /&gt;Console.WriteLine(dbex.Message);&lt;br /&gt;}&lt;br /&gt;catch (RuntimeException ex)&lt;br /&gt;{&lt;br /&gt;Console.WriteLine(ex.Message);&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Una vez creadas estas clases dentro del proyecto la estructura se verá más o menos así en &lt;b&gt;MonoDevelop&lt;/b&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/postexcep/postEx3.png"&gt;&lt;/div&gt;&lt;br /&gt;Para ejecutar este programa siendo una aplicación de consola debemos de habilitar la salida en una terminal independiente en el menú &lt;i&gt;Project&lt;/i&gt; del menú principal elegimos la opción &lt;i&gt;Project properties&lt;/i&gt; donde nos aparece la siguiente ventana.&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/postexcep/postEx3a.png"&gt;&lt;/div&gt;&lt;br /&gt;Ahí seleccionamos la opción &lt;i&gt;Run on external console&lt;/i&gt;, ahora al ejecutar el programa el resultado se verá en una ventana terminal independiente como en la siguiente imagen que muestra el resultado sin ninguna excepción.&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/postexcep/postEx5.png"&gt;&lt;/div&gt;&lt;br /&gt;Sin embargo si ocurre una excepción relacionada con la base de datos se mostrará la salida como en la siguiente imagen.&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/postexcep/postEx6.png"&gt;&lt;/div&gt;&lt;br /&gt;Si hay una excepción en la aplicación se mostrará el resultado como en la siguiente imagen.&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/postexcep/postEx7.png"&gt;&lt;/div&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;La técnica de &lt;b&gt;custom exceptions&lt;/b&gt; permite la separación entre el código de flujo de la aplicación y el código de manejo de excepciones lo que hace la aplicación cumpla con un mecanismo mínimo de calidad y  sea mucho más manejable, robusta y escalable.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6494419861240446187-1479006087796929896?l=xomalli.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/1479006087796929896'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/1479006087796929896'/><link rel='alternate' type='text/html' href='http://xomalli.blogspot.com/2011/04/uso-de-custom-exceptions-excepciones.html' title='Uso de Custom Exceptions (excepciones personalizadas) en .NET'/><author><name>Martín Márquez</name><uri>http://www.blogger.com/profile/10939957618126542300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_j4WRR9G9bfY/SV2_nw3UxeI/AAAAAAAAAAM/nT3SYp94IHo/s1600-R/photo.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-6494419861240446187.post-7341015556454609814</id><published>2011-03-21T12:21:00.000-07:00</published><updated>2011-03-21T13:09:50.106-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Lenguajes .NET'/><title type='text'>Referencias acerca del uso del Garbage Collector en .NET</title><content type='html'>&lt;p align="justify"&gt;Buscando referencias en cuanto al uso de los destructores en C# me encontré estos fragmentos del libro &lt;a href="http://www.amazon.com/Advanced-C-Programming-Paul-Kimmel/dp/0072224177"&gt;Advanced C# Programming&lt;/a&gt; de &lt;a href="http://www.softconcepts.com/"&gt;Paul Kimmel&lt;/a&gt; donde en el capítulo 1 pag 18 habla acerca de la destrucción no determinística y Garbage Collector, fragmento que copio tal cuál se encuentra en el libro:&lt;/p&gt;&lt;br /&gt;&lt;p align="justify"&gt;&lt;i&gt;C# uses non-deterministic destruction. The CLR implements a garbage collector that cleans up memory when objects are no longer used. This means that you don’t have to worry as much about destructors in C# as you do in C++ or Delphi.&lt;br /&gt;The garbage collector will call the destructor for your objects when they are no longer needed. The destructor will call any Finalize method. You can force garbage collection by calling GC.Collect, but this is not a recommended process. The garbage collector suspends any running threads, which can cause performance problems. Besides, the garbage collector will do a good job of determining when to run.&lt;/i&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p align="justify"&gt;De nuevo en el en el capítulo 3 pag 76, recalca la importancia de que no es una buena práctica, fragmento que copio tal cuál se encuentra en el libro&lt;/p&gt;&lt;br /&gt;&lt;p align="Justify"&gt;&lt;br /&gt;&lt;i&gt;Control Dispose Methods C# is a .NET language. I state the obvious as a way to segue into a subject that may not be obvios. Languages like Object Pascal or C++  use deterministic construction and destruction. This means that the programmer is responsible for both creating and destroying objects.&lt;br /&gt;.NET employs non-deterministic destruction.This means that the programmer is not responsible for destroying objects.The gargabe collector will clean up objects for you. As a result, you will write code that invokes the new operator, but there is no equivalent free operator.&lt;br /&gt;&lt;b&gt;NOTE:&lt;/b&gt; You can invoke the garbage collector explicitly by calling &lt;b&gt;GC.Collect&lt;/b&gt;, but this is not a recommended practice.&lt;/i&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p align="justify"&gt;Aunque la biblioteca de la universidad tiene la edición 2002 y no sé si en las ediciones actuales haya cambiado, considero que es interesante lo que menciona además que un amigo y compañero de trabajo me pregunto hace algunos años si era posible invocar a voluntad el &lt;i&gt;Garbage Collector&lt;/i&gt; a lo cual respondí por lógica que sí porque ya había visto la clase &lt;i&gt;System.GC&lt;/i&gt; y algo había leído algo al respecto pero en ese momento no sabía bien acerca de sus implicaciones y no había recordado la fuente.&lt;/p&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/libros/advancedc.png"&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6494419861240446187-7341015556454609814?l=xomalli.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/7341015556454609814'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/7341015556454609814'/><link rel='alternate' type='text/html' href='http://xomalli.blogspot.com/2011/03/referencias-acerca-del-uso-del-garbage.html' title='Referencias acerca del uso del Garbage Collector en .NET'/><author><name>Martín Márquez</name><uri>http://www.blogger.com/profile/10939957618126542300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_j4WRR9G9bfY/SV2_nw3UxeI/AAAAAAAAAAM/nT3SYp94IHo/s1600-R/photo.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-6494419861240446187.post-791747478001022482</id><published>2011-03-20T20:33:00.000-07:00</published><updated>2011-03-21T12:50:02.864-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Lenguajes .NET'/><title type='text'>Uso de Destructores en C#</title><content type='html'>&lt;p align="justify"&gt;En lenguajes orientados a objetos como C#,C++ o Java los objetos tienen un ciclo de vida el cual inicia cuando se  crea el objeto mediante un constructor y acaba cuando se termina el objeto mediante un destructor.&lt;br /&gt;Por ejemplo con la palabra reservada  &lt;i&gt;new&lt;/i&gt;, llamamos al constructor de un  &lt;br /&gt;objeto del tipo router:&lt;/p&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Router router = new Router();&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p align="justify"&gt;&lt;br /&gt;El uso de constructores es igual en C# como lo es en C++ y Java, donde sino especificamos el constructor, el compilador se encarga de crearlo ya que una de sus responsabilidades es la llamada a un constructor el cual  como un estándar tomado de C++ el constructor tiene el mismo nombre que la  clase.&lt;br /&gt;De igual forma la clase puede tener el constructor predeterminado sin  argumentos, como un constructor personalizado, por ejemplo en el siguiente  código:&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Router router = new Router("Contabilidad");&lt;br /&gt;Router router = new Router("Contabilidad",new byte[]{192,168,1,4});&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p align="justify"&gt;&lt;br /&gt;En C# a diferencia de C++ existe el Garbage Collector (recolector de basura) que se encarga de destruir los objetos que fueron creados y ya no son utilizados, por lo que el programador no es responsable de liberar recursos asignando un destructor a cada objeto.&lt;/p&gt;&lt;br /&gt;&lt;p align="justify"&gt;Sin embargo hay casos en C# donde los destructores son necesarios para objetos que hacen uso de recursos no administrados (unmanaged resources) como las conexiones hacia las bases de datos o el uso de archivos.&lt;br /&gt;Los destructores a diferencia de los constructores no se heredan, no pueden recibir parámetros y  no pueden sobrescribirse.&lt;br /&gt;La sintaxis de un destructor es con el mismo nombre que el constructor solo se agrega una  ~ como prefijo, como se muestra en el siguiente código:&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public class Router{&lt;br /&gt;~Router(){&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div&gt;Veamos un ejemplo del uso de destructores en una clase Router que implementa un método destructor&lt;/div&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;using System;&lt;br /&gt;using System.IO;&lt;br /&gt;&lt;br /&gt;namespace Samples{&lt;br /&gt; public class Router&lt;br /&gt; {&lt;br /&gt;  public string Name{private set;get;}&lt;br /&gt;  public byte[] IPNetwork{private set;get;}&lt;br /&gt;  public Router(string name){&lt;br /&gt;   Name = name;&lt;br /&gt;   Console.WriteLine("{0} Creado {1}",Name,DateTime.Now);&lt;br /&gt;   }&lt;br /&gt; public Router(string name,byte[] ipnet){&lt;br /&gt; Name = name;&lt;br /&gt; IPNetwork = ipnet;&lt;br /&gt; Console.WriteLine("{0} Creado {1}",Name,DateTime.Now);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; ~Router(){&lt;br /&gt;  Console.WriteLine("{0} Destruido {1}",Name,DateTime.Now);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div&gt;A continuación el programa principal para ejemplificar los destructores&lt;/div&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;using System;&lt;br /&gt;using System.Threading;&lt;br /&gt;&lt;br /&gt;namespace Samples{&lt;br /&gt; public class DestructorSample{&lt;br /&gt; public static void Main(string[] args){&lt;br /&gt;&lt;br /&gt;  Router router = new Router("Cordoba");&lt;br /&gt;  Router router2 = new Router("Monterrey",new  &lt;br /&gt;byte[]{10,3,0,0});&lt;br /&gt;  Console.WriteLine("\n");&lt;br /&gt;  //simulamos un proceso en ejecucción&lt;br /&gt;  Console.WriteLine("Primer router {0}", router.Name);&lt;br /&gt;  Working();&lt;br /&gt;  Console.WriteLine("Segundo router {0}", router2.Name);&lt;br /&gt;  Working();&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public static void Working(){&lt;br /&gt;  Console.Write("trabajando");&lt;br /&gt;  for(int i = 1;i &lt;= 10;i++){&lt;br /&gt;   Console.Write(".");&lt;br /&gt;  Thread.Sleep(500);&lt;br /&gt;  }&lt;br /&gt;  Console.WriteLine("\n");&lt;br /&gt; }&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p align="justify"&gt;En este ejemplo el código dentro del destructor imprime un mensaje en la  consola lo cual es algo trivial, esto es importante ya que en la mayoría  de la documentación que hablan acerca de destructores en C# señalan que deben usarse con extremo cuidado.Hay ciertas reglas acerca de su uso:&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;Se debe tener presente es nunca utilizar destructores en managed code (código manejado) ya que representa un problema de desempeño para el garbage collector, ya que a diferencia de C++ el objeto no es destruido inmediatamente cuando es ejecutado el destructor.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;En lugar de destructores utilizar Close() o Dispose().&lt;/li&gt;&lt;br /&gt;&lt;li&gt;NUNCA poner código en el destructor que realice cambios críticos al ambiente o bien código que utilice recursos, es decir los destructores se usaron para liberar no para utilizar.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;No se debe hacer referencia a otros objetos dentro del destructor.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Nunca llames a un constructor de forma directa, el garbage collector  &lt;br /&gt;lo invoca de forma automática, si se requiere liberar recursos de forma  &lt;br /&gt;determinística lo recomendable es usar la interfaz &lt;a href="http://msdn.microsoft.com/en-us/library/system.idisposable.aspx"&gt;IDisposable&lt;/a&gt;.&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;p align="justify"&gt;&lt;br /&gt;Es posible invocar y controlar el Garbage Collector vía los métodos estáticos de la clase System.GC, pero no es recomendable ya que se activa para todas las aplicaciones que utilicen recursos en ese momento no únicamente para la aplicación que lo invoco, además que debemos de conocer los métodos no determinísticos para la liberación de memoria.&lt;br /&gt;A continuación la salida del programa&lt;/p&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/destructor/destructor.png"&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6494419861240446187-791747478001022482?l=xomalli.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/791747478001022482'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/791747478001022482'/><link rel='alternate' type='text/html' href='http://xomalli.blogspot.com/2011/03/destructores-en-c.html' title='Uso de Destructores en C#'/><author><name>Martín Márquez</name><uri>http://www.blogger.com/profile/10939957618126542300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_j4WRR9G9bfY/SV2_nw3UxeI/AAAAAAAAAAM/nT3SYp94IHo/s1600-R/photo.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-6494419861240446187.post-3754932662401212347</id><published>2011-02-27T12:40:00.000-08:00</published><updated>2011-02-27T13:37:21.735-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><title type='text'>Cambiando la resolución de pantalla de forma permanente en OpenSuse 11.3</title><content type='html'>&lt;p align="justify"&gt;Pues teniendo desde hace un par de meses &lt;a href="http://en.opensuse.org/Main_Page"&gt;OpenSuse&lt;/a&gt; 11.3 en mí nueva portátil (Dell Inspiron 14), algo que ya había leído pero no había hecho era cambiar la resolución de la pantalla de forma permanente. &lt;br /&gt;Ya que de forma predeterminada el sistema establecía la resolución 1366x768 resolución que para mostrar ciertas gráficas en proyectores no era apropiada, por lo que siempre cambiaba la resolución de forma manual a una resolución estándar de 1024x768, algo que en versiones anteriores de &lt;a href="http://en.opensuse.org/Main_Page"&gt;OpenSuse&lt;/a&gt; se realizaba con &lt;a href="http://en.opensuse.org/Archive:SaX2"&gt;Sax2&lt;/a&gt; y se conservaba después de reiniciar o apagar el equipo cosa que en esta versión no ocurre.&lt;/p&gt;&lt;br /&gt;&lt;p align="justify"&gt;Leyendo en la documentación de OpenSuse encuentro que esta versión no incluye &lt;a href="http://en.opensuse.org/Archive:SaX2"&gt;Sax2&lt;/a&gt; ni sus derivados como (Sax2-vesa), por lo que ese cambio debe hacerse de forma programática.&lt;p&gt;&lt;br /&gt;&lt;p&gt;El procedimiento se describe en este &lt;a href="http://www.forosuse.org/forosuse/showthread.php?t=24465"&gt;enlace &lt;/a&gt;.&lt;br /&gt;A continuación pongo algunas anotaciones con imágnes en caso de que el enlace/post cambie y para que tenga manera de recordarlo.&lt;p&gt;&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;Como root cambiamos al directorio /etc/X11/xorg.conf.d/&lt;br&gt; &lt;b&gt;# cd /etc/X11/xorg.conf.d/&lt;/b&gt;&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Sacamos una copia de seguridad del archivo 50-screen.conf &lt;br&gt;&lt;b&gt;# cp 50-screen.conf 50-screen.conf.bak&lt;/b&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/susescreen/resol1.png"&gt;&lt;/div&gt;&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Vemos las resoluciones soportadas en el menú "Preferencias del sistema" del inicio de KDE.&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/susescreen/resol4.png"&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/susescreen/resol3.png"&gt;&lt;/div&gt;&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Editamos el archivo, agregando las siguientes líneas y colocando en primer lugar la resolución que necesitamos de forma permanente. &lt;br&gt; &lt;b&gt;# vi 50-screen.conf &lt;br /&gt;Section "Screen"&lt;br /&gt; Identifier "Default Screen"&lt;br /&gt; Device "Default Device"&lt;br /&gt;&lt;br /&gt; ##Doesn't help for radeon/radeonhd drivers;use magic in&lt;br /&gt; ##50-device.conf instead&lt;br /&gt; Monitor "Default Monitor"&lt;br /&gt;&lt;br /&gt; SubSection "Display"&lt;br /&gt; modes "1024x768" "800x600" "640x480"&lt;br /&gt; EndSubSection&lt;br /&gt;&lt;br /&gt;EndSection&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/susescreen/resol2.png"&gt;&lt;/div&gt;&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Reiniciamos el equipo para probar el cambio.&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6494419861240446187-3754932662401212347?l=xomalli.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/3754932662401212347'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/3754932662401212347'/><link rel='alternate' type='text/html' href='http://xomalli.blogspot.com/2011/02/cambiando-la-resolucion-de-pantalla-de.html' title='Cambiando la resolución de pantalla de forma permanente en OpenSuse 11.3'/><author><name>Martín Márquez</name><uri>http://www.blogger.com/profile/10939957618126542300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_j4WRR9G9bfY/SV2_nw3UxeI/AAAAAAAAAAM/nT3SYp94IHo/s1600-R/photo.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-6494419861240446187.post-2189446210626274611</id><published>2011-02-27T11:17:00.000-08:00</published><updated>2011-03-06T14:41:00.279-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Lenguajes .NET'/><title type='text'>Diferencias entre C# DateTime.Now y DateTime.Today</title><content type='html'>&lt;p align="justify"&gt;Hoy por la tarde haciendo un programa para enviar mensajes hacia un servidor me salió un error simple que después de cierto tiempo pude resolverlo y se debió más a un bloqueo de mi memoria que ha otro factor.&lt;br /&gt;Resulta que uno de los requisitos en el programa era enviar como título del mensaje  fecha, hora, minutos y segundos en los que cada mensaje se había generado. &lt;br /&gt;Básicamente existía una clase mensaje con una propiedad &lt;i&gt;DateCreated&lt;/i&gt; como en el siguiente código:&lt;/p&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;using System;&lt;br /&gt;&lt;br /&gt;namespace Messages&lt;br /&gt;{&lt;br /&gt; public class Message&lt;br /&gt; {&lt;br /&gt;  public string Title{&lt;br /&gt;   private set;get;&lt;br /&gt;  }&lt;br /&gt;  public DateTime DateCreated{&lt;br /&gt;   get{ return DateTime.Today;}&lt;br /&gt;  }&lt;br /&gt;  public string Description{&lt;br /&gt;   set;get;&lt;br /&gt;  }&lt;br /&gt;  private Message(){}&lt;br /&gt;  public Message(string title)&lt;br /&gt;  {&lt;br /&gt;   Title = title;&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p align="justify"&gt;Al crear el mensaje, el programa debía notificar con un aviso, indicando fecha, hora, minutos y segundos, algo así como lo siguiente:&lt;/p&gt;&lt;br /&gt;&lt;div&gt;“Mensaje recibido 24-02-2011  a las 22:04:12”&lt;/div&gt;&lt;br /&gt;&lt;div&gt;Sin embargo el mensaje lo notificaba de la siguiente forma:&lt;/div&gt;&lt;br /&gt;&lt;div&gt;“Mensaje recibido 24-02-2011 a las 22:04:00 ”&lt;/div&gt;&lt;br /&gt;&lt;div&gt;El código principal era más o menos asi&lt;/div&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;using System;&lt;br /&gt;using Messages;&lt;br /&gt;&lt;br /&gt;namespace Messages {&lt;br /&gt;class Program {&lt;br /&gt;public static void Main(string[] args) {&lt;br /&gt; Message msg = new Message("Sistemas de control");&lt;br /&gt; msg.Description = "Los sistemas de control son de lazo abierto ó lazo cerrado.";&lt;br /&gt; Console.WriteLine("Mensaje creado en {0:dd-MM-yyyy hh:mm:ss}",msg.DateCreated);&lt;br /&gt; Console.ReadLine();&lt;br /&gt;} &lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p align="justify"&gt;Al revisar el código descubrí que al usar la estructura DateTime utilice la propiedad &lt;a href=”http://msdn.microsoft.com/en-us/library/system.datetime.today%28v=VS.71%29.aspx”&gt;Today&lt;/a&gt; en lugar de la propiedad&lt;a href=” http://msdn.microsoft.com/en-us/library/system.datetime.now%28v=VS.71%29.aspx”&gt;Now &lt;/a&gt;.&lt;br /&gt;Ambas propiedades obtienen el valor de la fecha actual, la diferencia es que en &lt;a href=”http://msdn.microsoft.com/en-us/library/system.datetime.today%28v=VS.71%29.aspx”&gt;Today&lt;/a&gt; la parte correspondiente al tiempo se establece en 00:00:00.&lt;/p&gt;&lt;br /&gt;&lt;div&gt;al cambiar la propiedad DateCreated como en la siguiente línea:&lt;/div&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public DateTime DateCreated&lt;br /&gt;{&lt;br /&gt;   get{ return DateTime.Now;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div&gt;El problema se soluciono y aquí el resultado.&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/formatdate/FormatDate.png"&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6494419861240446187-2189446210626274611?l=xomalli.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/2189446210626274611'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/2189446210626274611'/><link rel='alternate' type='text/html' href='http://xomalli.blogspot.com/2011/02/diferencias-entre-c-datetimenow-y.html' title='Diferencias entre C# DateTime.Now y DateTime.Today'/><author><name>Martín Márquez</name><uri>http://www.blogger.com/profile/10939957618126542300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_j4WRR9G9bfY/SV2_nw3UxeI/AAAAAAAAAAM/nT3SYp94IHo/s1600-R/photo.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-6494419861240446187.post-8523682248212559073</id><published>2011-02-03T15:24:00.000-08:00</published><updated>2011-03-21T11:54:06.514-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><title type='text'>Liberación del número 18 de la revista ATIX</title><content type='html'>&lt;p align="justify"&gt;El día 31 de Enero se público en línea un nuevo ejemplar de la revista ATIX, el sitio para la descarga es &lt;a href="http://atix.opentelematics.org/?p=202"&gt;http://atix.opentelematics.org/&lt;/a&gt;, este número contiene un tutorial introductorio al uso de expresiones Lambda con C# usando mono.&lt;br&gt;&lt;br /&gt;El enlace del tutorial en PDF para descarga &lt;a href="http://www.humansharp.com/docs/EntendiendoExpresionesLambda.pdf"&gt;aquí&lt;/a&gt;.&lt;br&gt;&lt;br /&gt;El código fuente en un proyecto de consola de MonoDevelop para descarga se encuentra &lt;a href="http://www.humansharp.com/Code/LambdaExample.zip"&gt;aquí&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6494419861240446187-8523682248212559073?l=xomalli.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/8523682248212559073'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/8523682248212559073'/><link rel='alternate' type='text/html' href='http://xomalli.blogspot.com/2011/02/liberacion-del-numero-18-de-la-revista.html' title='Liberación del número 18 de la revista ATIX'/><author><name>Martín Márquez</name><uri>http://www.blogger.com/profile/10939957618126542300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_j4WRR9G9bfY/SV2_nw3UxeI/AAAAAAAAAAM/nT3SYp94IHo/s1600-R/photo.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-6494419861240446187.post-4479344017253992811</id><published>2011-01-14T06:52:00.000-08:00</published><updated>2011-01-14T08:52:27.426-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Lenguajes .NET'/><title type='text'>Operadores a nivel de bits en C# (bitwise operators)</title><content type='html'>&lt;p align="justify"&gt;Además de los operadores condicionales lógicos y de relación C# cuenta con operadores a nivel de bits (bitwise operators o logical operators) que permiten realizar operaciones con las representaciones binarias de las variables que internamente utiliza la computadora, esto es útil en ciertos casos donde se requiere interactuar directamente con el hardware o utilizar  una variable entera como un arreglo de bits donde por ejemplo un tipo short representaría un arreglo de bits con una longitud de 16 valores y cada bit podría ser utilizado como si fuera un valor booleano 1 igual true y 0 igual a false.&lt;br /&gt;Los tipos de datos donde usualmente aplican estos operadores son: los numéricos y las enumeraciones.&lt;br /&gt;La siguiente tabla muestra los tipos numéricos, su longitud en bytes y su valor en decimal.&lt;p&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;+--------------+------+----------------------------+--------------+&lt;br /&gt;| Tipos de dato| Bytes| Valor minimo               |  Valor Máximo|&lt;br /&gt;+--------------+------+----------------------------+--------------+&lt;br /&gt;sbyte  1 -128                       | 127&lt;br /&gt;byte  1 0                           | 255&lt;br /&gt;short  2 -32,768                    | 32,767&lt;br /&gt;ushort  2       0                   |  65,535&lt;br /&gt;int  4 -2,147,483,648               |2,147,483,647&lt;br /&gt;uint  4 0                           |4,294,967,295&lt;br /&gt;long  8 -9,223,372,036,854,775,808  |9,223,372,036,854,775,807&lt;br /&gt;ulong  8  0                         |18,446,744,073,709,551,615&lt;br /&gt;+-----------------------------------------------------------------------------&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p align="justify"&gt;&lt;br /&gt;Así por ejemplo si tenemos valores decimales representados en variables byte  (8 bits hasta 255 en decimal)&lt;br /&gt;&lt;br /&gt;byte a = 22;&lt;br /&gt;byte b = 33;&lt;br /&gt;&lt;br /&gt;Internamente su representación en binario es:&lt;br /&gt;&lt;br /&gt;22 = 00010110&lt;br /&gt;33 = 00100001&lt;br /&gt;&lt;br /&gt;si utilizamos variables de tipo short (16 bits hasta 65,535) &lt;br /&gt;&lt;br /&gt;short c = 666;&lt;br /&gt;short d = 6666;&lt;br /&gt;&lt;br /&gt;su representación en binario es:&lt;br /&gt;&lt;br /&gt;666  = 00000010 10011010 &lt;br /&gt;6666 = 00011010 00001010&lt;br /&gt;&lt;br /&gt;Así con cada tipo numérico siempre agrupando las cadenas de bits de 8 en 8.&lt;br /&gt;La siguiente tabla muestra los operadores bitwise, su significado y su resultado.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;p align="justify"&gt;&lt;br /&gt;+----------+-------------+-----------&lt;br /&gt;| Operador | Significado | Resultado &lt;br /&gt;+----------+-------------+--------------------------&lt;br /&gt;&amp;           AND            Si ambos bits son 1 el resultado es 1&lt;br /&gt;                           Si cualquiera de ambos bits es 0 el resultado es 0&lt;br /&gt;----------------------------------------------------&lt;br /&gt;|           OR             Si ambos bits son 0 el resultado es 0   &lt;br /&gt;                           Si cualquiera o ambos bits son 1,el resultado es 1&lt;br /&gt;----------------------------------------------------------------------&lt;br /&gt;^           Exclusive OR   Si ambos bits son iguales el resultado es 0&lt;br /&gt;                           Si un bit es 0 y el otro es 1,el resultado es 1.&lt;br /&gt;--------------------------------------------------------------------------&lt;br /&gt;~           NOT            Si un bit es 1 es resultado es 0 o viceversa.&lt;br /&gt;--------------------------------------------------------------------------&lt;br /&gt;&lt;&lt;          shift left     Cada bit es recorrido n posiciones a la izquierda&lt;br /&gt;----------------------------------&lt;br /&gt;&gt;&gt;          shift right    Cada bit es recorrido n posiciones a la derecha&lt;br /&gt;--------------------------------------------------------------------------&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div&gt;Un ejemplo de la utilización de estos operadores con enteros:&lt;/div&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;using System;&lt;br /&gt;using System.Collections.Generic;&lt;br /&gt;using System.Linq;&lt;br /&gt;using System.Text;&lt;br /&gt;&lt;br /&gt;namespace BitwiseCalc&lt;br /&gt;{&lt;br /&gt;class BitwiseCalc&lt;br /&gt;{&lt;br /&gt;delegate int DelBinOp(int a,int b);&lt;br /&gt;delegate int DelUriOp(int a);&lt;br /&gt;static void Main(string[] args)&lt;br /&gt;{&lt;br /&gt;    ushort option = 0;&lt;br /&gt;    do {&lt;br /&gt;    option = Menu();&lt;br /&gt;    switch(option){&lt;br /&gt;    case 1:&lt;br /&gt;        Console.WriteLine("\t\t[ &amp; AND ]\n\n");&lt;br /&gt;        BinaryOp((a, b) =&gt;a &amp; b);&lt;br /&gt;        break;&lt;br /&gt;    case 2:&lt;br /&gt;        Console.WriteLine("\t\t[ | OR ]\n\n");&lt;br /&gt;        BinaryOp((a,b) =&gt; a | b);&lt;br /&gt;        break;&lt;br /&gt;    case 3:&lt;br /&gt;        Console.WriteLine("\t\t[ ^ Exclusive OR ]\n\n");&lt;br /&gt;        BinaryOp((a,b) =&gt; a ^ b);&lt;br /&gt;        break;&lt;br /&gt;    case 4:&lt;br /&gt;        Console.WriteLine("\t\t[ ~ NOT ]\n\n");&lt;br /&gt;        UnaryOp(a =&gt; ~a);&lt;br /&gt;        break;&lt;br /&gt;    case 5:&lt;br /&gt;        Console.WriteLine("\t\t[ &lt;&lt; Shift Left ]\n\n");&lt;br /&gt;        ShiftOp((a,b) =&gt; a &lt;&lt; b);&lt;br /&gt;        break;&lt;br /&gt;    case 6:&lt;br /&gt;        Console.WriteLine("\t\t[ &gt;&gt; Shift right ]\n\n");&lt;br /&gt;        ShiftOp((a,b) =&gt; a &gt;&gt; b);&lt;br /&gt;        break;&lt;br /&gt;                &lt;br /&gt;        }&lt;br /&gt;    } while (option &gt; 0);&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;static ushort Menu() {&lt;br /&gt;ushort option = 0;&lt;br /&gt;Console.WriteLine("\t\tOPERADORES BITWISE\n\n");&lt;br /&gt;Console.WriteLine("1. &amp; AND");&lt;br /&gt;Console.WriteLine("2. | OR");&lt;br /&gt;Console.WriteLine("3. ^ Exclusive OR");&lt;br /&gt;Console.WriteLine("4. ~ NOT");&lt;br /&gt;Console.WriteLine("5. &lt;&lt; Shift Left");&lt;br /&gt;Console.WriteLine("6. &gt;&gt; Shift right");&lt;br /&gt;Console.WriteLine();&lt;br /&gt;Console.WriteLine("0. Salir\n\n");&lt;br /&gt;Console.Write("Elija opción: ");&lt;br /&gt;try&lt;br /&gt;{&lt;br /&gt;    option = Convert.ToUInt16(Console.ReadLine());&lt;br /&gt;}&lt;br /&gt;catch (FormatException) {&lt;br /&gt;    Console.WriteLine("Opción no válida");&lt;br /&gt;    option = 0;&lt;br /&gt;}&lt;br /&gt;return option;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;static void BinaryOp(DelBinOp del) {&lt;br /&gt;int op1,op2,resp;&lt;br /&gt;Console.Write("Teclee el primer operador: ");&lt;br /&gt;op1 = Convert.ToInt32(Console.ReadLine());&lt;br /&gt;Console.Write("Teclee el segundo operador: ");&lt;br /&gt;op2 = Convert.ToInt32(Console.ReadLine());&lt;br /&gt;resp = del(op1,op2);&lt;br /&gt;Console.WriteLine();&lt;br /&gt;DisplayBinary(op1);&lt;br /&gt;DisplayBinary(op2);&lt;br /&gt;Console.WriteLine("----------------------------");&lt;br /&gt;DisplayBinary(resp);&lt;br /&gt;Pause();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;static void ShiftOp(DelBinOp del)&lt;br /&gt;{&lt;br /&gt;int op1, op2,resp;&lt;br /&gt;Console.Write("Teclee el primer operador: ");&lt;br /&gt;op1 = Convert.ToInt32(Console.ReadLine());&lt;br /&gt;Console.Write("Teclee las posiciones: ");&lt;br /&gt;op2 = Convert.ToInt32(Console.ReadLine());&lt;br /&gt;resp = del(op1, op2);&lt;br /&gt;Console.WriteLine();&lt;br /&gt;DisplayBinary(op1);&lt;br /&gt;Console.WriteLine("-----------------------");&lt;br /&gt;DisplayBinary(resp);&lt;br /&gt;Pause();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;static void UnaryOp(DelUriOp del) {&lt;br /&gt;int op1,resp;&lt;br /&gt;Console.Write("Teclee el primer operador: ");&lt;br /&gt;op1 = Convert.ToInt32(Console.ReadLine());&lt;br /&gt;resp = del(op1);&lt;br /&gt;DisplayBinary(op1);&lt;br /&gt;Console.WriteLine("-----------------------");&lt;br /&gt;DisplayBinary(resp);&lt;br /&gt;Pause();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;static void DisplayBinary(int i) {&lt;br /&gt;Console.WriteLine("{0} = {1}",i, Convert.ToString(i, 2).PadLeft(32,'0'));&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;static void Pause() {&lt;br /&gt;Console.Write("\n\nPresiona cualquier tecla para continuar.");&lt;br /&gt;Console.Read();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div&gt;Compilamos y ejecutamos el programa&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;tt&gt;mcs BitwiseCalc.cs&lt;/tt&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;tt&gt;mono BitwiseCalc.exe&lt;/tt&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;Al ejecutarlo veremos los siguientes resultados:&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/bitwise/bitwise0.png"&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/bitwise/bitwise1.png"&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/bitwise/bitwise2.png"&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/bitwise/bitwise3.png"&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/bitwise/bitwise4.png"&gt;&lt;/div&gt;&lt;br /&gt;&lt;p align="justify"&gt;Otro uso común de estos operadores esta en las enumeraciones como en el caso de los valores de las enumeraciones FileMode y FileAccess del siguiente código.&lt;/p&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;FileStream outStream = new FileStream("log.txt",FileMode.Append | FileMode.Create,&lt;br /&gt;FileAccess.Read | FileAccess.Write,FileShare.Read);&lt;br /&gt;StreamWriter sw = new StreamWriter(outStream);&lt;br /&gt;sw.WriteLine("Archivo de log");&lt;br /&gt;sw.Close();&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;h3&gt;&lt;a href="http://www.humansharp.com/Code/BitwiseCalc.zip"&gt;&lt;img src="http://www.humansharp.com/picture_library/dw.jpg" border="0"&gt;&amp;nbsp; Descarga el código fuente&lt;/a&gt;&lt;/h3&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6494419861240446187-4479344017253992811?l=xomalli.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/4479344017253992811'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/4479344017253992811'/><link rel='alternate' type='text/html' href='http://xomalli.blogspot.com/2011/01/operadores-nivel-de-bits-en-c-bitwise.html' title='Operadores a nivel de bits en C# (bitwise operators)'/><author><name>Martín Márquez</name><uri>http://www.blogger.com/profile/10939957618126542300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_j4WRR9G9bfY/SV2_nw3UxeI/AAAAAAAAAAM/nT3SYp94IHo/s1600-R/photo.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-6494419861240446187.post-2829006187572697881</id><published>2011-01-04T11:39:00.000-08:00</published><updated>2011-01-04T19:22:13.319-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Redes'/><title type='text'>Notas acerca de los elementos de la comunicación en redes de datos</title><content type='html'>&lt;p align="justify"&gt;La comunicación comienza con un mensaje o información que debe enviarse de un individuo o de un dispositivo a otro. Aunque hay muchos métodos de comunicación la comunicación tiene básicamente tres partes, que son:&lt;/p&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;La fuente del mensaje o el emisor que pueden ser personas o dispositivos.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;El destino del mensaje o el receptor quien recibe el mensaje y lo interpreta.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;El canal que consiste del medio en el cual se transmite el mensaje.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;p align="justify"&gt;En el caso de las redes de datos en vez de enviar todo el mensaje por el canal y esperar hasta que el receptor lo interprete de principio a fin, se realiza una estrategia llamada segmentación donde el mensaje se divide en pequeñas partes y cada una de esas partes es enviada al emisor hasta completar el mensaje, esto trae dos ventajas, la primera es que se pueden enviar diferentes mensajes por el mismo canal ya que se pueden intercalar las partes de diferentes mensajes dentro del canal evitando la saturación por un mensaje de tamaño considerable y la segunda es que no todos los mensajes van desde la misma fuente al mismo destino si una vía dentro del canal se congestiona o se cae, las partes pueden tomar vías alternas y además si algunas partes del mensaje no llegan a su destino esas partes pueden ser retransmitidas.&lt;br&gt;&lt;br /&gt;Aunque la segmentación le agrega mayor complejidad y consumo de tiempo al proceso de la comunicación en las redes de datos esto asegura el correcto envió y recepción de mensajes. Varios tipos de dispositivos a través de la red participan en este proceso, los componentes visibles y los componentes no visibles. Los componentes visibles de la red de datos son los elementos de hardware que participan en la red como laptops, PC's, el cableado y los switches y los elementos no visibles se refiere al software como los procesos de servicios de los programas de comunicación que se ejecutan en los dispositivos de red, estos servicios responden a una petición como los servicios de emaill o de web, aunque son menos evidentes son críticos para la operación de las redes ya que se encargan de la respuesta a las solicitudes de los mensajes.&lt;br&gt;&lt;br /&gt;Los dispositivos de red que están cerca del usuario se conocen como dispositivos finales estos dispositivos son la interfaz entre la red humana y la red de comunicación de datos. En el contexto de las redes de datos un dispositivo final está referido como un host, ya que es tanto como el emisor o el receptor de los mensajes transmitidos a través de la red, un host se distingue de otro dentro de la red mediante su dirección. En las redes modernas un host actúa tanto como cliente, como servidor o como ambas cosas esto lo determina el tipo de software que tenga instalado.&lt;br&gt;&lt;br /&gt;Por ejemplo si una PC tiene instalado un servidor de correo electrónico (como postfix) y de hosteo de páginas Web (como apache) entonces está habilitada como servidor tanto de correo electrónico como de páginas web y sí tiene además instalado software de cliente de correo (como thunderbird) y de navegador web (como firefox) entonces también está habilitada como cliente de correo electrónico y de páginas web.&lt;br&gt;&lt;br /&gt;Además de los dispositivos finales en la red de datos existen los dispositivos intermediarios que proporcionan la conectividad y todo el trabajo para asegurarse que los datos fluyan dentro de la red. Estos dispositivos conectan los hosts a la red y la red o redes de hosts para formar una interred o internetwork como es el caso de Internet, ejemplos de dispositivos intermediarios son:&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Dispositivos de acceso a la red (Hubs,switches, wireless access point)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Dispositivos interred (routers)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Servidores de comunicación y los modems&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Dispositivos de seguridad (firewalls)&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;p align="justify"&gt;Estos dispositivos usan la dirección de host (host address) en conjunción con la información de las redes interconectadas para determinar la trayectoria de los mensajes dentro de la red, los procesos que se ejecutan en estos dispositivos realizan las siguientes funciones:&lt;/p&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Generan y retransmiten las señales de datos.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Mantienen la información acerca de las rutas existentes en la red.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Notifican a otros dispositivos de los errores o de las fallas de comunicación.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Si hay un error de enlace enviar la señal en rutas alternas.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Clasifican los mensajes acorde a las prioridades de QoS.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Permite o rechazan el flujo de datos basados en la configuración de seguridad.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;p align="justify"&gt;Las redes modernas usan principalmente tres tipos de medio para la interconexión de dispositivos, esos medios son:&lt;/p&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Cables metálicos&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Cables de fibra óptica&lt;/li&gt;&lt;br /&gt;&lt;li&gt;La transmisión por ondas (wireless)&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;p align="justify"&gt;La codificación de la señal es diferente en cada tipo de medio, en los medios metálicos la señal es codificada mediante impulsos eléctricos, en los medios de fibra óptica es codificada como impulsos de luz infrarroja o blanca y en la transmisión wireless es codificada como patrones de ondas electromagnéticas.&lt;/p&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/PacketTracer1.png"&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6494419861240446187-2829006187572697881?l=xomalli.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/2829006187572697881'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/2829006187572697881'/><link rel='alternate' type='text/html' href='http://xomalli.blogspot.com/2011/01/notas-acerca-de-los-elementos-de-la.html' title='Notas acerca de los elementos de la comunicación en redes de datos'/><author><name>Martín Márquez</name><uri>http://www.blogger.com/profile/10939957618126542300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_j4WRR9G9bfY/SV2_nw3UxeI/AAAAAAAAAAM/nT3SYp94IHo/s1600-R/photo.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-6494419861240446187.post-5084845900236009164</id><published>2010-11-30T19:57:00.000-08:00</published><updated>2010-12-01T12:55:58.553-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Redes'/><title type='text'>Notas acerca de direcciones IP y la dirección IP en .NET</title><content type='html'>&lt;p align="justify"&gt;Las direcciones IP se dividen en tres clases generales (A, B, C)  y dos especializadas que son utilizadas para propósitos experimentales (D, E). Las direcciones IP se representan por  cuatro octetos u ocho bits,  separados por puntos, así como la dirección MAC nos proporciona identificación, la dirección IP nos da ubicación.&lt;/p&gt;&lt;br /&gt;&lt;p align="justify"&gt;Cada dirección IP se compone de dos campos un campo de red y un campo de host. El tamaño de cada uno de esos campos varía según la clase:&lt;br /&gt;Para la clase A tenemos el primer octeto para identificar la red y los restantes tres para identificar al host.&lt;br /&gt;Para la clase B tenemos los dos primeros octetos para identificar la red y los dos restantes para identificar al host.&lt;br /&gt;Para la clase C tenemos los tres primeros octetos para identificar al host y el último octeto para identificar al host.&lt;br /&gt;El primer octeto en decimal  siempre nos indica la clase a la que pertenece una red, dependiendo de su valor en decimal dentro de los siguientes rangos: &lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;0 a 127 es clase A&lt;/li&gt;&lt;br /&gt;&lt;li&gt;128 a 191 es clase B&lt;/li&gt;&lt;br /&gt;&lt;li&gt;192 a 223 es clase C&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;Aquí si observamos el inicio del rango es par y el final es impar.&lt;br /&gt;En la clase A, la dirección IP 127.0.0.1 se reserva como dirección de loopback.&lt;br /&gt;Existen además tipos reservados de IP como por ejemplo si los octetos de host son puestos en 0 (cero) esa dirección IP identifica a la red o si todos los octetos de host son puestos en 1 o 255 en decimal esa dirección IP es una dirección IP de Broadcast.&lt;/p&gt;&lt;br /&gt;&lt;p align="justify"&gt;Una manera de identificar los tipos de red es buscar la posición del bit 0 (cero) dentro del primer octeto, la reglas son:&lt;br /&gt;Si el primer bit es 0 (cero) la dirección es clase A, si el segundo bit es 0 (cero) la dirección es clase B, si el tercer bit es 0 (cero) entonces es clase C. Como en el siguiente esquema:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;clase A  | 0 1 1 1 1 1 1 1&lt;br /&gt;---------+-----------------&lt;br /&gt;clase B  | 1 0 1 1 1 1 1 1 &lt;br /&gt;---------+----------------&lt;br /&gt;clase C  | 1 1 0 1 1 1 1 1&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;div&gt;&lt;b&gt;IP local en .NET&lt;/b&gt;&lt;/div&gt;&lt;br /&gt;&lt;p align="justify"&gt;.Net tiene diversas clases dentro del ensamblado System.Net para el manejo de direcciones IP mostraremos  el uso básico de esas clases para obtener la dirección o las direcciones IP de la máquina en donde se ejecute el siguiente listado.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;span class="using"&gt;using&lt;/span&gt; System;&lt;br /&gt;&lt;span class="using"&gt;using&lt;/span&gt; System.Net;&lt;br /&gt;&lt;span class="using"&gt;using&lt;/span&gt; System.Net.Sockets;&lt;br /&gt;&lt;br /&gt;&lt;span class="reserved"&gt;namespace&lt;/span&gt; Samples {&lt;br /&gt;&lt;span class="reserved"&gt;class&lt;/span&gt; Program {&lt;br /&gt;&lt;span class="reserved"&gt;public static void&lt;/span&gt; Main(string[] args)  {&lt;br /&gt; try {&lt;br /&gt;    IPHostEntry ipinfo = Dns.GetHostByName(Dns.GetHostName());&lt;br /&gt;    &lt;span class="reserved"&gt;int&lt;/span&gt; i = 0;&lt;br /&gt;    &lt;span class="reserved"&gt;if&lt;/span&gt;(ipinfo.AddressList.Length &gt; -1)    {&lt;br /&gt; &lt;span class="reserved"&gt;foreach&lt;/span&gt;(IPAddress ip &lt;span class="reserved"&gt;in&lt;/span&gt;  ipinfo.AddressList){&lt;br /&gt; &lt;span class="reserved"&gt;byte&lt;/span&gt;[] b = ip.GetAddressBytes();&lt;br /&gt;Console.WriteLine("IP[{0}] = {1}.{2}.{3}.{4}",i,b[0],b[1],b[2],b[3]);&lt;br /&gt;i++;&lt;br /&gt;     }&lt;br /&gt;Console.WriteLine("LoopBack =\t{0} ",IPAddress.Loopback);&lt;br /&gt;Console.WriteLine("Broadcast =\t{0} ",IPAddress.Broadcast);&lt;br /&gt; } &lt;br /&gt;&lt;span class="reserved"&gt;else&lt;/span&gt;&lt;br /&gt; Console.WriteLine("Sin IP");&lt;br /&gt;  }&lt;br /&gt; &lt;span class="reserved"&gt;catch&lt;/span&gt;(SocketException se){&lt;br /&gt; Console.WriteLine(se.Message);&lt;br /&gt;  }&lt;br /&gt; &lt;span class="reserved"&gt;catch&lt;/span&gt;(ArgumentException sa){&lt;br /&gt; Console.WriteLine(sa.Message);&lt;br /&gt;  }&lt;br /&gt; &lt;span class="reserved"&gt;catch&lt;/span&gt;(Exception e){&lt;br /&gt; Console.WriteLine(e.Message);&lt;br /&gt;  }&lt;br /&gt;  }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Para acceder a las clases de red, primeramente hacemos referencia a los ensamblados&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;span class="using"&gt;using&lt;/span&gt; System.Net;&lt;br /&gt;&lt;span class="using"&gt;using&lt;/span&gt; System.Net.Sockets;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;En la siguiente línea&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;IPHostEntry ipinfo = Dns.GetHostByName(Dns.GetHostName());&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Utilizamos el método GetHostByName de la clase &lt;a href=” http://msdn.microsoft.com/en-us/library/system.net.dns.aspx”&gt;Dns&lt;/a&gt; el cual nos devuelve un objeto &lt;a href=” http://msdn.microsoft.com/en-us/library/system.net.iphostentry.aspx”&gt;IPHostEntry&lt;/a&gt; del cual utilizamos la propiedad &lt;i&gt;AddressList&lt;/i&gt; que es una lista de objetos del tipo &lt;a href=” http://msdn.microsoft.com/en-us/library/system.net.ipaddress.aspx”&gt;IPAddress&lt;/a&gt; que representa cada IP de la máquina en caso de tener más de una interface de red y que recorremos con un ciclo utilizando el método &lt;i&gt;GetAddressBytes()&lt;/i&gt; para obtener los octetos como un arreglo.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;span class="reserved"&gt;foreach&lt;/span&gt;(IPAddress ip in  ipinfo.AddressList){&lt;br /&gt;&lt;span class="reserved"&gt;byte&lt;/span&gt;[] b = ip.GetAddressBytes();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Por último utilizamos las propiedades estáticas &lt;i&gt;IPAddress.Loopback&lt;/i&gt; y &lt;i&gt;IPAddress.Broadcast&lt;/i&gt; para imprimir la dirección Loopback y de Broadcast respectivamente.&lt;br /&gt;Al compilar y ejecutar el programa obtendremos algo similar a lo que se muestra en la siguiente imagen:&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/ip/getip.png"&gt;&lt;/div&gt;&lt;br /&gt;&lt;h3&gt;&lt;a href="http://www.humansharp.com/Code/ip.zip"&gt;&lt;img src="http://www.humansharp.com/picture_library/dw.jpg" border="0"&gt;&amp;nbsp; Descarga el código fuente&lt;/a&gt;&lt;/h3&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6494419861240446187-5084845900236009164?l=xomalli.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/5084845900236009164'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/5084845900236009164'/><link rel='alternate' type='text/html' href='http://xomalli.blogspot.com/2010/11/notas-acerca-de-direcciones-ip-y-la.html' title='Notas acerca de direcciones IP y la dirección IP en .NET'/><author><name>Martín Márquez</name><uri>http://www.blogger.com/profile/10939957618126542300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_j4WRR9G9bfY/SV2_nw3UxeI/AAAAAAAAAAM/nT3SYp94IHo/s1600-R/photo.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-6494419861240446187.post-1776736100545127428</id><published>2010-11-25T17:45:00.000-08:00</published><updated>2010-11-25T18:01:59.846-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Redes'/><title type='text'>Notas de la certificación CCNA de Cisco</title><content type='html'>&lt;p align="justify"&gt;Notas de las primeras clases del módulo Aspectos básicos de Networking de CCNA Exploration 4.0.&lt;br /&gt;&lt;hr&gt;&lt;br /&gt;La problemática básica de toda red está dividida en 3 aspectos:&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;La interconexión&lt;/li&gt;&lt;br /&gt;&lt;li&gt;La colisión de paquetes&lt;/li&gt;&lt;br /&gt;&lt;li&gt;El ancho de banda&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p align="justify"&gt;Debido a la distancia en la conexión física la señal se debilita por lo que es necesario poner un dispositivo en la capa física que ayude a propagar la señal, este dispositivo en capa física se conoce como Hub.&lt;br /&gt;El hub resuelve el problema de la interconexión en cuanto a la propagación de la señal, pero no logra evitar las colisiones debido a que también propaga el residuo de la trama  y las colisiones se producen cuando chocan dos tramas. El hub solo reproduce bit a bit y no es capaz de ver la longitud de trama que son 64 bits por lo que no distingue cuando es  una trama completa y cuando un residuo de trama.&lt;br /&gt;El tamaño del dominio de colisión es el número de computadoras conectadas a un medio físico y es todo aquel dispositivo que puede verse afectado por una colisión.&lt;br /&gt;A nivel de capa 1 el segmento de red es el cable físico y el dispositivo para segmentar es el hub, si se extiende el cable se extiende también la colisión.&lt;/p&gt;&lt;br /&gt;&lt;p align="justify"&gt;&lt;br /&gt;El switch es un dispositivo de capa 2 y hace lo mismo que el hub pero tiene una tabla de conmutación y además es capaz de revisar la longitud de la trama de 64 bits y si es menor a 64 bits elimina la trama por lo que elimina el dominio de colisión.&lt;br /&gt;Todo dispositivo que des encapsule de capa 1 a capa 2 detiene el dominio de colisión y todo dispositivo de capa 2 que des encapsule a capa tres detiene el dominio de broadcast.&lt;br /&gt;La diferencia entre un brigde y un switch es que hacen lo mismo pero el switch lo hace en base a hardware y el brigde lo hace en base a software.&lt;br /&gt;La segmentación en capa 2(a nivel de switches) incluye los dispositivos de capa 1(a nivel de hubs), esta segmentación hace más pequeño el dominio de colisión.&lt;br /&gt;Lo único que no puede detener el switch es el dominio de broadcast, un dominio de broadcast es hasta a donde puede llegar el  broadcast.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p align="justify"&gt;&lt;br /&gt;El dominio de broadcast solo se puede detener en capa tres y a ese nivel trabajan los routers que tienen capacidades para  detener el dominio de broadcast y las capacidades de los dispositivos en capas inferiores.&lt;br /&gt;Es decir un router detiene las colisiones y destruye los paquetes de broadcast, además puede diferenciar si es una red WAN o una red LAN.&lt;br /&gt;La segmentación en capa 3 incluye dispositivos de capa 2 (switches) y de capa 1 (hubs) y esta segmentación hace más pequeño el dominio de broadcast.&lt;br /&gt;El switch trabaja con dirección MAC y el router con dirección IP, para sacar el ancho de banda de cada PC la formula es el ancho de banda del medio por el tamaño del dominio de colisión.&lt;br /&gt;&lt;div&gt;&lt;i&gt;Ancho de banda = capacidad del medio (mbps)/tdc&lt;/i&gt;&lt;/div&gt;&lt;br /&gt;Cada puerto del switch o cada interface del switch es un dominio de colisión.&lt;br /&gt;En resumen:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;El hub manipula bits&lt;/li&gt;&lt;br /&gt;&lt;li&gt;El switch manipula tramas&lt;/li&gt;&lt;br /&gt;&lt;li&gt;El router manipula paquetes&lt;/li&gt;&lt;br /&gt;&lt;li&gt;La dirección MAC son de 48 bits que representan en Hexadecimal.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;La dirección MAC nos proporciona identificación.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6494419861240446187-1776736100545127428?l=xomalli.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/1776736100545127428'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/1776736100545127428'/><link rel='alternate' type='text/html' href='http://xomalli.blogspot.com/2010/11/notas-de-la-certificacion-ccna-de-cisco.html' title='Notas de la certificación CCNA de Cisco'/><author><name>Martín Márquez</name><uri>http://www.blogger.com/profile/10939957618126542300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_j4WRR9G9bfY/SV2_nw3UxeI/AAAAAAAAAAM/nT3SYp94IHo/s1600-R/photo.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-6494419861240446187.post-8578256668118626958</id><published>2010-11-18T15:34:00.000-08:00</published><updated>2010-11-18T15:45:17.547-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Ingeniería de software'/><title type='text'>Lecturas de ingeniería de software</title><content type='html'>&lt;p align="justify"&gt;El día 19 de noviembre de 2010 dentro del grupo de procesos y estándares para el desarrollo de software se tendrá una lectura acerca de cada una de las posturas de cada autor o empresa que están publicadas en este sitio &lt;a href="http://www.semat.org/"&gt;http://www.semat.org&lt;/a&gt; dedicado a la ingeniería de software.&lt;p&gt;&lt;br /&gt;&lt;p align="justify"&gt;Las  posturas se encuentran en el enlace de &lt;a href="http://www.semat.org/bin/view/Main/WorkshopPositions"&gt;http://www.semat.org/bin/view/Main/WorkshopPositions&lt;/a&gt;&lt;/p&gt;&lt;br /&gt;&lt;p align="justify"&gt;En mí caso me toca leer las posturas de las empresas &lt;a href="http://www.semat.org/pub/Main/WorkshopPositions/SEMAT_position_corporate_Ericsson.docx"&gt;Ericsson&lt;/a&gt; y  &lt;a href="http://www.semat.org/pub/Main/WorkshopPositions/Fujitsu_SEMAT_Position_Statement.pdf"&gt; Fujitsu&lt;/a&gt;.&lt;/p&gt;&lt;br /&gt;&lt;p align="justify"&gt;En ese sitio también hacen mención de la muerte de &lt;a href="http://es.wikipedia.org/wiki/Watts_Humphrey"&gt;Watts Humphrey&lt;/a&gt; un personaje importante en la ingeniería de software, sin duda una lamentable perdida.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6494419861240446187-8578256668118626958?l=xomalli.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/8578256668118626958'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/8578256668118626958'/><link rel='alternate' type='text/html' href='http://xomalli.blogspot.com/2010/11/lecturas-de-ingenieria-de-software.html' title='Lecturas de ingeniería de software'/><author><name>Martín Márquez</name><uri>http://www.blogger.com/profile/10939957618126542300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_j4WRR9G9bfY/SV2_nw3UxeI/AAAAAAAAAAM/nT3SYp94IHo/s1600-R/photo.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-6494419861240446187.post-4746663499204518399</id><published>2010-10-31T15:17:00.000-07:00</published><updated>2010-10-31T21:19:34.310-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Lenguajes .NET'/><title type='text'>Uso de unchecked en C#</title><content type='html'>&lt;p align="justify"&gt;En este &lt;a href="http://xomalli.blogspot.com/2010/10/conversiones-y-curiosidades-acerca-de-c.html"&gt;post&lt;/a&gt; mencione sobre algunos ejemplos que tome del libro&lt;a href="http://www.javapuzzlers.com/"&gt;Java Puzzlers: Traps, Pitfalls, and Corner Cases&lt;/a&gt; de &lt;b&gt;Joshua Bloch&lt;/b&gt; y &lt;b&gt;Neal Gafter&lt;/b&gt; publicado por Addison Wesley Professional en el año 2005 donde vienen curiosidades y trucos acerca de la programación con Java, Los siguientes ejemplos se encuentran en el libro y requieren el uso en C# de los operadores &lt;a href="http://msdn.microsoft.com/en-us/library/74b4xzyw.aspx"&gt;checked&lt;/a&gt; y &lt;a href="http://msdn.microsoft.com/en-us/library/a569z7k8.aspx"&gt;unchecked&lt;/a&gt; para controlar la comprobación de &lt;i&gt;overflow&lt;/i&gt; en operaciones aritméticas y conversiones.&lt;/p&gt;&lt;br /&gt;&lt;p align="justify"&gt;Siempre que trabajemos con operaciones numéricas o con conversiones en nuestros programas hay posibilidades de que suceda un &lt;i&gt;overflow&lt;/i&gt; (desbordamiento) cuando el resultado de dicha operación sobrepase la capacidad mínima o máxima de la variable que usemos para contener ese resultado.&lt;br /&gt;Siempre que trabajemos con operaciones numéricas o con conversiones en nuestros programas hay posibilidades de que suceda un &lt;i&gt;overflow&lt;/i&gt; (desbordamiento) cuando el resultado de dicha operación sobrepase la capacidad mínima o máxima de la variable que usemos para contener ese resultado.&lt;br /&gt;Los siguientes listados ejemplifican el uso de estos operadores.&lt;/p&gt;&lt;br /&gt;&lt;div&gt;&lt;b&gt;Listado 1&lt;/b&gt;&lt;/div&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;span class="using"&gt;using&lt;/span&gt; System;&lt;br /&gt;&lt;span class="using"&gt;namespace&lt;/span&gt; Samples&lt;br /&gt;{&lt;br /&gt;&lt;span class="reserved"&gt;public class&lt;/span&gt; Puzzle4&lt;br /&gt;{&lt;br /&gt;&lt;span class="reserved"&gt;public static int&lt;/span&gt; Main(string[] args)&lt;br /&gt;{&lt;br /&gt;    &lt;span class="reserved"&gt;long&lt;/span&gt; resp = 0;&lt;br /&gt;    &lt;span class="reserved"&gt;try&lt;/span&gt;&lt;br /&gt;    {&lt;br /&gt;     &lt;br /&gt; &lt;span class="reserved"&gt;const long&lt;/span&gt; MICROS_PER_DAY = 24 * 60 * 60 * 1000 * 1000;&lt;br /&gt; &lt;span class="reserved"&gt;const long&lt;/span&gt; MILIS_PER_DAY = 24 * 60 * 60 * 1000;   &lt;br /&gt; resp = (MICROS_PER_DAY / MILIS_PER_DAY);   &lt;br /&gt;     &lt;br /&gt;    }&lt;br /&gt;&lt;span class="reserved"&gt;catch&lt;/span&gt; (OverflowException e)&lt;br /&gt;{&lt;br /&gt;    Console.WriteLine(e.Message);&lt;br /&gt;}&lt;br /&gt;Console.WriteLine("{0}", resp);&lt;br /&gt;&lt;span class="reserved"&gt;return&lt;/span&gt; 0;&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div&gt;&lt;b&gt;Listado 2&lt;/b&gt;&lt;/div&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;span class="using"&gt;using&lt;/span&gt; System;&lt;br /&gt;&lt;br /&gt;&lt;span class="using"&gt;namespace&lt;/span&gt; Samples{&lt;br /&gt;&lt;span class="reserved"&gt;public class&lt;/span&gt; Puzzle6{&lt;br /&gt;&lt;span class="reserved"&gt;public static int&lt;/span&gt; Main(string[] args){&lt;br /&gt;    &lt;span class="reserved"&gt;try&lt;/span&gt;&lt;br /&gt;    {&lt;br /&gt;Console.WriteLine(&lt;span class="reserved"&gt;(int)(char)(byte)&lt;/span&gt;-1); &lt;br /&gt;}&lt;br /&gt;&lt;span class="reserved"&gt;catch&lt;/span&gt; (OverflowException e)&lt;br /&gt;{&lt;br /&gt;    Console.WriteLine(e.Message);&lt;br /&gt;}&lt;br /&gt; &lt;span class="reserved"&gt;return&lt;/span&gt; 0;&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p align="justify"&gt;En el primer caso el compilador envía el siguiente error:&lt;tt&gt;&lt;br /&gt;Puzzle4.cs(12,50): error CS0220: The operation overflows at compile time in checked mode&lt;/tt&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/unchecked/img1.png"&gt;&lt;/div&gt;&lt;br /&gt;Para el segundo caso el mensaje es similar&lt;br /&gt;&lt;tt&gt;&lt;br /&gt;Puzzle6.cs(10,30): error CS0221: Constant value `-1' cannot be converted to a `byte' (use `unchecked' syntax to override) Compilation failed: 1 error(s), 0 warnings&lt;/tt&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/unchecked/img2.png"&gt;&lt;/div&gt;&lt;br /&gt;&lt;p align="justify"&gt;Debido a que en los dos listados el &lt;i&gt;overflow&lt;/i&gt; puede ser comprobado en tiempo de compilación, en C# de forma predeterminada todo el código asignado a constantes es comprobado aunque este dentro de un bloque &lt;a href="http://msdn.microsoft.com/en-us/library/a569z7k8.aspx"&gt;unchecked&lt;/a&gt;, y para las variables si el overflow ocurre en tiempo de ejecución el programa lanza una &lt;a href="http://msdn.microsoft.com/en-us/library/system.overflowexception.aspx"&gt;OverflowException&lt;/a&gt; excepto que sea suprimida usando &lt;a href="http://msdn.microsoft.com/en-us/library/a569z7k8.aspx"&gt;unchecked&lt;/a&gt;.&lt;/p&gt;&lt;br /&gt;&lt;div&gt;Por lo tanto para compilar los listados, debemos de usar un bloque &lt;a href="http://msdn.microsoft.com/en-us/library/a569z7k8.aspx"&gt;unchecked&lt;/a&gt;  en la asignación de las siguientes variables en el primer listado:&lt;/div&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt; &lt;span class="reserved"&gt;unchecked&lt;/span&gt;{&lt;br /&gt; &lt;span class="reserved"&gt;const long&lt;/span&gt; MICROS_PER_DAY = 24 * 60 * 60 * 1000 * 1000;&lt;br /&gt; &lt;span class="reserved"&gt;const long&lt;/span&gt; MILIS_PER_DAY = 24 * 60 * 60 * 1000;   &lt;br /&gt; resp = (MICROS_PER_DAY / MILIS_PER_DAY);   &lt;br /&gt;     }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div&gt;Y un bloque similar en el segundo listado.&lt;/div&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;span class="reserved"&gt;unchecked&lt;/span&gt;&lt;br /&gt;        {&lt;br /&gt;Console.WriteLine(&lt;span class="reserved"&gt;(int)(char)(byte)&lt;/span&gt;-1);&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p align="justify"&gt;El uso de &lt;a href="http://msdn.microsoft.com/en-us/library/a569z7k8.aspx"&gt;unchecked&lt;/a&gt; en el primer listado ocasiona que no se produzca una excepción aunque ocurra el &lt;i&gt;overflow&lt;/i&gt; esto siempre ocasiona que los valores sean truncados, por lo que el resultado de la ejecucción de este programa no es lo esperado.&lt;/p&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/unchecked/img3.png"&gt;&lt;/div&gt;&lt;br /&gt;&lt;p align="justify"&gt;Para solucionar por completo el código del listado 1 debemos agregar el caracter  &lt;tt&gt;L&lt;/tt&gt; al final del  primer término (en este ejemplo el número 24), así toda las subsecuentes expresiones seran de tipo &lt;tt&gt;long&lt;/tt&gt;.&lt;br /&gt;El bloque de código se muestra a continuación.&lt;/p&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;span class="reserved"&gt;const long&lt;/span&gt; MICROS_PER_DAY = 24L * 60 * 60 * 1000 * 1000;&lt;br /&gt; &lt;span class="reserved"&gt;const long&lt;/span&gt; MILIS_PER_DAY = 24L * 60 * 60 * 1000;   &lt;br /&gt; resp = (MICROS_PER_DAY / MILIS_PER_DAY);  &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div&gt;El código final del listado 1 es&lt;/div&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;span class="using"&gt;using&lt;/span&gt; System;&lt;br /&gt;&lt;span class="using"&gt;namespace&lt;/span&gt; Samples&lt;br /&gt;{&lt;br /&gt;&lt;span class="reserved"&gt;public class&lt;/span&gt; Puzzle4&lt;br /&gt;{&lt;br /&gt;&lt;span class="reserved"&gt;public static int&lt;/span&gt; Main(string[] args)&lt;br /&gt;{&lt;br /&gt;    &lt;span class="reserved"&gt;long&lt;/span&gt; resp = 0;&lt;br /&gt;    &lt;span class="reserved"&gt;try&lt;/span&gt;&lt;br /&gt;    {&lt;br /&gt;     &lt;span class="reserved"&gt;unchecked&lt;/span&gt;{&lt;br /&gt; &lt;span class="reserved"&gt;const long&lt;/span&gt; MICROS_PER_DAY = 24L * 60 * 60 * 1000 * 1000;&lt;br /&gt; &lt;span class="reserved"&gt;const long&lt;/span&gt; MILIS_PER_DAY = 24L * 60 * 60 * 1000;   &lt;br /&gt; resp = (MICROS_PER_DAY / MILIS_PER_DAY);   &lt;br /&gt;     }&lt;br /&gt;    }&lt;br /&gt;&lt;span class="reserved"&gt;catch&lt;/span&gt; (OverflowException e)&lt;br /&gt;{&lt;br /&gt;    Console.WriteLine(e.Message);&lt;br /&gt;}&lt;br /&gt;Console.WriteLine("{0}", resp);&lt;br /&gt;&lt;span class="reserved"&gt;return&lt;/span&gt; 0;&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div&gt;El código final del listado 2 es&lt;/div&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;span class="using"&gt;using&lt;/span&gt; System;&lt;br /&gt;&lt;br /&gt;&lt;span class="using"&gt;namespace&lt;/span&gt; Samples{&lt;br /&gt;&lt;span class="reserved"&gt;public class&lt;/span&gt; Puzzle6{&lt;br /&gt;&lt;span class="reserved"&gt;public static int&lt;/span&gt; Main(string[] args){&lt;br /&gt;    &lt;span class="reserved"&gt;try&lt;/span&gt;&lt;br /&gt;    {&lt;br /&gt;        &lt;span class="reserved"&gt;unchecked&lt;/span&gt;&lt;br /&gt;        {&lt;br /&gt;Console.WriteLine(&lt;span class="reserved"&gt;(int)(char)(byte)&lt;/span&gt;-1);&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;span class="reserved"&gt;catch&lt;/span&gt; (OverflowException e)&lt;br /&gt;{&lt;br /&gt;    Console.WriteLine(e.Message);&lt;br /&gt;}&lt;br /&gt; &lt;span class="reserved"&gt;return&lt;/span&gt; 0;&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div&gt;La salida al ejecutar el listado 1 es&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/unchecked/img4.png"&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;y la salida al ejecutar el listado 2 es&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/unchecked/img5.png"&gt;&lt;/div&gt;&lt;br /&gt;&lt;h3&gt;&lt;a href="http://www.humansharp.com/Code/unchecked.zip"&gt;&lt;img src="http://www.humansharp.com/picture_library/dw.jpg" border="0"&gt;&amp;nbsp; Descarga el código fuente&lt;/a&gt;&lt;/h3&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6494419861240446187-4746663499204518399?l=xomalli.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/4746663499204518399'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/4746663499204518399'/><link rel='alternate' type='text/html' href='http://xomalli.blogspot.com/2010/10/uso-de-unchecked-y-checked-en-c.html' title='Uso de unchecked en C#'/><author><name>Martín Márquez</name><uri>http://www.blogger.com/profile/10939957618126542300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_j4WRR9G9bfY/SV2_nw3UxeI/AAAAAAAAAAM/nT3SYp94IHo/s1600-R/photo.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-6494419861240446187.post-3268553533579919484</id><published>2010-10-25T23:20:00.000-07:00</published><updated>2010-10-26T23:27:29.473-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Lenguajes .NET'/><title type='text'>Expresiones Lambda (Lambda Expressions) con C#</title><content type='html'>&lt;p align="Justify"&gt;Las expresiones lambda provienen del cálculo lambda (lambda calculus) desarrollado por Alonzo Church en los años 1930’s como una notación para representar todas las funciones computables equivalentes a una máquina de Turing, todos los lenguajes funcionales pueden ser vistos como una variante sintáctica del cálculo lambda. &lt;br /&gt;Las expresiones Lambda son útiles para sintetizar funciones con pocos parámetros que regresan algún valor, esta expresión consiste básicamente en una regla de sustitución que expresa tal cual una función o sea un mapeo de los elementos del conjunto dominio a los elementos de un codominio  por ejemplo en la siguiente expresión:&lt;/p&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;cuadrado : integer → integer donde cuadrado(n) = n²&lt;/div&gt;&lt;br /&gt;&lt;p align="justify"&gt;Aunque C# no utiliza los símbolos de la notación matemática lambda, el operador lambda es =&gt; que significa “tiende a” o “va hacia a”, la estructura de una expresión lambda en C# es:&lt;/p&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;(Argumentos de entrada) =&gt; (salida al procesarlos)&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;Veamos algunos ejemplos:&lt;/div&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;span class="using"&gt;using&lt;/span&gt; System;&lt;br /&gt;&lt;span class="using"&gt;namespace&lt;/span&gt; Samples{&lt;br /&gt;&lt;span class="reserved"&gt;public class&lt;/span&gt; Lambda&lt;br /&gt;{&lt;br /&gt;&lt;span class="reserved"&gt;delegate int&lt;/span&gt; a(&lt;span class="reserved"&gt;int&lt;/span&gt; b, &lt;span class="reserved"&gt;int&lt;/span&gt; c);&lt;br /&gt;&lt;span class="reserved"&gt;public static int&lt;/span&gt; Main(string[] args)&lt;br /&gt;{&lt;br /&gt;    Print(5, 5, (a, b) =&gt; a + b);&lt;br /&gt;    Print(4, 2, (x, y) =&gt; x * y);&lt;br /&gt;    Print(6, 6, (a, b) =&gt; a + b);&lt;br /&gt;    Print(144, 666, (x, y) =&gt; x * y);&lt;br /&gt;    &lt;span class="reserved"&gt;return&lt;/span&gt; 0;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="reserved"&gt;static void&lt;/span&gt; Print(&lt;span class="reserved"&gt;int&lt;/span&gt; a, &lt;span class="reserved"&gt;int&lt;/span&gt; b, a del)&lt;br /&gt;{&lt;br /&gt;    Console.WriteLine("Imprimiendo: {0}",del(a, b));&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div&gt;La salida del programa es la siguiente imagen&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/lambda/lambda1.png"&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;Ahora un ejemplo con funciones estadísticas:&lt;/div&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;span class="using"&gt;using&lt;/span&gt; System;&lt;br /&gt;&lt;span class="using"&gt;using&lt;/span&gt; System.Collections.Generic;&lt;br /&gt;&lt;span class="using"&gt;using&lt;/span&gt; System.Linq;&lt;br /&gt;&lt;span class="using"&gt;using&lt;/span&gt; System.Text;&lt;br /&gt;&lt;br /&gt;&lt;span class="using"&gt;namespace&lt;/span&gt; Samples&lt;br /&gt;{&lt;br /&gt;&lt;span class="reserved"&gt;class&lt;/span&gt; Program&lt;br /&gt;{&lt;br /&gt;&lt;span class="reserved"&gt;delegate &lt;span class="reserved"&gt;double&lt;/span&gt;&lt;/span&gt; DelegateToApply(&lt;span class="reserved"&gt;double&lt;/span&gt;[] data);&lt;br /&gt;static void Main(string[] args)&lt;br /&gt;{&lt;br /&gt;    &lt;span class="reserved"&gt;double&lt;/span&gt;[] data = {&lt;br /&gt;147.8,137.4,125.2,141.1,145.7,&lt;br /&gt;119.9,133.3,142.3,138.7,125.7,&lt;br /&gt;142.0,130.8,129.8,141.2,134.9,&lt;br /&gt;125.0,128.9,142.0,118.6,133.0,&lt;br /&gt;151.1,125.7,126.3,140.9,138.9&lt;br /&gt;    };&lt;br /&gt;Console.WriteLine("\n CONJUNTO DE DATOS");&lt;br /&gt;Printf(data, 5);&lt;br /&gt;Console.WriteLine("\n Reporte:\n");&lt;br /&gt;Console.WriteLine(" Media = {0}", GetOperation(data, d =&gt;&lt;br /&gt;{&lt;br /&gt;    &lt;span class="reserved"&gt;double&lt;/span&gt; sum = 0.0;&lt;br /&gt;    &lt;span class="reserved"&gt;for&lt;/span&gt; (&lt;span class="reserved"&gt;int&lt;/span&gt; i = 0; i &lt; data.Length; i++)&lt;br /&gt;        sum += data[i];&lt;br /&gt;    &lt;span class="reserved"&gt;return&lt;/span&gt; sum / data.Length;&lt;br /&gt;}));&lt;br /&gt;Console.WriteLine(" Máximo = {0}", GetOperation(data, d =&gt;&lt;br /&gt;{&lt;br /&gt;    &lt;span class="reserved"&gt;double&lt;/span&gt; min = data[0];&lt;br /&gt;    &lt;span class="reserved"&gt;for&lt;/span&gt; (&lt;span class="reserved"&gt;int&lt;/span&gt; i = 1; i &lt; data.Length; i++)&lt;br /&gt;        &lt;span class="reserved"&gt;if&lt;/span&gt; (data[i] &lt; min)&lt;br /&gt;            min = data[i];&lt;br /&gt;    &lt;span class="reserved"&gt;return&lt;/span&gt; min;&lt;br /&gt;}));&lt;br /&gt;Console.WriteLine(" Mínimo = {0}", GetOperation(data, d =&gt;&lt;br /&gt;{&lt;br /&gt;    &lt;span class="reserved"&gt;double&lt;/span&gt; max = data[0];&lt;br /&gt;    &lt;span class="reserved"&gt;for&lt;/span&gt; (&lt;span class="reserved"&gt;int&lt;/span&gt; i = 1; i &lt; data.Length; i++)&lt;br /&gt;        &lt;span class="reserved"&gt;if&lt;/span&gt; (data[i] &gt; max)&lt;br /&gt;            max = data[i];&lt;br /&gt;    &lt;span class="reserved"&gt;return&lt;/span&gt; max;&lt;br /&gt;}));&lt;br /&gt;Console.WriteLine("Presione cualquier tecla");&lt;br /&gt;Console.Read();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;static &lt;span class="reserved"&gt;double&lt;/span&gt; GetOperation(&lt;span class="reserved"&gt;double&lt;/span&gt;[] data, DelegateToApply del)&lt;br /&gt;{&lt;br /&gt;    &lt;span class="reserved"&gt;return&lt;/span&gt; del(data);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;static void Printf(&lt;span class="reserved"&gt;double&lt;/span&gt;[] entries, &lt;span class="reserved"&gt;int&lt;/span&gt; entrywidth)&lt;br /&gt;{&lt;br /&gt;    &lt;span class="reserved"&gt;int&lt;/span&gt; size = entrywidth;&lt;br /&gt;    &lt;span class="reserved"&gt;for&lt;/span&gt; (&lt;span class="reserved"&gt;int&lt;/span&gt; i = 0; i &lt; entries.Length; i++)&lt;br /&gt;    {&lt;br /&gt;        Console.Write(" " + PadString(entries[i].ToString(), size));&lt;br /&gt;        &lt;span class="reserved"&gt;if&lt;/span&gt; ((i + 1) % entrywidth == 0)&lt;br /&gt;            Console.WriteLine();&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;static string PadString(string entry, &lt;span class="reserved"&gt;int&lt;/span&gt; size)&lt;br /&gt;{&lt;br /&gt;    StringBuilder buf = new StringBuilder(entry);&lt;br /&gt;    &lt;span class="reserved"&gt;int&lt;/span&gt; extra = size - entry.Length;&lt;br /&gt;    &lt;span class="reserved"&gt;for&lt;/span&gt; (&lt;span class="reserved"&gt;int&lt;/span&gt; i = 0; i &lt; extra; i++)&lt;br /&gt;        buf.Append(" ");&lt;br /&gt;    &lt;span class="reserved"&gt;return&lt;/span&gt; buf.ToString();&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div&gt;la salida de este ejemplo es la siguiente imagen&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/lambda/lambda2.png"&gt;&lt;/div&gt;&lt;br /&gt;&lt;p align="justify"&gt;Es importante saber que es el tipo  &lt;tt&gt;delegate&lt;/tt&gt;  que dicta el tipo de los parámetros de entrada y de salida.&lt;/p&gt;&lt;br /&gt;&lt;h3&gt;&lt;a href="http://www.humansharp.com/Code/Lambda.zip"&gt;&lt;img src="http://www.humansharp.com/picture_library/dw.jpg" border="0"&gt;&amp;nbsp; Descarga el código fuente&lt;/a&gt;&lt;/h3&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6494419861240446187-3268553533579919484?l=xomalli.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/3268553533579919484'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/3268553533579919484'/><link rel='alternate' type='text/html' href='http://xomalli.blogspot.com/2010/10/expresiones-lambda-lambda-expressions.html' title='Expresiones Lambda (Lambda Expressions) con C#'/><author><name>Martín Márquez</name><uri>http://www.blogger.com/profile/10939957618126542300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_j4WRR9G9bfY/SV2_nw3UxeI/AAAAAAAAAAM/nT3SYp94IHo/s1600-R/photo.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-6494419861240446187.post-5335581372322771608</id><published>2010-10-03T23:36:00.000-07:00</published><updated>2010-10-04T02:44:22.019-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Lenguajes .NET'/><title type='text'>Conversiones y curiosidades acerca de C#</title><content type='html'>&lt;p align="justify"&gt;En el libro &lt;a href="http://www.javapuzzlers.com/"&gt;Java Puzzlers: Traps, Pitfalls, and Corner Cases&lt;/a&gt; de &lt;b&gt;Joshua Bloch&lt;/b&gt; y &lt;b&gt;Neal Gafter&lt;/b&gt; publicado por Addison Wesley Professional en el año 2005  encontré ciertas curiosidades y trucos acerca de la programación en Java que  me llamaron la atención, los autores explican la razón de tales escollos por lo que tome algunos ejemplos del libro para programarlos con C# y ver si obtendría los mismos resultados que sus contrapartes en Java.&lt;/p&gt;&lt;br /&gt;&lt;p align="justify"&gt;Aquí algunos ejemplos del libro con las mismas preguntas, la diferencia únicamente es la implementación de Java a C#.&lt;/p&gt;&lt;br /&gt;&lt;div&gt;1-. En el siguiente programa ¿Es en todos los casos seguro que el método &lt;tt&gt;IsOdd&lt;/tt&gt;  determine correctamente si el número entero es par o no?&lt;/div&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;span class="using"&gt;using&lt;/span&gt; System;&lt;br /&gt;&lt;br /&gt;&lt;span class="using"&gt;namespace&lt;/span&gt; Samples&lt;br /&gt;{&lt;br /&gt;&lt;span class="reserved"&gt;public class&lt;/span&gt; Puzzles&lt;br /&gt;{&lt;br /&gt;&lt;span class="reserved"&gt;public static&lt;/span&gt; &lt;span class="reserved"&gt;int&lt;/span&gt; Main(string[] args)&lt;br /&gt;{&lt;br /&gt;    var i = 0;&lt;br /&gt;    &lt;span class="reserved"&gt;if&lt;/span&gt; (args.Length == 1)&lt;br /&gt;    {&lt;br /&gt;      &lt;span class="reserved"&gt;if&lt;/span&gt; (IsNumber(args[0]))&lt;br /&gt;      {&lt;br /&gt;      i = Convert.ToInt32(args[0]);&lt;br /&gt;      Console.WriteLine("{0} {1}", i, (IsOdd(i) ? "Es impar" : "Es par"));&lt;br /&gt;      }&lt;br /&gt;      &lt;span class="reserved"&gt;else&lt;/span&gt; Console.WriteLine("No es un número");&lt;br /&gt;    }&lt;br /&gt;    &lt;span class="reserved"&gt;else&lt;/span&gt;&lt;br /&gt;        Console.WriteLine("usar: Puzzle1 [number]");&lt;br /&gt;    &lt;span class="reserved"&gt;return&lt;/span&gt; 0;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="reserved"&gt;static bool&lt;/span&gt; IsOdd(&lt;span class=""&gt;int&lt;/span&gt; i)&lt;br /&gt;{&lt;br /&gt;    &lt;span class="reserved"&gt;return&lt;/span&gt; i % 2 == 1;&lt;br /&gt;}&lt;br /&gt;&lt;span class="reserved"&gt;static bool&lt;/span&gt; IsNumber(string s)&lt;br /&gt;{&lt;br /&gt;    &lt;span class=""&gt;if&lt;/span&gt; (s.IndexOf("1") != -1 ||&lt;br /&gt;    s.IndexOf("2") != -1 ||&lt;br /&gt;    s.IndexOf("3") != -1 ||&lt;br /&gt;    s.IndexOf("4") != -1 ||&lt;br /&gt;    s.IndexOf("5") != -1 ||&lt;br /&gt;    s.IndexOf("6") != -1 ||&lt;br /&gt;    s.IndexOf("7") != -1 ||&lt;br /&gt;    s.IndexOf("8") != -1 ||&lt;br /&gt;    s.IndexOf("9") != -1 ||&lt;br /&gt;    s.IndexOf("0") != -1)&lt;br /&gt;    &lt;span class="reserved"&gt;return&lt;/span&gt; &lt;span class="reserved"&gt;true&lt;/span&gt;;&lt;br /&gt;    &lt;span class="reserved"&gt;return&lt;/span&gt; &lt;span class="reserved"&gt;false&lt;/span&gt;;&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div&gt;2-.¿Qué valor imprime el siguiente programa?&lt;/div&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;span class="using"&gt;using&lt;/span&gt; System;&lt;br /&gt;&lt;br /&gt;&lt;span class="using"&gt;namespace&lt;/span&gt; Samples&lt;br /&gt;{&lt;br /&gt;&lt;span class="reserved"&gt;public class&lt;/span&gt; Puzzle2&lt;br /&gt;{&lt;br /&gt; &lt;span class="reserved"&gt;public static int&lt;/span&gt; Main(string[] args)&lt;br /&gt; {&lt;br /&gt;    Console.WriteLine(12345 + 5432l);&lt;br /&gt;    &lt;span class="reserved"&gt;return&lt;/span&gt; 0;&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div&gt;3-. ¿Cuál es el resultado del siguiente programa?&lt;/div&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;span class="using"&gt;using&lt;/span&gt; System;&lt;br /&gt;&lt;br /&gt;&lt;span class="reserved"&gt;public class&lt;/span&gt; Puzzle3&lt;br /&gt;{&lt;br /&gt;&lt;span class="reserved"&gt;public static int&lt;/span&gt; Main(string[] args)&lt;br /&gt;{&lt;br /&gt;    char x = 'X';&lt;br /&gt;    &lt;span class="reserved"&gt;int&lt;/span&gt; i = 0;&lt;br /&gt;    Console.Write(&lt;span class="reserved"&gt;true&lt;/span&gt; ? x : 0);&lt;br /&gt;    Console.Write(&lt;span class="reserved"&gt;false&lt;/span&gt; ? i : x);&lt;br /&gt;    &lt;span class="reserved"&gt;return&lt;/span&gt; 0;&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div&gt;Analicemos cada uno de los ejemplos.&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;b&gt;Ejemplo 1&lt;/b&gt;&lt;/div&gt;&lt;br /&gt;&lt;p align="justify"&gt;&lt;b&gt;Observaciones&lt;/b&gt; Al ejecutar el programa y pasarle un número entero como argumento desde la línea de comandos al parecer el programa determina si ese número es par o no, como en las siguientes imagen.&lt;/p&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/puzzles/img1.png"&gt;&lt;/div&gt;&lt;br /&gt;&lt;p align="justify"&gt;Pero el método que determina si el número es par o impar falla al pasarle un número negativo par o impar, esto siendo que toma como parámetro un entero y la mitad de los valores del tipo entero son negativos, el método supone que los residuos son únicamente positivos siendo que cuando la operación del residuo regresa un número que no es cero conserva el signo del dividendo.&lt;/p&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/puzzles/img2.png"&gt;&lt;/div&gt;&lt;br /&gt;&lt;p align="justify"&gt;La solución entonces es cambiar el método para que la comparación en vez de quedar igual a uno cambie a diferente a cero&lt;/p&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;span class="reserved"&gt;static bool&lt;/span&gt; IsOdd(int i)&lt;br /&gt;{&lt;br /&gt;    &lt;span class="reserved"&gt;return&lt;/span&gt; i % 2 != 0;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;La siguiente imagen nos muestra el resultado:&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/puzzles/img3.png"&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;b&gt;Ejemplo 2&lt;/b&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;Observaciones Este ejemplo se refiere a una mala práctica de programación, si examinamos el código puede que no nos percatemos que el último digito del segundo sumando en lugar de ser el número uno (1) es la letra l (ele) minúscula, por lo que una de las buenas prácticas de programación señaladas en el libro es no utilizar la letra l (ele) minúscula para indicar un valor numérico de tipo &lt;tt&gt;long&lt;/tt&gt; o como variable.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Console.WriteLine(12345 + 5432l);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p align="Justify"&gt;En todo caso el compilador de C# nos lanza la advertencia al compilar el programa, &lt;/p&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Puzzle2.cs(9,34): warning CS0078: The 'l' suffix is easily &lt;br /&gt;confused with the digit '1' (use 'L' for clarity)&lt;br /&gt;Compilation succeeded - 1 warning(s)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;que nos recomienda usar siempre la letra mayúscula para evitar confusiones, como se muestra en la siguiente imagen.&lt;/p&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/puzzles/img4.png"&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;b&gt;Ejemplo 3&lt;/b&gt;&lt;/div&gt;&lt;br /&gt;&lt;p align="Justify"&gt;&lt;b&gt;Observaciones&lt;/b&gt; si examinamos el código del programa, al ejecutarlo debería de imprimir XX o sea dos veces el carácter ‘X’, un carácter por cada expresión por expresión, sin embargo al ejecutar el programa imprime 8888 como en la siguiente imagen:&lt;/p&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/puzzles/img5.png"&gt;&lt;/div&gt;&lt;br /&gt;&lt;p align="Justify"&gt;Esto se debe a ciertas reglas del operador ternario u operador condicional &lt;a href=”http://msdn.microsoft.com/en-us/library/aa691313%28VS.71%29.aspx”&gt;(condicional operator) &lt;/a&gt; donde el primer operando debe ser de tipo bool que se cumple en el caso de ambas expresiones, la diferencia está en el segundo y tercer operador donde las reglas son:&lt;/p&gt;&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;Si los dos operadores son del mismo tipo la expresión devuelve ese tipo.&lt;/li&gt;&lt;br /&gt;&lt;li&gt; Si hay una conversión implícita del segundo al tercero pero no del tercero al segundo entonces la expresión devuelve el tipo del tercer operador.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Si hay una conversión implícita del tercero al segundo pero no del segundo al tercero entonces la expresión devuelve el tipo del segundo operador.&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;p align="justify"&gt;En el ejemplo 3 en la primera expresión existe la conversión implícita de &lt;tt&gt;char&lt;/tt&gt; a &lt;tt&gt;int&lt;/tt&gt; por lo que valor de la expresión es de tipo int y a imprimir es de tipo carácter se cumple la primera regla y en la segunda expresión no existe conversión implícita de &lt;tt&gt;int&lt;/tt&gt; a &lt;tt&gt;char&lt;/tt&gt; por lo se cumple la tercera regla.&lt;/p&gt;&lt;br /&gt;En ambos casos es el equivalente de &lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Console.Write((int)x);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div&gt;Para eliminar la confusión cambiemos el código a una conversión explicita:&lt;/div&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;span class="using"&gt;using&lt;/span&gt; System;&lt;br /&gt;&lt;br /&gt;&lt;span class="reserved"&gt;public class&lt;/span&gt; Puzzle3_cast{&lt;br /&gt;&lt;span class="reserved"&gt; public static int&lt;/span&gt; Main(string[] args){&lt;br /&gt;  &lt;span class="reserved"&gt;char&lt;/span&gt; x = 'X';&lt;br /&gt;  &lt;span class="reserved"&gt;int&lt;/span&gt; i = 0;&lt;br /&gt;  Console.Write(true ? x : (&lt;span class="reserved"&gt;char&lt;/span&gt;)0);&lt;br /&gt;  Console.Write(false ? (&lt;span class="reserved"&gt;char&lt;/span&gt;)i : x);&lt;br /&gt;  Console.Write(Environment.NewLine);&lt;br /&gt;  &lt;span class="reserved"&gt;return&lt;/span&gt; 0;&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div&gt;El resultado es el esperado como se muestra en la siguiente imagen:&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/puzzles/img6.png"&gt;&lt;/div&gt;&lt;br /&gt;&lt;h3&gt;&lt;a href="http://www.humansharp.com/Code/Puzzle.zip"&gt;&lt;img src="http://www.humansharp.com/picture_library/dw.jpg" border="0"&gt;&amp;nbsp; Descarga el código fuente&lt;/a&gt;&lt;/h3&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6494419861240446187-5335581372322771608?l=xomalli.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/5335581372322771608'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/5335581372322771608'/><link rel='alternate' type='text/html' href='http://xomalli.blogspot.com/2010/10/conversiones-y-curiosidades-acerca-de-c.html' title='Conversiones y curiosidades acerca de C#'/><author><name>Martín Márquez</name><uri>http://www.blogger.com/profile/10939957618126542300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_j4WRR9G9bfY/SV2_nw3UxeI/AAAAAAAAAAM/nT3SYp94IHo/s1600-R/photo.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-6494419861240446187.post-5118290549335248149</id><published>2010-09-30T22:14:00.000-07:00</published><updated>2010-09-30T22:19:28.015-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><title type='text'>Libros Gratis sobre Bases de Datos</title><content type='html'>&lt;p align="justify"&gt;Buscando bibliografía en Internet acerca de PostgreSQL, encontré esta página con enlaces para descargar libros electrónicos de sobre PostgreSQL y  otras bases de datos.&lt;br /&gt;&lt;br&gt;&lt;br /&gt;&lt;a href="http://www.database-books.us/"&gt;http://www.database-books.us/&lt;/a&gt;&lt;br /&gt;El enlace directo hacia los libros de PostgreSQL es &lt;br /&gt;&lt;a href="http://www.database-books.us/postgresql.php"&gt;http://www.database-books.us/postgresql.php&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6494419861240446187-5118290549335248149?l=xomalli.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/5118290549335248149'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/5118290549335248149'/><link rel='alternate' type='text/html' href='http://xomalli.blogspot.com/2010/09/libros-gratis-sobre-bases-de-datos.html' title='Libros Gratis sobre Bases de Datos'/><author><name>Martín Márquez</name><uri>http://www.blogger.com/profile/10939957618126542300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_j4WRR9G9bfY/SV2_nw3UxeI/AAAAAAAAAAM/nT3SYp94IHo/s1600-R/photo.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-6494419861240446187.post-3022581841340002963</id><published>2010-09-19T21:23:00.000-07:00</published><updated>2010-09-19T22:43:51.207-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><title type='text'>Trabajando con Store Procedures PL/pgSQL en PostgreSQL</title><content type='html'>&lt;p align="justify"&gt;Los  lenguajes de procedimientos &lt;i&gt;(procedural languages)&lt;/i&gt;  han extendido la funcionalidad de las bases de datos proporcionando al lenguaje SQL cierto flujo de control similar al de un lenguaje de programación.&lt;br /&gt;Cada fabricante tiene su propia implementación de un lenguaje de procedimiento basado en SQL, así &lt;b&gt;Microsoft SQL Server&lt;/b&gt; tiene &lt;b&gt;Transact-SQL&lt;/b&gt;, &lt;b&gt;Oracle&lt;/b&gt; tiene &lt;b&gt;PL/SQL&lt;/b&gt; y así sucesivamente una lista de bases de datos con su correspondiente lenguaje de procedimiento.&lt;br /&gt;En el caso de &lt;b&gt;PostgreSQL&lt;/b&gt; se tienen varios lenguajes que pueden usarse como lenguajes de procedimiento entre ellos tenemos a PL/Tcl, PL/Perl, PL/Python,C y como opción predeterminada &lt;b&gt;PL/pgSQL&lt;/b&gt;.&lt;/p&gt;&lt;br /&gt;&lt;p align="justify"&gt;Las ventajas de ejecutar funciones del lado del servidor o Store Procedures con &lt;b&gt;PL/pgSQL&lt;/b&gt; son las siguientes:&lt;/p&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;b&gt;Extensibilidad&lt;/b&gt; PL/pgsql es como un lenguaje de programación incluye la asignación y evaluación de variables y la posibilidad de hacer iteraciones y cálculos más complejos que con SQL.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;b&gt;Seguridad&lt;/b&gt; Ayuda a evitar ciertos ataques con SQL Injection ya que al utilizar parámetros evita la construcción de comandos SQL utilizando la concatenación de cadenas.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;b&gt;Rapidez&lt;/b&gt; Son ejecutados más rápidamente que las consultas SQL individuales ya que después de la primera ejecución el plan de ejecución se mantiene en memoria y el código no tiene que ser analizado ni optimizado nuevamente.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;b&gt;Programación modular&lt;/b&gt; similar a los procedimientos y funciones en los lenguajes de programación, lo que evita que se tengan planas de sentencias SQL.&lt;br /&gt;Reutilización de código una función puede ejecutarse dentro de distintos &lt;i&gt;Store Procedures&lt;/i&gt;.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;b&gt;Rendimiento&lt;/b&gt; un &lt;i&gt;Store Procedure&lt;/i&gt; puede contener decenas de sentencias SQL que son ejecutadas como una sola unidad de golpe,  a diferencia de las sentencias SQL individuales donde hay que esperar a que cada una sea procesada.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;div&gt;Mediante los siguientes ejemplos mostraremos el uso de &lt;i&gt;Store Procedures&lt;/i&gt; utilizando &lt;b&gt;PL/pgSQL&lt;/b&gt;.&lt;/div&gt;&lt;br /&gt;&lt;div&gt;Creamos una base de datos de ejemplo llamada &lt;i&gt;Catalogs&lt;/i&gt; con el siguiente comando desde el Shell.&lt;/div&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$ createdb Catalogs&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/plpgsql/img1.png"&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;Revisamos los lenguajes de procedimiento instalados en la base de datos, revisamos que &lt;b&gt;PL/pgSQL&lt;/b&gt; se encuentre instalado con el siguiente comando.&lt;/div&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$ createlang -l Catalogs&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/plpgsql/img2.png"&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;Si no se encuentra, entonces ejecutamos el siguiente comando para instalarlo, esto siempre como administrador del servidor:&lt;/div&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$ createlang –U postgres plpgsql Catalogs&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p align="justify"&gt;Si está instalado entonces abrimos un editor de texto y creamos un archivo llamado catalogs.sql donde escribiremos los comandos para crear las tablas de ejemplo y los &lt;i&gt;Store Procedures&lt;/i&gt; para administrar los registros de cada una de las tablas.&lt;/p&gt;&lt;br /&gt;&lt;div&gt;Para la creación de las tablas escribimos lo siguiente:&lt;/div&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;span class="reserved"&gt;CREATE TABLE&lt;/span&gt; Countries(&lt;br /&gt;idcountry char(3) &lt;span class="reserved"&gt;NOT NULL PRIMARY KEY&lt;/span&gt;&lt;br /&gt;,name varchar(250) &lt;span class="reserved"&gt;NOT NULL&lt;/span&gt;&lt;br /&gt;,created timestamp &lt;span class="reserved"&gt;DEFAULT NOW() NOT NULL&lt;/span&gt;&lt;br /&gt;);&lt;br /&gt;&lt;br /&gt;&lt;span class="reserved"&gt;CREATE TABLE&lt;/span&gt; States(&lt;br /&gt;idstate serial &lt;span class="reserved"&gt;NOT NULL PRIMARY KEY&lt;/span&gt;&lt;br /&gt;,name varchar(250) &lt;span class="reserved"&gt;NOT NULL&lt;/span&gt;&lt;br /&gt;,idcountry varchar(3)&lt;span class="reserved"&gt; NOT NULL REFERENCES&lt;/span&gt; Countries(idcountry)&lt;br /&gt;,created timestamp &lt;span class="reserved"&gt;DEFAULT NOW() NOT NULL&lt;/span&gt;&lt;br /&gt;);&lt;br /&gt;&lt;br /&gt;&lt;span class="reserved"&gt;CREATE TABLE&lt;/span&gt; Cities(&lt;br /&gt;idcity serial &lt;span class="reserved"&gt;NOT NULL PRIMARY KEY&lt;/span&gt;&lt;br /&gt;,name varchar(250) &lt;span class="reserved"&gt;NOT NULL&lt;/span&gt;&lt;br /&gt;,idstate int &lt;span class="reserved"&gt;NOT NULL REFERENCES&lt;/span&gt; States(idstate)&lt;br /&gt;,created timestamp &lt;span class="reserved"&gt;DEFAULT NOW() NOT NULL&lt;/span&gt;&lt;br /&gt;);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p align="justify"&gt;En acuerdo con la llave foránea definida en cada tabla, debe existir un país para poder crear un estado, así mismo debe de existir un estado para poder crear una ciudad, entonces creamos unos registros en la tabla países&lt;/p&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;span class="reserved"&gt;INSERT INTO&lt;/span&gt; Countries(idcountry,name)&lt;span class="reserved"&gt;VALUES&lt;/span&gt;('arg','argentina');&lt;br /&gt;&lt;span class="reserved"&gt;INSERT INTO&lt;/span&gt; Countries(idcountry,name)&lt;span class="reserved"&gt;VALUES&lt;/span&gt;('bra','brasil');&lt;br /&gt;&lt;span class="reserved"&gt;INSERT INTO&lt;/span&gt; Countries(idcountry,name)&lt;span class="reserved"&gt;VALUES&lt;/span&gt;('ury','uruguay');&lt;br /&gt;&lt;span class="reserved"&gt;INSERT INTO&lt;/span&gt; Countries(idcountry,name)&lt;span class="reserved"&gt;VALUES&lt;/span&gt;('mex','méxico');&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/plpgsql/img3.png"&gt;&lt;/div&gt;&lt;br /&gt;&lt;p align="justify"&gt;Supongamos que estas tablas van a utilizarse en un sistema donde sea obligatorio que los nombres de país, estado y ciudad, se almacenen teniendo la primera letra mayúscula o en notación &lt;i&gt;Camel Case&lt;/i&gt;,(en este caso los países quedaron guardados con letras minúsculas de manera intencional, con el fin  de mostrar un &lt;i&gt;Store Procedure&lt;/i&gt;).&lt;/p&gt;&lt;br /&gt;&lt;div&gt;Creamos entonces una función para aplicar esta regla a los datos de la tabla countries.&lt;/div&gt;&lt;br /&gt;&lt;div&gt;La función se define con el siguiente código:&lt;/div&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;span class="reserved"&gt;CREATE FUNCTION&lt;/span&gt; UpperCamelCase(varchar) &lt;span class="reserved"&gt;RETURNS&lt;/span&gt; varchar &lt;span class="reserved"&gt;AS&lt;/span&gt;&lt;br /&gt;&lt;span class="void"&gt;'DECLARE&lt;br /&gt;        res varchar;&lt;br /&gt;BEGIN&lt;br /&gt;        SELECT INTO  res UPPER(SUBSTRING($1,1,1)) || LOWER(SUBSTRING($1,2));&lt;br /&gt;        return res;&lt;br /&gt;END;'&lt;/span&gt;&lt;br /&gt;&lt;span class="reserved"&gt;LANGUAGE&lt;/span&gt; 'plpgsql';&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div&gt;Lo aplicamos de la  siguiente manera para actualizar los registros.&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/plpgsql/img4.png"&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;Una vez creada en el servidor se encuentra disponible para cualquier transformación que queramos aplicar sobre cualquier cadena.&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/plpgsql/img5.png"&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;Ahora escribiremos las funciones para insertar registros en cada una de las tablas.&lt;/div&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;span class="reserved"&gt;CREATE FUNCTION&lt;/span&gt; InsertState(varchar,varchar) &lt;span class="reserved"&gt;RETURNS&lt;/span&gt; int &lt;span class="reserved"&gt;AS&lt;/span&gt;&lt;br /&gt;&lt;span class="void"&gt;'DECLARE&lt;br /&gt;        regs record;&lt;br /&gt;        res numeric;&lt;br /&gt;BEGIN&lt;br /&gt;        SELECT INTO regs count(name) FROM States WHERE name = UpperCamelCase($1);&lt;br /&gt;        IF regs.count = 0&lt;br /&gt;                THEN&lt;br /&gt;                INSERT INTO States(name,idcountry)VALUES(UPPER($1,$2));&lt;br /&gt;                SELECT INTO res idstate FROM States WHERE name = UpperCamelCase($1);&lt;br /&gt;                RETURN res;&lt;br /&gt;        END IF;&lt;br /&gt;        IF regs.count &gt; 0&lt;br /&gt;                THEN&lt;br /&gt;                SELECT INTO res idstate FROM States WHERE name = UpperCamelCase($1);&lt;br /&gt;        RETURN res;&lt;br /&gt;        END IF;&lt;br /&gt;END;&lt;br /&gt;' &lt;/span&gt;&lt;span class="reserved"&gt;LANGUAGE&lt;/span&gt;  'plpgsql';&lt;br /&gt;&lt;br /&gt;&lt;span class="reserved"&gt;CREATE FUNCTION&lt;/span&gt;InsertCity (varchar,numeric) &lt;span class="reserved"&gt;RETURNS&lt;/span&gt; int &lt;span class="reserved"&gt;AS&lt;/span&gt;&lt;br /&gt;&lt;span class="void"&gt;'DECLARE&lt;br /&gt;        regs record;&lt;br /&gt;        res numeric;&lt;br /&gt;BEGIN&lt;br /&gt;        SELECT INTO regs count(name) FROM Cities WHERE name = UpperCamelCase($1);&lt;br /&gt;        IF regs.count = 0&lt;br /&gt;                THEN&lt;br /&gt;                INSERT INTO Cities(name,idstate)VALUES(UPPER($1,$2));&lt;br /&gt;                SELECT INTO res idcity FROM Cities WHERE name = UpperCamelCase($1);&lt;br /&gt;                RETURN res;&lt;br /&gt;        END IF;&lt;br /&gt;        IF regs.count &gt; 0&lt;br /&gt;                THEN&lt;br /&gt;                SELECT INTO res idcity FROM Cities WHERE name = UpperCamelCase($1);&lt;br /&gt;        RETURN res;&lt;br /&gt;        END IF;&lt;br /&gt;END;&lt;br /&gt;' &lt;/span&gt;&lt;span class="reserved"&gt;LANGUAGE&lt;/span&gt;  'plpgsql';&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div&gt;Básicamente la estructura de un &lt;i&gt;Store Procedure&lt;/i&gt; es la siguiente:&lt;/div&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;span class="reserved"&gt;CREATE FUNCTION&lt;/span&gt; [nombre de la función] ([parámetros separados por comas]) &lt;span class="reserved"&gt;RETURNS&lt;/span&gt; [el tipo de dato que regresa] &lt;span class="reserved"&gt;AS&lt;/span&gt;&lt;br /&gt;&lt;span class="void"&gt;'DECLARE aquí se definen las variables que se usarán.&lt;br /&gt;BEGIN indica el inicio de la función.&lt;br /&gt;SELECT INTO este comando permite que los resultados de las consultas sean asignados a variables. (no debe de confundirse con SELECT [columnas] INTO)&lt;br /&gt;RETURN Sale de la función y regresa el tipo de dato que se declaro después de la palabra RETURNS del CREATE FUNCTION&lt;br /&gt;END indica el fin de la función&lt;/span&gt;&lt;br /&gt;' &lt;span class="reserved"&gt;LANGUAGE&lt;/span&gt; indica con que lenguaje esta escrita la función, puede ser un lenguaje de procedimiento (plpgsql) o de consulta (SQL).&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p align="justify"&gt;Vemos que en cada &lt;i&gt;Store Procedure&lt;/i&gt;, reutiliza la función UpperCamelCase(varchar) que habíamos previamente creado.&lt;br /&gt;Esto porque un &lt;i&gt;Store Procedure&lt;/i&gt; puede llamar a otro &lt;i&gt;Store Procedure&lt;/i&gt; que se encuentre disponible.&lt;br /&gt;En las siguientes imágenes los resultados de la ejecución de cada &lt;i&gt;Store Procedure&lt;/i&gt;.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/plpgsql/img6.png"&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/plpgsql/img7.png"&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/plpgsql/img8.png"&gt;&lt;/div&gt;&lt;br /&gt;&lt;h3&gt;&lt;a href="http://www.humansharp.com/Code/catalogs.zip"&gt;&lt;img src="http://www.humansharp.com/picture_library/dw.jpg" border="0"&gt;&amp;nbsp; Descarga el código fuente para PostgreSQL&lt;/a&gt;&lt;/h3&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6494419861240446187-3022581841340002963?l=xomalli.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/3022581841340002963'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/3022581841340002963'/><link rel='alternate' type='text/html' href='http://xomalli.blogspot.com/2010/09/trabajando-con-store-procedures-con.html' title='Trabajando con Store Procedures PL/pgSQL en PostgreSQL'/><author><name>Martín Márquez</name><uri>http://www.blogger.com/profile/10939957618126542300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_j4WRR9G9bfY/SV2_nw3UxeI/AAAAAAAAAAM/nT3SYp94IHo/s1600-R/photo.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-6494419861240446187.post-705869952794512895</id><published>2010-09-07T17:27:00.000-07:00</published><updated>2010-09-19T22:33:59.815-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><title type='text'>Utilizando los objetos NpgsqlConnection y NpgConnectionStringBuilder para PostgreSQL con MonoDevelop</title><content type='html'>Hoy día es difícil imaginarse un sistema informático que no haga uso de fuente de datos para persistir información.&lt;br /&gt;Entre estas fuentes de datos se encuentran:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Sin estructura: Archivos que no tienen un orden lógico. (Cartas, memos)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Estructurado, sin jerarquía: Contienen datos agrupados por separadores o indicadores de inicio y fin (archivos de acceso secuencial, archivos separados por tabuladores ó comas)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Jerárquica: tienen una estructura de nodos anidados. (XML)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Bases de datos relacionales: &lt;/li&gt;&lt;br /&gt;&lt;li&gt;Objetos: Los datos están organizados como objetos.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;p align="justify"&gt;&lt;br /&gt;Debido a esta variedad, las clases de ADO para acceder y extraer cuentan con un diseño independiente  y portable de la implementación de la fuente de datos que se utilice.&lt;br /&gt;Desde luego, primeramente debemos tener acceso a la fuente de datos antes de ejecutar operaciones de consulta o modificación.&lt;br /&gt;Para lograr este propósito usamos un objeto proveedor de conexión especifico según la fuente de datos a utilizar, cada uno de estos objetos son equivalentes en funcionalidades generales por derivar de la clase &lt;a href="http://msdn.microsoft.com/es-es/library/system.data.common.dbconnection(VS.80).aspx"&gt;DBConnection.&lt;/a&gt;&lt;br /&gt;Aunque estos objetos son equivalentes en la funcionalidad general, cada uno tiene código específico para su fuente de datos, como se muestra en la tabla siguiente.&lt;/p&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;+-----------------+-------------------+&lt;br /&gt;| Fuente de datos |Objeto de conexión |&lt;br /&gt;+-----------------+-------------------+&lt;br /&gt;| SQL Server      | SqlConnection     |&lt;br /&gt;+-----------------+-------------------+&lt;br /&gt;| Suportan OLE DB | OleDbConnection   |&lt;br /&gt;+-----------------+-------------------+&lt;br /&gt;| Oracle          | Oracleconnection* |&lt;br /&gt;+-----------------+-------------------+&lt;br /&gt;| PostgreSQL      | NpgsqlConnection  |&lt;br /&gt;+-----------------+-------------------+&lt;br /&gt;*Depende de que el cliente de Oracle se encuentre instalado.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;b&gt;El objeto NpgsqlConnection&lt;/b&gt;&lt;br /&gt;&lt;p align="justify"&gt;&lt;br /&gt;Un objeto conexión representa una conexión física a una fuente de datos, por lo que una de las mejores recomendaciones es conectarse y cerrar las conexiones abiertas en cuanto dejen de utilizarse.&lt;br /&gt;&lt;b&gt; ConnectionStrings (Cadenas de conexión)&lt;/b&gt;&lt;br /&gt;Antes de trabajar con cualquiera de los objetos de conexión es indispensable proporcionarle la Connection String (cadena de conexión) , esta Connection String es propia de cada objeto Connection y cada objeto Connection es propio de cada fuente de datos con la que trabajemos.&lt;br /&gt;La cadena de conexión es una serie de parámetros y valores separados por (;) y aunque cada Connection String cambie según el proveedor de Base de datos, hay ciertos parámetros que son siempre requeridos, como:&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;+---------------------------+-------------------------------------------------+&lt;br /&gt;|Data Source o Server       | El lugar donde se encuentra la fuente de datos: |&lt;br /&gt;                            | servidor, máquina, lugar de red, IP, directorio,|&lt;br /&gt;                            | archivo.                                        |&lt;br /&gt;+---------------------------+-------------------------------------------------+&lt;br /&gt;DataBase o Initial Catalog  | El nombre de la base de datos a usar.           |&lt;br /&gt;+---------------------------+-------------------------------------------------+&lt;br /&gt;|User ID                    | El usuario para acceder.                        |&lt;br /&gt;+---------------------------+-------------------------------------------------+&lt;br /&gt; Password                   | El password del usuario para aceder             |&lt;br /&gt;+---------------------------+-------------------------------------------------+&lt;br /&gt;Integrated Security         | Si es true se utiliza la seguridad de Windows &lt;br /&gt;                            | para acceder, si es false se debe de proporcionar &lt;br /&gt;                            | el user y password para acceder.&lt;br /&gt;+---------------------------+-------------------------------------------------+&lt;br /&gt;Timeout o Connection Timeout| El tiempo que debe esperar la aplicación para   |&lt;br /&gt;                            | que el servidor le asigne una conexión.         |&lt;br /&gt;                            | El valor predeterminado es de 15 segundos       |&lt;br /&gt;+---------------------------+-------------------------------------------------+&lt;br /&gt;Pooling                     | Crea un pool de conexiones para la cadena de    |&lt;br /&gt;                            | conexión si no existe, caso contrario           |&lt;br /&gt;                            | asigna una conexión de un pool existente.       |&lt;br /&gt;+---------------------------+-------------------------------------------------+&lt;br /&gt;MinPoolSize                 | Número mínimo de conexiones por pool, valor     |&lt;br /&gt;                            | predeterminado 1                                |&lt;br /&gt;+---------------------------+-------------------------------------------------+&lt;br /&gt;MaxPoolSize                 | Número máximo de conexiones por pool, valor     |&lt;br /&gt;                            | máximo permitido 100                            |&lt;br /&gt;+---------------------------+-------------------------------------------------+&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p align="justify"&gt;El sitio &lt;a href="http://www.connectionstrings.com/"&gt;Connection Strings.com&lt;/a&gt; contiene ejemplos y una amplia referencia a cada uno de los parámetros y valores según la fuente de datos.&lt;/p&gt;&lt;br /&gt;&lt;b&gt;El objeto NpgsqlConnectionStringBuilder&lt;/b&gt;&lt;br /&gt;&lt;p align="Justify"&gt;Hay una clase que nos ayuda a evitar errores de sintaxis al momento de construir cadenas de conexión, esto para no tener recordar cada una de las opciones en el caso de trabajar con diferentes bases de datos. Esta clase es similar a las clases Connection, hay una clase DbConnectionStringBuilder de donde surgen las objetos ConnectionStringBuilder específicos para cada cadena de conexión de cada objeto Connection.&lt;br /&gt;Derivados de la clase &lt;tt&gt;DbConnectionStringBuilder&lt;/tt&gt;, existe la clases &lt;tt&gt;NpgsqlConnectionStringBuilder&lt;/tt&gt; la cual encapsula una ConnectionString (cadena de conexión) para PostgreSQL, la cual demostraremos en el siguiente programa junto con el uso de la clase &lt;tt&gt;NpgsqlConnection&lt;/tt&gt; respectivamente.&lt;/p&gt;&lt;br /&gt;&lt;div&gt; Abrimos MonoDevelop, creamos una nueva solución GTK# y agregamos unos controles al formulario para que su aspecto luzca como en la siguiente imagen.&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/npgconn/pgstrb1.png"&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;Como utilizaremos el proveedor de datos de &lt;a href="http://npgsql.projects.postgresql.org/"&gt;PostgreSQL para .NET&lt;/a&gt; debemos agregarlo a la solución, hacemos click derecho en la solución(recomiendo la versión 2.x).&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/npgconn/pgstrb2.png"&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;Aparecerá la ventana para agregar/quitar las referencias a los ensamblados instalados en el GAC o para buscarlos en el sistema de archivos.&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/npgconn/pgstrb3.png"&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;Una vez agregado correctamente, se mostrará el ensamblado en la solución.&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/npgconn/pgstrb4.png"&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;Dentro del método para dar funcionalidad al botón de aceptar, mostramos la utilización de la clase &lt;tt&gt;NpgsqlConnectionStringBuilder&lt;/tt&gt; como ayuda para crear la cadena de conexión.&lt;/div&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;NpgsqlConnectionStringBuilder connString = &lt;span class="reserved"&gt;new&lt;/span&gt; NpgsqlConnectionStringBuilder();&lt;br /&gt;connString.Host = txtServer.Text;&lt;br /&gt;connString.Database = @txtDataBase.Text;&lt;br /&gt;connString.UserName = @txtUserID.Text;&lt;br /&gt;connString.Password = @txtPassWord.Text;&lt;br /&gt;connString.Timeout = (string.IsNullOrEmpty(txtTimeOut.Text) ? 0 : Convert.ToInt32(txtTimeOut.Text));&lt;br /&gt;connString.Pooling = &lt;span class="reserved"&gt;this&lt;/span&gt;.chkPooling.Active;&lt;br /&gt;connString.MinPoolSize = (String.IsNullOrEmpty(txtMinPool.Text) ? 0 : Convert.ToInt32(txtMinPool.Text));&lt;br /&gt;connString.MaxPoolSize = (String.IsNullOrEmpty(txtMaxPool.Text) ? 0 : Convert.ToInt32(txtMaxPool.Text));&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div&gt;También dentro de este método tenemos el código para la creación de la conexión al servidor.&lt;/div&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;span class="using"&gt;using&lt;/span&gt;(NpgsqlConnection conn = &lt;span class="reserved"&gt;new&lt;/span&gt; NpgsqlConnection(connString.ToString())){&lt;br /&gt;conn.Open();&lt;br /&gt;&lt;span class="reserved"&gt;if&lt;/span&gt;(conn.State ==  System.Data.ConnectionState.Open)&lt;br /&gt;  MessageBox("Conexión exitosa",MessageType.Info);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div&gt; Si descargamos el código completo del proyecto, al compilarlo correctamente y ejecutarlo,nos pedirá teclear los parámetros para una conexión hacia un servidor PostgreSQL.&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/npgconn/pgstrb5.png"&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt; Si los parámetros son correctos y el servidor se encuentra disponible entonces la aplicación mostrará el mensaje siguiente:&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/npgconn/pgstrb6.png"&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;En caso de un parámetro incorrecto nos mostrará los mensajes de la excepción recibida.&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/npgconn/pgstrb7.png"&gt;&lt;/div&gt;&lt;br /&gt;&lt;h3&gt;&lt;a href="http://www.humansharp.com/Code/SimpleNpgConn.zip"&gt;&lt;img src="http://www.humansharp.com/picture_library/dw.jpg" border="0"&gt;&amp;nbsp; Descarga el código fuente del proyecto para MonoDevelop&lt;/a&gt;&lt;/h3&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6494419861240446187-705869952794512895?l=xomalli.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/705869952794512895'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/705869952794512895'/><link rel='alternate' type='text/html' href='http://xomalli.blogspot.com/2010/09/utilizando-los-objetos-npgsqlconnection.html' title='Utilizando los objetos NpgsqlConnection y NpgConnectionStringBuilder para PostgreSQL con MonoDevelop'/><author><name>Martín Márquez</name><uri>http://www.blogger.com/profile/10939957618126542300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_j4WRR9G9bfY/SV2_nw3UxeI/AAAAAAAAAAM/nT3SYp94IHo/s1600-R/photo.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-6494419861240446187.post-8389810703234211414</id><published>2010-08-21T20:22:00.000-07:00</published><updated>2010-08-25T12:53:53.575-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><title type='text'>Utilizando la clase FtpWebRequest para un cliente básico FTP con MonoDevelop</title><content type='html'>&lt;p align="justify"&gt;Una de las tareas más habituales que existen en el tema de interacción entre sistemas es la copia de archivos de una máquina a otra, existen distintos mecanismos según el tipo de sistema operativo que se disponga entre la máquina destino y la máquina fuente, por ejemplo si se trata de sistemas UNIX/Gnu/Linux podemos utilizar el comando  &lt;tt&gt;rcp&lt;/tt&gt; o &lt;tt&gt;scp&lt;/tt&gt; si se trata del servicio SSH.&lt;br /&gt;Para el caso de copiar archivos entre sistemas operativos distintos la opción más común es utilizar el protocolo FTP (File Transfer Protocol) que es un protocolo orientado al usuario que hace uso de comandos para realizar operaciones con archivos en el servidor donde se establece la comunicación y para el cual .NET nos ofrece la clase &lt;a href="http://msdn.microsoft.com/en-us/library/system.net.ftpwebrequest.aspx"&gt;FtpWebRequest&lt;/a&gt; que encapsula toda la funcionalidad de un cliente FTP y de los comandos propios del protocolo mediante los campos de la clase &lt;a href="http://msdn.microsoft.com/en-us/library/system.net.webrequestmethods.ftp.aspx"&gt;WebRequestMethods.Ftp&lt;/a&gt;.&lt;/p&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;+====================+========+==========================================+&lt;br /&gt;| OPERACIÓN          |COMANDO | DESCRIPCIÓN                              |&lt;br /&gt;+====================+========+==========================================+&lt;br /&gt;|AppendFile          |APPE    | Anexa un archivo a un archivo existente. |&lt;br /&gt;+--------------------+--------+------------------------------------------+&lt;br /&gt;|DeleteFile          | DELE   | Elimina un archivo existente.            |&lt;br /&gt;+--------------------+--------+------------------------------------------+&lt;br /&gt;|DownloadFile        | RETR   | Descarga un archivo existente.           |&lt;br /&gt;+--------------------+--------+------------------------------------------+&lt;br /&gt;|GetDateTimestamp    | MDTM   | Obtiene el date-time stamp de un archivo.|&lt;br /&gt;+--------------------+--------+------------------------------------------+&lt;br /&gt;|GetFileSize         | SIZE   | Obtiene el tamaño de un archivo.         |&lt;br /&gt;+--------------------+--------+------------------------------------------+&lt;br /&gt;|ListDirectory       | NLIST  | obtiene un listado corto de los archivos |&lt;br /&gt;|                               de un directorio en el servidor.         |&lt;br /&gt;+--------------------+---------------------------------------------------+&lt;br /&gt;|ListDirectoryDetails| LIST   | Obtiene un listado detallado de los      |&lt;br /&gt;                                archivos de un directorio en el servidor.|  &lt;br /&gt;+--------------------+--------+------------------------------------------+&lt;br /&gt;|MakeDirectory       | MKD    | Crea un directorio en el servidor.      |    &lt;br /&gt;+----------------------+------+-----------------------------------------+&lt;br /&gt;|PrintWorkingDirectory | PWD  | Imprime el nombre del directorio        |&lt;br /&gt;                                 de trabajo.                            |&lt;br /&gt;+----------------------+------+-----------------------------------------+&lt;br /&gt;|RemoveDirectory       | RMD  | Elimina un directorio.                  |&lt;br /&gt;+----------------------+------+-----------------------------------------+&lt;br /&gt;|Rename                | RENAME| Renombra un directorio.                |&lt;br /&gt;+----------------------+-------+----------------------------------------+&lt;br /&gt;|UploadFile            | STOR  | Envia un archivo al servidor.          |&lt;br /&gt;+------------------------+-----+----------------------------------------+&lt;br /&gt;|UploadFileWithUniqueName|STOU |Envia un archivo con                    |&lt;br /&gt;                                un nombre unico al servidor.            |&lt;br /&gt;+------------------------+-----+----------------------------------------+&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p align="Justify"&gt;&lt;br /&gt;Y que ejemplificaremos a continuación programando un cliente FTP básico con MonoDevelop.&lt;br /&gt;Ejecutamos MonoDevelop y diseñamos un formulario GTK# como se muestra en la siguiente imagen:&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/monoftp/monoftp5.png"&gt;&lt;/div&gt;&lt;br /&gt;&lt;p align="justify"&gt;Agregamos una nueva clase a nuestro proyecto con el nombre de FtpDAO, que es donde se encontrarán los métodos que darán la funcionalidad a nuestro formulario.&lt;br /&gt;En esta clase hacemos referencia a los siguientes ensamblados:&lt;/p&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;span class="using"&gt;using&lt;/span&gt; System.IO;&lt;br /&gt;&lt;span class="using"&gt;using&lt;/span&gt; System.Net;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p align="justify"&gt;Y completamos la funcionalidad de la clase con los siguientes métodos.&lt;br /&gt;Para listar los archivos del directorio en el servidor, escribimos el siguiente método:&lt;/p&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;span class="reserved"&gt;public&lt;/span&gt; ListStore ObtenerListado(Uri serverUri,bool lsl){&lt;br /&gt;_ftprequest = (FtpWebRequest)WebRequest.Create(serverUri);&lt;br /&gt;_ftprequest.Credentials = creden;&lt;br /&gt;_ftprequest.KeepAlive = &lt;span class="reserved"&gt;true&lt;/span&gt;;&lt;br /&gt;ListStore ls_l = &lt;span class="reserved"&gt;new&lt;/span&gt; ListStore(typeof(string));&lt;br /&gt;&lt;span class="reserved"&gt;if&lt;/span&gt;(lsl)&lt;br /&gt;_ftprequest.Method = WebRequestMethods.Ftp.ListDirectoryDetails;&lt;br /&gt;&lt;span class="reserved"&gt;else&lt;/span&gt;&lt;br /&gt;_ftprequest.Method = WebRequestMethods.Ftp.ListDirectory;&lt;br /&gt;_ftprequest.UseBinary = &lt;span class="reserved"&gt;true&lt;/span&gt;;&lt;br /&gt;_ftprequest.UsePassive = &lt;span class="reserved"&gt;true&lt;/span&gt;;&lt;br /&gt;_ftprequest.Timeout = 20000;&lt;br /&gt;&lt;span class="using"&gt;using&lt;/span&gt;(FtpWebResponse response = (FtpWebResponse)_ftprequest.GetResponse()){&lt;br /&gt;&lt;span class="using"&gt;using&lt;/span&gt;(StreamReader reader = &lt;span class="reserved"&gt;new&lt;/span&gt; StreamReader(response.GetResponseStream())){&lt;br /&gt;string ln = "";&lt;br /&gt;&lt;span class="reserved"&gt;do&lt;/span&gt;&lt;br /&gt;{&lt;br /&gt;ln = reader.ReadLine();&lt;br /&gt;&lt;span class="reserved"&gt;if&lt;/span&gt;(ln != null){&lt;br /&gt;ls_l.AppendValues(ln); &lt;br /&gt;}&lt;br /&gt;}&lt;span class="reserved"&gt;while&lt;/span&gt;(ln != null);&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;span class="reserved"&gt;return&lt;/span&gt; ls_l;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p align="justify"&gt;&lt;br /&gt;Que nos regresa la lista de los archivos en un objeto ListStore que servirá de modelo para nuestra interfaz gráfica.&lt;br /&gt;Con el siguiente código establecemos un Uri con la dirección IP o Host y con el directorio al cuál accedemos.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;string.Format("ftp://{0}/{1}/",txtServer.Text,txtDir.Text);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;La clase &lt;a href="http://msdn.microsoft.com/en-us/library/system.uri.aspx"&gt;Uri&lt;/a&gt; sirve para encapsular un URI (Uniform Resource Identifier) que es una manera de identificar  &lt;br /&gt;Sin ambigüedades un recurso en Internet, puede ser un archivo, una dirección email o una dirección IP con su protocolo. Hay dos tipos de URIs: URL (Universal Resource Location) o URN (Universal Resource Names), en C# la clase &lt;a href="http://msdn.microsoft.com/en-us/library/system.uri.aspx"&gt;Uri&lt;/a&gt; nos brinda todos los métodos y propiedades para el manejo de URI's.&lt;br /&gt;En nuestro ejemplo será  la URL del servidor de FTP, como se utiliza con la línea.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Uri serverUri = &lt;span class="reserved"&gt;new&lt;/span&gt; Uri(string.Format("ftp://{0}/{1}/",txtServer.Text,txtDir.Text));&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Donde concatenamos el protocolo con la IP o nombre del servidor y el directorio donde mostramos el listado, para después seleccionar el archivo a descargar.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;h3&gt;C# WebRequest y WebResponse&lt;/h3&gt;&lt;br /&gt;&lt;p align="justify"&gt;&lt;br /&gt;La clase &lt;a href="http://msdn.microsoft.com/en-us/library/system.net.webrequest(VS.71).aspx"&gt;System.Net.WebRequest&lt;/a&gt; representa una petición al servidor y la clase &lt;a href="http://msdn.microsoft.com/en-us/library/system.net.httpwebresponse.aspx"&gt;System.Net.WebResponse&lt;/a&gt; representa la respuesta del servidor como un flujo de datos o &lt;a href="http://msdn.microsoft.com/en-us/library/system.io.streamreader.aspx"&gt;StreamReader&lt;/a&gt;.&lt;br /&gt;Usamos el método estático &lt;tt&gt;Create&lt;/tt&gt; de WebRequest para solicitar el recurso del servidor dependiendo del URI que le pasemos como parámetro.&lt;/p&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;_ftprequest = (FtpWebRequest)WebRequest.Create(serverUri);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p align="justify"&gt;Usamos el método &lt;tt&gt;GetResponse&lt;/tt&gt; para obtener la respuesta como un flujo de datos y asociándola a un objeto &lt;a href="http://msdn.microsoft.com/en-us/library/system.io.streamreader.aspx"&gt;StreamReader&lt;/a&gt;.&lt;/p&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;span class="using"&gt;using&lt;/span&gt;(FtpWebResponse listResponse = (FtpWebResponse)_ftprequest.GetResponse()){&lt;br /&gt;&lt;span class="using"&gt;using&lt;/span&gt;(StreamReader reader = &lt;span class="reserved"&gt;new&lt;/span&gt; StreamReader(listResponse.GetResponseStream())){&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p align="justify"&gt;Podemos establecer el timeout de la respuesta en milisegundos con la propiedad timeout que tiene un valor predeterminado de 10000. &lt;br /&gt;La funcionalidad de descargar un archivo se la damos con el siguiente método.&lt;/p&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public &lt;span class="reserved"&gt;void&lt;/span&gt; DescargarArchivo(Uri serverUri,string destino,bool modobin)&lt;br /&gt;{&lt;br /&gt;_ftprequest = (FtpWebRequest)WebRequest.Create(serverUri);&lt;br /&gt;_ftprequest.Credentials = creden;&lt;br /&gt;_ftprequest.KeepAlive = &lt;span class="reserved"&gt;true&lt;/span&gt;;&lt;br /&gt;_ftprequest.Method = WebRequestMethods.Ftp.DownloadFile;&lt;br /&gt;_ftprequest.UseBinary = modobin;&lt;br /&gt;_ftprequest.UsePassive = &lt;span class="reserved"&gt;true&lt;/span&gt;;&lt;br /&gt;string contenido = "";&lt;br /&gt;char[] charbuffer = null;&lt;br /&gt;byte[] bytebuffer = &lt;span class="reserved"&gt;new&lt;/span&gt; byte[2048];&lt;br /&gt;int tbytes = 0;&lt;br /&gt;&lt;span class="using"&gt;using&lt;/span&gt;(FtpWebResponse response = (FtpWebResponse)_ftprequest.GetResponse())&lt;br /&gt;{&lt;br /&gt;&lt;span class="using"&gt;using&lt;/span&gt;(Stream stream = response.GetResponseStream())&lt;br /&gt;{&lt;br /&gt;&lt;span class="using"&gt;using&lt;/span&gt; (FileStream fileout = &lt;span class="reserved"&gt;new&lt;/span&gt; FileStream(destino, FileMode.Create, FileAccess.ReadWrite))&lt;br /&gt;{&lt;br /&gt;&lt;span class="reserved"&gt;if&lt;/span&gt; (modobin)&lt;br /&gt;{&lt;br /&gt;&lt;span class="reserved"&gt;do&lt;/span&gt;&lt;br /&gt;{&lt;br /&gt;tbytes = stream.Read(bytebuffer, 0, 2048);&lt;br /&gt;fileout.Write(bytebuffer,0,bytebuffer.Length);&lt;br /&gt;} &lt;span class="reserved"&gt;while&lt;/span&gt; (tbytes != 0);&lt;br /&gt;}&lt;br /&gt;&lt;span class="reserved"&gt;else&lt;/span&gt;&lt;br /&gt;{&lt;br /&gt;&lt;span class="using"&gt;using&lt;/span&gt;(StreamReader reader = &lt;span class="reserved"&gt;new&lt;/span&gt; StreamReader(stream)){&lt;br /&gt;contenido = reader.ReadToEnd();&lt;br /&gt;charbuffer = contenido.ToCharArray();&lt;br /&gt;}&lt;br /&gt;&lt;span class="using"&gt;using&lt;/span&gt;(StreamWriter text = &lt;span class="reserved"&gt;new&lt;/span&gt; StreamWriter(fileout)){&lt;br /&gt;text.Write(charbuffer,0,charbuffer.Length);&lt;br /&gt;}}}}} &lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;Al construir y ejecutar la aplicación veremos los resultados como en las siguientes imágenes.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;Al oprimir el botón &lt;tt&gt;Aceptar&lt;/tt&gt; después de teclear la IP, el directorio, el usuario y el password, si son válidos para el servidor se muestra el listado de los archivos.&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/monoftp/monoftp1.png"&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;Si activamos la casilla de &lt;tt&gt;Listado detallado&lt;/tt&gt; mostrará el listado detallado de los archivos.&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/monoftp/monoftp2.png"&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;En caso de que ocurra un error en la conexión con el servidor, se mostrará un mensaje con la excepción correspondiente.&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/monoftp/monoftp4.png"&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;Si seleccionamos un archivo de la lista de archivos y pulsamos el botón guardar se solicitará el archivo del servidor y se guardará en el disco duro en el directorio donde se ejecute la aplicación.&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/monoftp/monoftp3.png"&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;En la siguiente imagen la aplicación se conecta a un sitio público habilitando la casilla de autenticación anónima.&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/monoftp/monoftp6.png"&gt;&lt;/div&gt;&lt;br /&gt;&lt;h3&gt;&lt;a href="http://www.humansharp.com/Code/MonoFTP.zip"&gt;&lt;img src="http://www.humansharp.com/picture_library/dw.jpg" border="0"&gt;&amp;nbsp;Descarga el código fuente del proyecto para MonoDevelop&lt;/a&gt;&lt;/h3&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6494419861240446187-8389810703234211414?l=xomalli.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/8389810703234211414'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/8389810703234211414'/><link rel='alternate' type='text/html' href='http://xomalli.blogspot.com/2010/08/utilizando-la-clase-ftpwebrequest-para.html' title='Utilizando la clase FtpWebRequest para un cliente básico FTP con MonoDevelop'/><author><name>Martín Márquez</name><uri>http://www.blogger.com/profile/10939957618126542300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_j4WRR9G9bfY/SV2_nw3UxeI/AAAAAAAAAAM/nT3SYp94IHo/s1600-R/photo.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-6494419861240446187.post-2781744979021416617</id><published>2010-08-05T22:44:00.000-07:00</published><updated>2010-08-06T08:04:59.090-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><title type='text'>Utilizando la clase WindowsPrincipal con MonoDevelop</title><content type='html'>&lt;p align="justify"&gt;En este post &lt;a href="http://xomalli.blogspot.com/2010/07/conceptos-basicos-de-seguridad-en-net_25.html"&gt;Conceptos Básicos de seguridad en .NET (parte II) &lt;/a&gt; muestro un par de programas ejemplificando acerca de la utilización de la clase &lt;a href="http://msdn.microsoft.com/en-us/library/sh5x3s59%28v=VS.71%29.aspx"&gt;WindowsPrincipal&lt;/a&gt;. Esta clase representa la información de autenticación y de autorización de una entidad dentro del sistema.&lt;br /&gt;Estos ejemplos pueden compilarse y ejecutarse en Linux, en este caso lo hice en un sistema operativo &lt;a href="http://www.opensuse.org/en/"&gt; OpenSuse&lt;/a&gt; versión 11.1,  con el compilador 2.6.7 y el runtime de mono versión 2.6.7, como se muestra en la siguiente imagen:&lt;/p&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/principalmono/prop.png"&gt;&lt;/div&gt;&lt;br /&gt;&lt;p align="justify"&gt;El primero de los dos ejemplos lo compilamos y lo ejecutamos mostrando el resultado como en la siguiente imagen:&lt;/p&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/principalmono/simplePrinLin.png"&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;En la siguiente imagen mostramos el resultado si lo ejecutamos como el superusuario &lt;tt&gt;root&lt;/tt&gt;.&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/principalmono/simplePrin2.png"&gt;&lt;/div&gt;&lt;br /&gt;&lt;p align="justify"&gt;En el caso del segundo ejemplo modificamos el código y cambiamos la interfaz de consola por una interfaz gráfica utilizando el diseñador GTK# de &lt;a href=”http://www.monodevelop.com”&gt;MonoDevelop&lt;/a&gt;, siguiendo los siguientes pasos:&lt;/p&gt;&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;&lt;div&gt;Creamos una solución con un  proyecto GTK# 2.0 en Monodevelop como en la siguiente imagen:&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/principalmono/simplePrin3.png"&gt;&lt;/div&gt;&lt;/il&gt;&lt;br /&gt;&lt;li&gt;&lt;p&gt;Modificamos la apariencia del formulario, agregamos dos botones &lt;i&gt;btnEnter&lt;/i&gt;, &lt;i&gt;btnClose&lt;/i&gt; y un&lt;tt&gt; textview&lt;/tt&gt; nombrado &lt;i&gt; txtInfo&lt;/i&gt; para que el formulario se vea como en la siguiente imagen:&lt;/p&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/principalmono/simplePrin4.png"&gt;&lt;/div&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;p&gt;Agregamos el método para el evento &lt;i&gt;Clicked&lt;/i&gt; del botón &lt;tt&gt;btnEnter&lt;/tt&gt;utilizando la pestaña señales en la ventana de propiedades, seleccionamos el evento y hacemos doble click para que &lt;b&gt;MonoDevelop&lt;/b&gt; genere el código del método, como se muestra en las siguientes imagenes:&lt;/p&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/principalmono/simplePrin5.png"&gt;&lt;/div&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/principalmono/simplePrin6.png"&gt;&lt;/div&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;p&gt;Agregamos las siguientes líneas al inicio del código de la clase &lt;tt&gt;MainWindow.cs&lt;/tt&gt; ,  para utilizar los miembros de los ensamblados &lt;tt&gt;System.Security.Principal&lt;/tt&gt; y &lt;tt&gt;System.Threading&lt;/tt&gt; respectivamente.&lt;/p&gt;&lt;pre&gt;&lt;br /&gt;&lt;span class="using"&gt;using&lt;/span&gt; System.Security.Principal;&lt;br /&gt;&lt;span class="using"&gt;using&lt;/span&gt; System.Threading;&lt;br /&gt;&lt;/pre&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;p&gt;Dentro del método &lt;tt&gt;OnBtnEnterClicked&lt;/tt&gt; del código generado por MonoDevelop para el evento del botón &lt;i&gt;btnEnter&lt;/i&gt;, escribimos el siguiente código, el cual contiene toda la funcionalidad de nuestro programa:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;span class="reserved"&gt;protected virtual void&lt;/span&gt; OnBtnEnterClicked (object sender, System.EventArgs e)&lt;br /&gt;{&lt;br /&gt;System.Text.StringBuilder buf = new System.Text.StringBuilder();&lt;br /&gt;Gtk.TextBuffer textbuf = txtInfo.Buffer;&lt;br /&gt;textbuf.Clear();&lt;br /&gt;&lt;span class="reserved"&gt;try&lt;/span&gt;{&lt;br /&gt;AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal);&lt;br /&gt;WindowsPrincipal wp = (WindowsPrincipal)Thread.CurrentPrincipal;&lt;br /&gt;buf.AppendFormat("Login: {0}\n",wp.Identity.Name);&lt;br /&gt;buf.AppendFormat("Esta autentificado: {0}\n",wp.Identity.IsAuthenticated);&lt;br /&gt;buf.AppendFormat("Tipo de autentificación: {0}\n",wp.Identity.AuthenticationType);&lt;br /&gt;}&lt;span class="reserved"&gt;catch&lt;/span&gt;(FormatException fe)&lt;br /&gt;{&lt;br /&gt; buf.AppendFormat("Error al asignar el rid.\n");&lt;br /&gt; buf.AppendFormat("Mensaje: {0}",fe.Message);&lt;br /&gt;}&lt;br /&gt;&lt;span class="reserved"&gt;catch&lt;/span&gt;(System.Security.SecurityException se)&lt;br /&gt;{&lt;br /&gt; buf.AppendFormat("No tiene permisos para establecer el principal.\n");&lt;br /&gt; buf.AppendFormat("Mensaje: {0}\n",se.Message);&lt;br /&gt;}&lt;br /&gt;&lt;span class="reserved"&gt;catch&lt;/span&gt;(InvalidCastException ie){&lt;br /&gt; buf.AppendFormat("Error al obtener el principal.\n");&lt;br /&gt; buf.AppendFormat("Mensaje: {0}",ie.Message);&lt;br /&gt; }&lt;br /&gt;&lt;span class="reserved"&gt;finally&lt;/span&gt;{&lt;br /&gt;textbuf.Text = buf.ToString(); &lt;br /&gt;}&lt;br /&gt;} &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Nuestro programa entonces se vera como en la siguiente imagen:&lt;br /&gt;&lt;/p&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/principalmono/simplePrin7.png"&gt;&lt;/div&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;p&gt;Ahora creamos el código del evento &lt;tt&gt;Clicked&lt;/tt&gt; para el botón &lt;i&gt;btnClose&lt;/i&gt; de la misma forma que lo hicimos para el botón &lt;i&gt;btnEnter&lt;/i&gt;, cuya acción será terminar el programa, por lo que escribimos el siguiente código dentro del método generado.&lt;/p&gt;&lt;pre&gt;&lt;br /&gt;&lt;span class="reserved"&gt;protected virtual void&lt;/span&gt; OnBtnCloseClicked (object sender, System.EventArgs e)&lt;br /&gt;{&lt;br /&gt;Application.Quit();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;p&gt;Para compilar el programa hacemos click en el submenú &lt;i&gt;Construir todo&lt;/i&gt; debajo del la opción &lt;i&gt;Construir&lt;/i&gt; en el menú principal. En caso de ejecutar el programa hacemos click en cualquiera de las opciones &lt;i&gt;Ejecutar&lt;/i&gt; o &lt;i&gt;Depurar&lt;/i&gt; bajo el menú  &lt;i&gt;Ejecutar&lt;/i&gt; en el menú principal.&lt;/p&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/principalmono/simplePrin8.png"&gt;&lt;/div&gt;&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;p&gt;Si el programa se compila correctamente al ejecutarse mostrará el resultado como en la siguiente imagen:&lt;/p&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/principalmono/simplePrin9.png"&gt;&lt;/div&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;p&gt;Si ejecutamos el programa desde la terminal como superusuario nos mostrará el resultado como en la siguiente imagen:&lt;/p&gt;&lt;div&gt;&lt;img src="http://www.humansharp.com/picture_library/principalmono/simplePrin10.png"&gt;&lt;/div&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;div&gt;Vemos en el resultado de la ejecucción que el metódo de autenticación es &lt;tt&gt;POSIX&lt;/tt&gt;.&lt;/div&gt;&lt;br /&gt;&lt;h3&gt;&lt;a href="http://www.humansharp.com/Code/GtkPrincipalThread.zip"&gt;&lt;img src="http://www.humansharp.com/picture_library/dw.jpg" border="0"&gt;&amp;nbsp;Descarga el código fuente del proyecto para MonoDevelop&lt;/a&gt;&lt;/h3&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6494419861240446187-2781744979021416617?l=xomalli.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/2781744979021416617'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/2781744979021416617'/><link rel='alternate' type='text/html' href='http://xomalli.blogspot.com/2010/08/utilizando-la-clase-windowsprincipal.html' title='Utilizando la clase WindowsPrincipal con MonoDevelop'/><author><name>Martín Márquez</name><uri>http://www.blogger.com/profile/10939957618126542300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_j4WRR9G9bfY/SV2_nw3UxeI/AAAAAAAAAAM/nT3SYp94IHo/s1600-R/photo.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-6494419861240446187.post-5200143384096498010</id><published>2010-07-25T01:29:00.000-07:00</published><updated>2010-07-25T23:06:36.140-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Lenguajes .NET'/><title type='text'>Conceptos Básicos de seguridad en .NET (parte II)</title><content type='html'>&lt;b&gt;Autorización&lt;/b&gt;&lt;br /&gt;&lt;p align="justify"&gt; &lt;br /&gt;La autorización ocurre inmediatamente después de la autenticación y es como el sistema determina que recursos pueden utilizarse de acuerdo con la autenticación, regresando a la analogía del edificio la autorización ocurre después que nos identificamos (autenticación) ante el guardia y le decimos a que piso vamos, entonces nos da un gafete con el número de piso y que nos autoriza movernos únicamente en ese piso mientras nos encontremos dentro el edificio.&lt;br&gt;&lt;br /&gt;&lt;b&gt;La interfaz &lt;a href="http://msdn.microsoft.com/en-us/library/system.security.principal.iprincipal.aspx"&gt;IPrincipal&lt;/a&gt;&lt;/b&gt;&lt;br&gt;&lt;br /&gt;El modelo de seguridad basado en roles (roled-based security o RBS) permite controlar el acceso de los usuarios a los recursos en base a su identidad y su pertenencia a un grupo o membership, este modelo esta diseñado para ser independiente de la plataforma donde se implemente por lo que .NET utiliza el concepto de principal (representado por la interfaz &lt;a href="http://msdn.microsoft.com/en-us/library/system.security.principal.iprincipal.aspx"&gt;IPrincipal&lt;/a&gt;) como una forma de abstraer este modelo y encapsular la información acerca del contexto de seguridad (security context) de la entidad (usuario o objeto) que ejecuta el código.&lt;/p&gt;&lt;br /&gt;   &lt;p align="justify"&gt; &lt;br /&gt;Hay diferentes tipos de objetos &lt;tt&gt;Principal&lt;/tt&gt; cada uno para cada tipo de identidad y de membership, .NET proporciona los siguientes tipos de principales.&lt;br /&gt; &lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;br /&gt;&lt;a href=” http://msdn.microsoft.com/en-us/library/sh5x3s59%28v=VS.71%29.aspx”&gt;Windows Principal&lt;/a&gt;: Si utilizamos la seguridad Integrada de Windows este objeto representa la identidad, la autenticación y los roles de Windows. &lt;/li&gt;&lt;br /&gt; &lt;li&gt;&lt;br /&gt;&lt;a href=”http://msdn.microsoft.com/en-us/library/system.security.principal.genericprincipal%28v=VS.71%29.aspx”&gt;Generic Principal&lt;/a&gt;: Representa una seguridad a nivel aplicación, independiente de la seguridad de Windows, los roles y los usuarios utilizan un método personalizado de autenticación como por ejemplo una tabla en una base de datos.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;   &lt;p align="justify"&gt; &lt;br /&gt;Hay dos técnicas para crear objetos &lt;tt&gt;Principal&lt;/tt&gt; dependiendo de si una aplicación requiere hacer la validación algunas veces o durante toda su ejecución. Vamos a mostrar estas formas utilizando como ejemplo el objeto &lt;a href=” http://msdn.microsoft.com/en-us/library/sh5x3s59%28v=VS.71%29.aspx”&gt;WindowsPrincipal&lt;/a&gt;.&lt;/p&gt;&lt;br /&gt;  &lt;p align="justify"&gt; &lt;br /&gt;La primera técnica se recomienda si requerimos hacer la validación de cierto código algunas veces durante la ejecución, la sintaxis es: &lt;br /&gt; &lt;pre&gt;&lt;br /&gt;WindowsIdentity wi = WindowsIdentity.GetCurrent();&lt;br /&gt;WindowsPrincipal wp = new WindowsPrincipal(wi);&lt;br /&gt; &lt;/pre&gt;&lt;br /&gt;En esas lineas, primero obtenemos una instancia de &lt;a href="http://msdn.microsoft.com/en-us/library/system.security.principal.windowsidentity%28v=VS.71%29.aspx"&gt;WindowsIdentity&lt;/a&gt; al consultar la cuenta de Windows que ejecuta el código con el método &lt;tt&gt;GetCurrent&lt;/tt&gt;  y después la usamos como parámetro para construir un objeto &lt;a href="http://msdn.microsoft.com/en-us/library/sh5x3s59%28v=VS.71%29.aspx"&gt;WindowsPrincipal&lt;/a&gt;. &lt;/p&gt;&lt;br /&gt;  &lt;p align="justify"&gt;&lt;br /&gt;La segunda técnica se utiliza si requerimos hacer la validación durante toda la ejecución de la aplicación entonces en este caso debemos establecer la seguridad de Windows a nuestro hilo principal de ejecución ya que .NET de forma predeterminada no estable esa propiedad, entonces  la sintaxis es la siguiente:&lt;br /&gt; &lt;pre&gt;&lt;br /&gt;AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal);&lt;br /&gt;WindowsPrincipal wp = (WindowsPrincipal)Thread.CurrentPrincipal;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;En esas líneas primeramente establecemos la política de autorización al dominio de la aplicación con el valor de la enumeración &lt;a href=” http://msdn.microsoft.com/en-us/library/system.security.principal.principalpolicy.aspx”&gt;PrincipalPolicy&lt;/a&gt; , después obtenemos el &lt;tt&gt;Principal&lt;/tt&gt; del hilo de ejecución y hacemos un casting a un objeto &lt;a href="http://msdn.microsoft.com/en-us/library/sh5x3s59%28v=VS.71%29.aspx"&gt;WindowsPrincipal&lt;/a&gt;, si no establecemos la política no podremos hacer el casting de &lt;tt&gt;Thread.CurrentPrincipal&lt;/tt&gt; a &lt;a href="http://msdn.microsoft.com/en-us/library/sh5x3s59%28v=VS.71%29.aspx"&gt;WindowsPrincipal&lt;/a&gt; ya que como mencionamos anteriormente .NET no establece esta propiedad. &lt;/p&gt;&lt;br /&gt;&lt;p align="justify"&gt;&lt;br /&gt;Una vez teniendo el objeto &lt;a href="http://msdn.microsoft.com/en-us/library/sh5x3s59%28v=VS.71%29.aspx"&gt;WindowsPrincipal&lt;/a&gt; además de las propiedades y métodos de la clase &lt;a href="http://msdn.microsoft.com/en-us/library/system.security.principal.windowsidentity%28v=VS.71%29.aspx"&gt;WindowsIdentity&lt;/a&gt; podemos determinar su pertenencia a un grupo o rol, con el método &lt;tt&gt;IsInRole&lt;/tt&gt;.&lt;br /&gt;El método &lt;a href="http://msdn.microsoft.com/en-us/library/system.security.principal.windowsprincipal.isinrole%28VS.71%29.aspx"&gt;IsInRole&lt;/a&gt; de &lt;a href="http://msdn.microsoft.com/en-us/library/sh5x3s59%28v=VS.71%29.aspx"&gt;WindowsPrincipal&lt;/a&gt; tiene tres sobrecargas la primera recibe como argumento una cadena conteniendo el nombre del grupo o rol que debe escribirse para grupos basados en dominios de la siguiente forma:&lt;br /&gt; &lt;br /&gt;&lt;pre&gt;&lt;b&gt;[NombreDelDominio]\[Grupo]&lt;/b&gt;&lt;/pre&gt;&lt;br /&gt; &lt;br /&gt;O de la siguiente forma si es para grupos de la computadora local.&lt;br /&gt; &lt;br /&gt;&lt;pre&gt;&lt;b&gt;[NombreDeLaMaquina]\[Grupo]&lt;/b&gt;&lt;/pre&gt;&lt;br /&gt; &lt;br /&gt;La segunda sobrecarga recibe un RID (Role Identifier) y la tercera recibe una enumeración &lt;a href=”http://msdn.microsoft.com/en-us/library/system.security.principal.windowsbuiltinrole%28v=VS.71%29.aspx”&gt;WindowsBuiltInRole&lt;/a&gt;&lt;br /&gt;La tabla siguiente lista los identificadores del rol con su correspondiente valor en la enumeración &lt;a href=”http://msdn.microsoft.com/en-us/library/system.security.principal.windowsbuiltinrole%28v=VS.71%29.aspx”&gt;WindowsBuiltInRole&lt;/a&gt;&lt;/p&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;+----------------+------+&lt;br /&gt;|AccountOperator |0x224 |&lt;br /&gt;|Administrator   |0x220 |&lt;br /&gt;|BackupOperator  |0x227 |&lt;br /&gt;|Guest           |0x222 |&lt;br /&gt;|PowerUser       |0x223 |&lt;br /&gt;|PrintOperator   |0x226 |&lt;br /&gt;|Replicator      |0x228 |&lt;br /&gt;|SystemOperator  |0x225 |&lt;br /&gt;|User            |0x221 |&lt;br /&gt;+----------------+------+&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div&gt;El siguiente programa demuestra el uso de la primera técnica de validación para conocer la autorización de una entidad.&lt;/div&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;span class="using"&gt;using&lt;/span&gt; System;&lt;br /&gt;&lt;span class="using"&gt;using&lt;/span&gt; System.Security.Principal;&lt;br /&gt;&lt;br /&gt;&lt;span class="using"&gt;namespace&lt;/span&gt; Samples{&lt;br /&gt;&lt;span class="reserved"&gt;public class&lt;/span&gt; SimplePrincipal{&lt;br /&gt;&lt;span class="reserved"&gt;public&lt;/span&gt;&lt;span class="void"&gt; static&lt;/span&gt; &lt;span class="reserved"&gt;int&lt;/span&gt; Main(&lt;span class="void"&gt;string&lt;/span&gt;[] args){&lt;br /&gt;&lt;span class="void"&gt;string&lt;/span&gt;[] roles = {&lt;br /&gt;@"BUILTIN\Account Operators",&lt;br /&gt;@"BUILTIN\Administrators",&lt;br /&gt;@"BUILTIN\Backup Operators",&lt;br /&gt;@"BUILTIN\Guests",&lt;br /&gt;@"BUILTIN\Power Users",&lt;br /&gt;@"BUILTIN\Print Operators",&lt;br /&gt;@"BUILTIN\Replicators",&lt;br /&gt;@"BUILTIN\Server Operators",&lt;br /&gt;@"BUILTIN\Users"&lt;br /&gt;};&lt;br /&gt;WindowsIdentity wi = WindowsIdentity.GetCurrent();&lt;br /&gt;WindowsPrincipal wp = new WindowsPrincipal(wi);&lt;br /&gt;Console.WriteLine("\n Información  ");&lt;br /&gt;Console.WriteLine("=====================\n");&lt;br /&gt;Console.WriteLine(" Login: {0}",wp.Identity.Name);&lt;br /&gt;Console.WriteLine(" Esta autentificado: {0}",wp.Identity.IsAuthenticated);&lt;br /&gt;Console.WriteLine(" Tipo de autentificación: {0}",wp.Identity.AuthenticationType); &lt;br /&gt;&lt;span class="reserved"&gt;for&lt;/span&gt;(&lt;span class="reserved"&gt;int&lt;/span&gt; i = 0;i &lt; roles.Length;i++){&lt;br /&gt; &lt;span class="reserved"&gt;if&lt;/span&gt;(wp.IsInRole(roles[i]))&lt;br /&gt; Console.WriteLine(" Es miembro de {0}",roles[i]); &lt;br /&gt;}&lt;br /&gt;Console.Write("\nPresione una tecla para continuar...");&lt;br /&gt;Console.Read();&lt;br /&gt;&lt;span class="reserved"&gt;return&lt;/span&gt; 0;&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p align="justify"&gt;&lt;br /&gt;&lt;div&gt;Al compilar y ejecutar el programa con una cuenta de administrador mostrará el siguiente resultado:&lt;/div&gt;&lt;br /&gt;&lt;img src="http://www.humansharp.com/picture_library/principal/sprincipal.png"&gt;&lt;br /&gt;Ahora bien, si ejecutamos el programa con el comando &lt;br /&gt;&lt;pre&gt;&lt;b&gt;runas /user:[Usuario] [Programa]&lt;/b&gt;&lt;/pre&gt; &lt;br /&gt;&lt;div&gt;en este caso con la cuenta del usuario postgres,como se muestra en la imagen:&lt;/div&gt;&lt;br /&gt;&lt;img src="http://www.humansharp.com/picture_library/principal/runas.png"&gt;&lt;br /&gt;&lt;div&gt;El programa mostrará el siguiente resultado:&lt;/div&gt;&lt;br /&gt;&lt;img src="http://www.humansharp.com/picture_library/principal/sprincipal2.png"&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p align="Justify"&gt;Y ahora demostramos la segunda técnica utilizando la política del dominio de la aplicación, algo más elaborado que el ejemplo anterior, lo ejemplificamos con el código de clase &lt;tt&gt;Roles.cs&lt;/tt&gt; y la clase &lt;tt&gt;SimplePrincipalThread.cs&lt;/tt&gt; que listamos a continuación.&lt;br /&gt;&lt;div&gt;El listado &lt;tt&gt;Roles.cs&lt;/tt&gt;&lt;/div&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;span class="using"&gt;using&lt;/span&gt; System;&lt;br /&gt;&lt;span class="using"&gt;namespace&lt;/span&gt; Samples{&lt;br /&gt;&lt;span class="reserved"&gt;public class&lt;/span&gt; Roles{&lt;br /&gt;//roles de Windows&lt;br /&gt;&lt;span class="void"&gt;string&lt;/span&gt;[,] roles = {&lt;br /&gt; {"0x224",@"BUILTIN\Account Operators"},&lt;br /&gt; {"0x220",@"BUILTIN\Administrators"},&lt;br /&gt; {"0x227",@"BUILTIN\Backup Operators"},&lt;br /&gt; {"0x222",@"BUILTIN\Guests"},&lt;br /&gt; {"0x223",@"BUILTIN\Power Users"},&lt;br /&gt; {"0x226",@"BUILTIN\Print Operators"},&lt;br /&gt; {"0x228",@"BUILTIN\Replicators"},&lt;br /&gt; {"0x225",@"BUILTIN\Server Operators"},&lt;br /&gt; {"0x221",@"BUILTIN\Users"}&lt;br /&gt;};&lt;br /&gt;&lt;span class="reserved"&gt;public&lt;/span&gt; &lt;span class="void"&gt;string&lt;/span&gt; &lt;span class="reserved"&gt;this&lt;/span&gt;[&lt;span class="void"&gt;string&lt;/span&gt; rid]{&lt;br /&gt;get{&lt;br /&gt; &lt;span class="reserved"&gt;for&lt;/span&gt;(&lt;span class="reserved"&gt;int&lt;/span&gt; i = 0;i &lt; (roles.Length/2);i++)&lt;br /&gt; {&lt;br /&gt; &lt;span class="reserved"&gt;if&lt;/span&gt;(roles[i,0].Equals(rid))&lt;br /&gt; &lt;span class="reserved"&gt;return&lt;/span&gt;  roles[i,1];&lt;br /&gt; }&lt;br /&gt; &lt;span class="reserved"&gt;return&lt;/span&gt; "Sin rol";&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div&gt;El listado &lt;tt&gt;SimplePrincipalThread.cs&lt;/tt&gt;&lt;/div&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;span class="using"&gt;using&lt;/span&gt; System;&lt;br /&gt;&lt;span class="using"&gt;using&lt;/span&gt; System.Security.Principal;&lt;br /&gt;&lt;span class="using"&gt;using&lt;/span&gt; System.Security;&lt;br /&gt;&lt;span class="using"&gt;using&lt;/span&gt; System.Threading;&lt;br /&gt;&lt;br /&gt;&lt;span class="using"&gt;namespace&lt;/span&gt; Samples{&lt;br /&gt;&lt;span class="reserved"&gt;public class&lt;/span&gt; SimplePrincipalThread{&lt;br /&gt;&lt;span class="reserved"&gt;public&lt;/span&gt; &lt;span class="void"&gt; static&lt;/span&gt;&lt;span class="reserved"&gt; int&lt;/span&gt; Main(&lt;span class="void"&gt;string&lt;/span&gt;[] args)&lt;br /&gt;{&lt;br /&gt;Console.WriteLine("\n");&lt;br /&gt;Console.WriteLine("===================");&lt;br /&gt;&lt;span class="reserved"&gt;if&lt;/span&gt;(args.Length &gt; 0 &amp;&amp; args.Length &lt; 3){&lt;br /&gt;&lt;span class="reserved"&gt;try&lt;/span&gt;{&lt;br /&gt;&lt;span class="reserved"&gt;if&lt;/span&gt;(args[0].ToLower().Equals("true"))&lt;br /&gt;AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal);&lt;br /&gt;WindowsPrincipal wp = (WindowsPrincipal)Thread.CurrentPrincipal;&lt;br /&gt;Console.WriteLine("Login: {0}",wp.Identity.Name);&lt;br /&gt;Console.WriteLine("Esta autentificado: {0}",wp.Identity.IsAuthenticated);&lt;br /&gt;Console.WriteLine("Tipo de autentificación: {0}",wp.Identity.AuthenticationType); &lt;br /&gt;Roles roles = new Roles();&lt;br /&gt;&lt;span class="void"&gt;string&lt;/span&gt; rid = args[1];&lt;br /&gt;&lt;span class="reserved"&gt;if&lt;/span&gt;(wp.IsInRole(rid))&lt;br /&gt;Console.WriteLine("Es miembro de {0}",roles[rid]);&lt;br /&gt;&lt;span class="reserved"&gt;else&lt;/span&gt;&lt;br /&gt;Console.WriteLine("No es miembro de {0}",roles[rid]);&lt;br /&gt;}&lt;br /&gt;&lt;span class="reserved"&gt;catch&lt;/span&gt;(FormatException fe)&lt;br /&gt;{&lt;br /&gt;Console.WriteLine("Error al asignar el rid.");&lt;br /&gt;Console.WriteLine("Mensaje: {0}",fe.Message);&lt;br /&gt;}&lt;br /&gt;&lt;span class="reserved"&gt;catch&lt;/span&gt;(SecurityException se)&lt;br /&gt;{&lt;br /&gt;Console.WriteLine("No tiene permisos para establecer el principal.");&lt;br /&gt;Console.WriteLine("Mensaje: {0}",se.Message);&lt;br /&gt;}&lt;br /&gt;&lt;span class="reserved"&gt;catch&lt;/span&gt;(InvalidCastException ie){&lt;br /&gt;Console.WriteLine("Error al obtener el principal.");&lt;br /&gt;Console.WriteLine("Mensaje: {0}",ie.Message);&lt;br /&gt;}&lt;br /&gt;}&lt;span class="reserved"&gt;else&lt;/span&gt;&lt;br /&gt;Usage();&lt;br /&gt;&lt;span class="reserved"&gt;return&lt;/span&gt; 0;&lt;br /&gt;} //fin de main&lt;br /&gt;&lt;br /&gt;&lt;span class="void"&gt; static void&lt;/span&gt; Usage(){&lt;br /&gt;Console.WriteLine("Usar:");&lt;br /&gt;Console.WriteLine("SimplePrincipalThread [true|false] [rid(hex)]");&lt;br /&gt;Console.WriteLine("ejemplo: SimplePrincipalThread true 0x222");&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;div&gt;Al compilar las clases y ejecutar el programa con la opción &lt;tt&gt;false&lt;/tt&gt; nos mostrará la excepción de que no hemos establecido una política de autorización.&lt;/div&gt;&lt;br /&gt;&lt;img src="http://www.humansharp.com/picture_library/principal/sprincipalt1.png"&gt;&lt;br /&gt;&lt;div&gt;Si ejecutamos el programa sin argumentos nos mostrará las instrucciones de uso.&lt;/div&gt;&lt;br /&gt;&lt;img src="http://www.humansharp.com/picture_library/principal/sprincipalt2.png"&gt;&lt;br /&gt;&lt;div&gt;Si ejecutamos el programa correctamente,nos mostrará la información como en la siguiente imagen&lt;/div&gt;&lt;br /&gt;&lt;img src="http://www.humansharp.com/picture_library/principal/sprincipalt3.png"&gt;&lt;br /&gt;&lt;h3&gt;&lt;a href="http://www.humansharp.com/Code/Principal.zip"&gt;&lt;img src="http://www.humansharp.com/picture_library/dw.jpg" border="0"&gt;&amp;nbsp;Descarga el código fuente&lt;/a&gt;&lt;/h3&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6494419861240446187-5200143384096498010?l=xomalli.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/5200143384096498010'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/5200143384096498010'/><link rel='alternate' type='text/html' href='http://xomalli.blogspot.com/2010/07/conceptos-basicos-de-seguridad-en-net_25.html' title='Conceptos Básicos de seguridad en .NET (parte II)'/><author><name>Martín Márquez</name><uri>http://www.blogger.com/profile/10939957618126542300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_j4WRR9G9bfY/SV2_nw3UxeI/AAAAAAAAAAM/nT3SYp94IHo/s1600-R/photo.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-6494419861240446187.post-2733160233540609655</id><published>2010-07-19T21:52:00.000-07:00</published><updated>2010-09-30T22:15:53.897-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Lenguajes .NET'/><title type='text'>Libros de programación en C# para descargar</title><content type='html'>&lt;p align="justify"&gt;Buscando bibliografía en Internet de C#, encontre esta página con enlaces para descargar libros electrónicos de programación en C#.&lt;br /&gt;&lt;br&gt;&lt;br /&gt;&lt;a href="http://www.computer-books.us/csharp.php"&gt;http://www.computer-books.us/csharp.php&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6494419861240446187-2733160233540609655?l=xomalli.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/2733160233540609655'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/2733160233540609655'/><link rel='alternate' type='text/html' href='http://xomalli.blogspot.com/2010/07/libros-de-programacion-en-c-para.html' title='Libros de programación en C# para descargar'/><author><name>Martín Márquez</name><uri>http://www.blogger.com/profile/10939957618126542300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_j4WRR9G9bfY/SV2_nw3UxeI/AAAAAAAAAAM/nT3SYp94IHo/s1600-R/photo.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-6494419861240446187.post-8683308445414856722</id><published>2010-07-14T12:45:00.001-07:00</published><updated>2010-07-14T22:17:17.339-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Lenguajes .NET'/><title type='text'>Conceptos Básicos de seguridad en .NET (parte I)</title><content type='html'>&lt;p align="justify"&gt;La seguridad es un tema  que debe estar presente desde el comienzo del diseño de todo sistema de información, más aún si este sistema será utilizado por usuarios desde Internet.&lt;br /&gt;Dos conceptos básicos para entender la seguridad de los sistemas es la autenticación y la autorización.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;b&gt;Autenticación&lt;/b&gt;&lt;br /&gt;&lt;p align="justify"&gt;La autenticación es el proceso mediante el cual el sistema identifica y válida que el usuario pruebe quién dice ser, es similar a cuando hacemos una visita a un edificio y un guardia de seguridad en la entrada nos solicita una credencial para que nos identifiquemos, el mecanismo de credenciales más usadas en los sistemas de información es el login y el password.&lt;br /&gt;Entonces en definición la autenticación es el mecanismo que se refiere a probar y validar quiénes somos dentro del sistema, esta identidad consiste generalmente del login de usuario y del rol asociado con ese login, NET proporciona los siguientes mecanismos de autenticación:&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p align="justify"&gt;&lt;br /&gt;&lt;b&gt;Windows Authentication&lt;/b&gt; Utiliza la seguridad del sistema operativo windows y compara las credenciales (login y password) con las credenciales de Windows una vez identificado, windows utiliza un número de 96 bits llamado SID (security identifier) para identificarlo.&lt;/p&gt;&lt;br /&gt;&lt;p align="justify"&gt;&lt;br /&gt;&lt;b&gt;Passport Authentication&lt;/b&gt; En este tipo los usuarios utilizan sus cuentas de Hotmail o de Windows Messenger para autenticarse y por ende su servicio de registro en caso de no tener una cuenta passport, para utilizar esta autenticación es necesario descargar e instalar Passport SDK desde Microsoft Passport Network.&lt;/p&gt;&lt;br /&gt;&lt;p align="justify"&gt;&lt;b&gt;Forms Authentication (ASP.NET)&lt;/b&gt; Aquí se realiza mediante un formulario solicitando el login y el password al usuario, cuando  ASP.NET válida las credenciales como correctas crea una cookie encriptada que se adjunta a cada respuesta de petición, por eso se dice que esta autenticación es basada en token (token-based), si el runtime de ASP .NET no encuentra la cookie entonces redirige al usuario a la pantalla del login, este tipo de autenticación es la más personalizable y portable que las anteriores.&lt;/p&gt;&lt;br /&gt;&lt;p align="justify"&gt;&lt;br /&gt;Estos mecanismos se utilizan en conjunto con la seguridad basada en roles de .NET (role-based security)  que se fundamenta en dos conceptos importantes: identidades y principales.&lt;br /&gt;La identidad de un usuario está representada en .NET por los siguientes tipos de identidades que se encuentran representadas en el Framework por clases que implementan la interfaz &lt;a href="http://msdn.microsoft.com/en-us/library/system.security.principal.iidentity.aspx"&gt;IIdentity&lt;/a&gt;.&lt;/p&gt;&lt;br /&gt;&lt;p align="justify"&gt;&lt;br /&gt;&lt;b&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/e599ywa6.aspx"&gt;Windows identity&lt;/a&gt;&lt;/b&gt; Se basa en los métodos de autenticación soportados por el sistema operativo Windows, esta identidad tiene la propiedad de hacerse pasar por otro usuario con la característica de impersonation(suplantación) además de ser una forma muy segura de autenticar usuarios.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p align="justify"&gt;&lt;br /&gt;&lt;b&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.security.principal.genericidentity.aspx"&gt;Generic identity&lt;/a&gt;&lt;/b&gt;  Se basa en un método personalizado de autenticación que se define a nivel aplicación, al ser un método personalizado por lo tanto no depende de las características del sistema de seguridad de Windows.&lt;/p&gt;&lt;br /&gt;&lt;p align="justify"&gt;&lt;br /&gt;&lt;b&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.web.security.passportidentity.aspx"&gt;Passport identity&lt;/a&gt;&lt;/b&gt;  Utiliza la autenticación del modulo de Passport de Microsoft donde los usuarios utilizan las credenciales de Hotmail o Windows Live para acceder a cualquier sistema que implemente el servicio Passport (single sign-inservice).&lt;/p&gt;&lt;br /&gt;&lt;p align="justify"&gt;&lt;br /&gt;Si bien se recomienda utilizar los mecanismos proporcionados por el framework, .NET permite también crear mecanismos personalizados de autenticación implementando la interfaz &lt;a href="http://msdn.microsoft.com/en-us/library/system.security.principal.iidentity.aspx"&gt;IIdentity&lt;/a&gt;.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;Código de ejemplo con la clase &lt;a href="http://msdn.microsoft.com/en-us/library/e599ywa6.aspx"&gt;WindowsIdentity&lt;/a&gt;:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;span class="using"&gt;using&lt;/span&gt; System;&lt;br /&gt;&lt;span class="using"&gt;using&lt;/span&gt; System.Security.Principal;&lt;br /&gt;&lt;br /&gt;&lt;span class="using"&gt;namespace&lt;/span&gt; Samples{&lt;br /&gt; &lt;span class="reserved"&gt;public class&lt;/span&gt; WindowsIdentitySample{&lt;br /&gt; &lt;span class="reserved"&gt;public&lt;/span&gt; &lt;span class="static"&gt;static&lt;/span&gt; int Main(string[] args){&lt;br /&gt; Console.WriteLine("\n| Información de la identidad ");&lt;br /&gt; Console.WriteLine("+-----------------------------------------------");&lt;br /&gt; WindowsIdentity wi = WindowsIdentity.GetCurrent();&lt;br /&gt; Console.WriteLine("Login: {0}",wi.Name);&lt;br /&gt; Console.WriteLine("Esta autentificado: {0}",wi.IsAuthenticated);&lt;br /&gt; Console.WriteLine("Tipo de autentificación: {0}",wi.AuthenticationType);&lt;br /&gt; Console.WriteLine("Es anónimo/invitado/sistema: {0}",&lt;br /&gt;   (wi.IsAnonymous ? "Anónimo" : &lt;br /&gt;    (wi.IsGuest ? "Invitado" : &lt;br /&gt;     (wi.IsSystem ? "Sistema" : "Ninguna"))));&lt;br /&gt; &lt;span class="reserved"&gt;return&lt;/span&gt; 0;&lt;br /&gt; }&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Al ejecutarse el programa mostrará la siguiente salida en Microsoft Windows:&lt;br /&gt;&lt;img src="http://www.humansharp.com/picture_library/identity/wiwin.png"&gt;&lt;br /&gt;Y la siguiente salida al ejecutarse en Linux utilizando &lt;a href="http://www.mono-project.com/Main_Page"&gt;Mono&lt;/a&gt;&lt;br /&gt;&lt;img src="http://www.humansharp.com/picture_library/identity/wimono.png"&gt;&lt;br /&gt;&lt;br /&gt;A continuación el código de ejemplo utilizando la clase &lt;a href="http://msdn.microsoft.com/en-us/library/system.security.principal.genericidentity.aspx"&gt;GenericIdentity&lt;/a&gt;:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;span class="using"&gt;using&lt;/span&gt; System;&lt;br /&gt;&lt;span class="using"&gt;using&lt;/span&gt; System.Security.Principal;&lt;br /&gt;&lt;br /&gt;&lt;span class="using"&gt;namespace&lt;/span&gt; Samples{&lt;br /&gt; &lt;span class="reserved"&gt;public class&lt;/span&gt; GenericIdentitySample{&lt;br /&gt;  &lt;span class="reserved"&gt;public&lt;/span&gt; static int Main(string[] args){&lt;br /&gt;   Console.WriteLine("\n| Información de la identidad");&lt;br /&gt;   Console.WriteLine("+-----------------------------------");&lt;br /&gt;   //lo construimos con los parámetros del nombre y del metódo de autenticación&lt;br /&gt;   GenericIdentity gi = new GenericIdentity("SuperUsuario","Autenticado personalizado");&lt;br /&gt;   Console.WriteLine("Nombre: {0}",gi.Name);&lt;br /&gt;   Console.WriteLine("Tipo de autenticación: {0}",gi.AuthenticationType);&lt;br /&gt;   Console.WriteLine("Esta autenticado: {0}",gi.IsAuthenticated);&lt;br /&gt;   &lt;span class="reserved"&gt;return&lt;/span&gt; 0;&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Al ejecutarse el programa mostrará la siguiente salida en Microsoft Windows:&lt;br /&gt;&lt;img src="http://www.humansharp.com/picture_library/identity/giwin.png"&gt;&lt;br /&gt;Y la siguiente salida al ejecutarse en Linux utilizando &lt;a href="http://www.mono-project.com/Main_Page"&gt;Mono&lt;/a&gt;&lt;br /&gt;&lt;img src="http://www.humansharp.com/picture_library/identity/gi.png"&gt;&lt;br /&gt;&lt;h3&gt;&lt;a href="http://www.humansharp.com/Code/Identities.zip"&gt;&lt;img src="http://www.humansharp.com/picture_library/dw.jpg" border="0"&gt;&amp;nbsp;Descarga el código fuente&lt;/a&gt;&lt;/h3&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6494419861240446187-8683308445414856722?l=xomalli.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/8683308445414856722'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/8683308445414856722'/><link rel='alternate' type='text/html' href='http://xomalli.blogspot.com/2010/07/conceptos-basicos-de-seguridad-en-net.html' title='Conceptos Básicos de seguridad en .NET (parte I)'/><author><name>Martín Márquez</name><uri>http://www.blogger.com/profile/10939957618126542300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_j4WRR9G9bfY/SV2_nw3UxeI/AAAAAAAAAAM/nT3SYp94IHo/s1600-R/photo.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-6494419861240446187.post-4715119857922483736</id><published>2010-05-30T09:30:00.000-07:00</published><updated>2010-05-30T10:19:06.795-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><title type='text'>Trabajando LINQ para XML con Monodevelop Parte II de II</title><content type='html'>&lt;p&gt;Esta es la segunda parte del post anterior &lt;a href="http://xomalli.blogspot.com/2010/05/trabajando-linq-para-xml-con.html"&gt;Trabajando LINQ para XML con Monodevelop&lt;/a&gt;, aunque este tutorial supone que los dos proyectos están dentro la misma solución, los dos proyectos son independientes uno del otro, por lo que pueden crearse en diferentes soluciones.&lt;/p&gt;&lt;br /&gt;&lt;b&gt;Consultando XML con LINQ&lt;/b&gt;&lt;br /&gt;&lt;p&gt;Ahora agregamos un segundo proyecto a nuestra solución, este proyecto será una aplicación GTK# que llamaremos “SegundoLinqXML” como se muestra en la siguiente imagen y que nos mostrará como consultar el archivo XML con LINQ creado con la aplicación de consola anterior.&lt;/p&gt;&lt;br /&gt;&lt;img src="http://www.humansharp.com/picture_library/linqxml/linqxml5.png"&gt;&lt;br /&gt;&lt;span&gt;Utilizando el diseñador agregamos y acomodamos los siguientes controles GTK# con sus respectivos identificadores al formulario.&lt;/span&gt;&lt;br /&gt;&lt;div&gt;&lt;b&gt;Tipo de control:&lt;/b&gt;Gtk.Entry&lt;b&gt; Nombre&lt;/b&gt;txtQuery&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;b&gt;Tipo de control:&lt;/b&gt;Gtk.Button&lt;b&gt; Nombre&lt;/b&gt;BtnBuscar&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;b&gt;Tipo de control:&lt;/b&gt;Gtk.RadioButton&lt;b&gt; Nombres&lt;/b&gt;RbCodigo,rbIdArticulo,rbNombre&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;b&gt;Tipo de control:&lt;/b&gt;Gtk.TreeView&lt;b&gt; Nombres&lt;/b&gt;Resultados&lt;/div&gt;&lt;br /&gt;&lt;span&gt;Colocando los controles el formulario deberá verse como en la siguiente imagen&lt;/span&gt;&lt;br /&gt;&lt;img src="http://www.humansharp.com/picture_library/linqxml/linqxml6.png"&gt;&lt;br /&gt;&lt;p align="justify"&gt;El código completo es el siguiente listado&lt;/p&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;span class="using"&gt;using&lt;/span&gt; System;&lt;br /&gt;&lt;span class="using"&gt;using&lt;/span&gt; Gtk;&lt;br /&gt;&lt;span class="using"&gt;using&lt;/span&gt; System.Xml.Linq;&lt;br /&gt;&lt;span class="using"&gt;using&lt;/span&gt; System.Collections.Generic;&lt;br /&gt;&lt;span class="using"&gt;using&lt;/span&gt; System.Linq;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="reserved"&gt;public partial class&lt;/span&gt; MainWindow : Gtk.Window&lt;br /&gt;{&lt;br /&gt;&lt;span class="reserved"&gt;public&lt;/span&gt; MainWindow () : base(Gtk.WindowType.Toplevel)&lt;br /&gt;{&lt;br /&gt;Build ();&lt;br /&gt;AddColumns(Resultados);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="reserved"&gt;protected&lt;/span&gt; &lt;span class="void"&gt;void&lt;/span&gt; OnDeleteEvent (object sender, DeleteEventArgs a)&lt;br /&gt;{&lt;br /&gt;Application.Quit ();&lt;br /&gt;a.RetVal = true;&lt;br /&gt;}&lt;br /&gt;&lt;span class="reserved"&gt;protected virtual&lt;/span&gt; &lt;span class="void"&gt;void&lt;/span&gt; OnBtnBuscarClicked (object sender, System.EventArgs e)&lt;br /&gt;{&lt;br /&gt;ListStore store = new ListStore(typeof(string));&lt;br /&gt;&lt;span class="reserved"&gt;if&lt;/span&gt;(System.IO.File.Exists("articulos.xml")){&lt;br /&gt;&lt;span class="void"&gt;string&lt;/span&gt; col = "Codigo";&lt;br /&gt;&lt;span class="reserved"&gt;if&lt;/span&gt;(rbNombre.Active)col = "Nombre";&lt;br /&gt;&lt;span class="reserved"&gt;if&lt;/span&gt;(rbIdArticulo.Active)col = "IdArticulo";&lt;br /&gt;Resultados.EnableGridLines = TreeViewGridLines.Horizontal;&lt;br /&gt;XElement xml = XElement.Load("articulos.xml");&lt;br /&gt;&lt;span class="reserved"&gt;var&lt;/span&gt; q = from s in xml.Elements("Table").Elements(col)&lt;br /&gt;&lt;span class="reserved"&gt;where&lt;/span&gt;  s.Value.Contains(txtQuery.Text)&lt;br /&gt;&lt;span class="reserved"&gt;select&lt;/span&gt; s;&lt;br /&gt;foreach(string r in q){&lt;br /&gt;store.AppendValues(r);&lt;br /&gt;}&lt;br /&gt;Resultados.Model = store;&lt;br /&gt;}&lt;span class="reserved"&gt;else&lt;/span&gt;&lt;br /&gt;&lt;span class="using"&gt;using&lt;/span&gt;(Dialog dia = new MessageDialog(this,DialogFlags.Modal,&lt;br /&gt;MessageType.Error,&lt;br /&gt;ButtonsType.Ok,"No existe el archivo XML",null)){&lt;br /&gt;dia.Run();&lt;br /&gt;dia.Destroy();&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;//se crean las columnas del Grid&lt;br /&gt;&lt;span class="void"&gt;void&lt;/span&gt; AddColumns (TreeView treeView) {&lt;br /&gt;CellRendererText rendererText = new CellRendererText ();&lt;br /&gt;&lt;span class="void"&gt;string&lt;/span&gt;[] s = {"Resultado"};&lt;br /&gt;TreeViewColumn column;&lt;br /&gt;&lt;span class="reserved"&gt;for&lt;/span&gt;(int i = 0;i &lt; s.Length;i++){&lt;br /&gt;column =  new TreeViewColumn (s[i], rendererText, "text", i);&lt;br /&gt;treeView.AppendColumn (column);  }&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p align="justify"&gt;El siguiente fragmento de código muestra como realizar la consulta del archivo XML donde la variable &lt;tt&gt;col&lt;/tt&gt; adquiere el valor de cualquier elemento dentro del elemento &lt;tt&gt;table&lt;/tt&gt; y donde el valor contenga el texto escrito dentro de &lt;tt&gt;txtQuery&lt;/tt&gt;, es aquí donde en esencia se utilizan las expresiones de consulta de LINQ una vez que se carga el documento XML en memoria.&lt;/p&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;XElement xml = XElement.Load("articulos.xml");&lt;br /&gt;&lt;span class="reserved"&gt;var&lt;/span&gt; q = from s in xml.Elements("Table").Elements(col)&lt;br /&gt;&lt;span class="reserved"&gt;where&lt;/span&gt; s.Value.Contains(txtQuery.Text)&lt;br /&gt;select s;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p align="justify"&gt;&lt;br /&gt;Construimos la aplicación pulsando el botón F8, seleccionamos el archivo de proyecto y haciendo &lt;tt&gt;click&lt;/tt&gt; con e botón secundario del ratón seleccionamos la aplicación para que se inicie al ejecutar  la solución, al ejecutarla teclear un valor y pulsar el botón consultar observaremos cualquiera de los siguientes resultados dependiendo del control radio seleccionado.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;img src="http://www.humansharp.com/picture_library/linqxml/linqxml7.png"&gt;&lt;br /&gt;&lt;img src="http://www.humansharp.com/picture_library/linqxml/linqxml8.png"&gt;&lt;br /&gt;&lt;h3&gt;&lt;a href="http://www.humansharp.com/Code/PrimerLinqXML.zip"&gt;&lt;img src="http://www.humansharp.com/picture_library/dw.jpg" border="0"&gt;&amp;nbsp;Descarga el código fuente&lt;/a&gt;&lt;/h3&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6494419861240446187-4715119857922483736?l=xomalli.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/4715119857922483736'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/4715119857922483736'/><link rel='alternate' type='text/html' href='http://xomalli.blogspot.com/2010/05/trabajando-linq-para-xml-con_30.html' title='Trabajando LINQ para XML con Monodevelop Parte II de II'/><author><name>Martín Márquez</name><uri>http://www.blogger.com/profile/10939957618126542300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_j4WRR9G9bfY/SV2_nw3UxeI/AAAAAAAAAAM/nT3SYp94IHo/s1600-R/photo.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-6494419861240446187.post-2192253697786049020</id><published>2010-05-26T22:02:00.000-07:00</published><updated>2010-05-27T07:14:52.425-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><title type='text'>Trabajando LINQ para XML con Monodevelop Parte I de II</title><content type='html'>&lt;p align="Justify"&gt;XML se ha convertido en un excelente estándar abierto para el intercambio de información entre aplicaciones de software debido a la manera de representar información estructurada, independiente de la plataforma, lenguaje de programación o sistema operativo, es utilizado extensamente en archivos y protocolos de Internet por ser un formato fácil de leer y suficientemente flexible para adaptarse a muchos propósitos. Debido a estas características XML y sus tecnologías están completamente integradas y soportadas por la plataforma .NET mediante un conjunto de clases que proporcionan lectura y escritura de documentos, validación, navegación, serialización, transformación y búsquedas. Aunque estas clases son suficientes para trabajar con XML su utilización no es sencilla y puede producir código difícil de mantener, por lo que .NET incorpora LINQ para XML (LINQ to XML) como una mejor manera de trabajar con XML.&lt;/p&gt;&lt;br /&gt;&lt;b&gt;Creando el archivo XML&lt;/b&gt;&lt;br /&gt;&lt;p align="Justify"&gt;Para mostrar de una manera práctica la utilización de LINQ para XML, ejecutamos MonoDevelop y creamos una nueva solución en el menú “Archivo”, del lado derecho de la ventana de nueva solución seleccionamos el icono que dice “Solución en  blanco”  y en el cuadro de texto nombre escogemos “LinqXML”, esta será la solución que contenga los dos proyectos de este tutorial.&lt;/p&gt;&lt;br /&gt;&lt;img src="http://www.humansharp.com/picture_library/linqxml/linqxml1.png"&gt;&lt;br /&gt;&lt;div&gt;Agregamos a nuestra solución un proyecto de consola, le llamamos CrearXML , como se muestra en la siguiente imagen.&lt;/div&gt;&lt;br /&gt;&lt;img src="http://www.humansharp.com/picture_library/linqxml/linqxml2.png"&gt;&lt;br /&gt;&lt;div&gt;Para que el soporte de LINQ a XML es importante hacer referencia a los siguientes ensamblados:&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;b&gt;System.Linq&lt;/b&gt; Es el ensamblado principal y básico que contiene todas las clases e interfaces para trabajar con LINQ.&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;b&gt;System.Xml.Linq&lt;/b&gt;Contiene las clases y extensiones para manipular   XML con LINQ.&lt;/div&gt;&lt;br /&gt;&lt;p align="justify"&gt;Esto se logra haciendo click derecho sobre el archivo de proyecto y en el menú desplegable escogemos la opción “Editar referencias” (Edit References) como se muestra en la imagen siguiente.&lt;/p&gt;&lt;br /&gt;&lt;img src="http://www.humansharp.com/picture_library/linqxml/linqxml3.png"&gt;&lt;br /&gt;&lt;p align="justify"&gt;Ahora completamos el código generado por &lt;i&gt;monodevelop&lt;/i&gt;, para que el programa completo quede como en el siguiente listado.&lt;/p&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;span class="using"&gt;using&lt;/span&gt; System;&lt;br /&gt;&lt;span class="using"&gt;using&lt;/span&gt; System.Linq;&lt;br /&gt;&lt;span class="using"&gt;using&lt;/span&gt; System.Xml.Linq;&lt;br /&gt;&lt;br /&gt;&lt;span class="using"&gt;namespace&lt;/span&gt; CrearXML{&lt;br /&gt; &lt;span class="reserved"&gt;class&lt;/span&gt; MainClass&lt;br /&gt; {&lt;br /&gt; &lt;span class="reserved"&gt; public static&lt;/span&gt;  &lt;span class="void"&gt;void&lt;/span&gt; Main (&lt;span class="string"&gt;string&lt;/span&gt;[] args){&lt;br /&gt; XDocument doc = new XDocument(new XElement("Articulos",&lt;br /&gt; new XElement("Articulo",new XElement("IdArticulo","1"),&lt;br /&gt; new XElement("Codigo","C01-01-C12140"),&lt;br /&gt; new XElement("Nombre","CATGUT CROMICO 4-0 30CM C1214/2-30")),&lt;br /&gt; new XElement("Articulo",new XElement("IdArticulo","2"),&lt;br /&gt; new XElement("Codigo","C01-01-C26109"),&lt;br /&gt; new XElement("Nombre","ACERO 2 45CM C26109x2")),&lt;br /&gt; new XElement("Articulo",new XElement("IdArticulo","3"),&lt;br /&gt; new XElement("Codigo","C01-01-C40590"),&lt;br /&gt; new XElement("Nombre","POLIESTER 2 75CM C4059"))));&lt;br /&gt; Console.WriteLine(doc.ToString());&lt;br /&gt; doc.Save("articulos.xml");&lt;br /&gt; Console.WriteLine("XML creado");&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p align="justify"&gt;&lt;br /&gt;La diferencia de la sintaxis para crear documentos XML con respecto a  la sintaxis empleada con las clases del ensamblado &lt;tt&gt;System.Xml&lt;/tt&gt;, es que esta  sintaxis se enfoca más en los elementos (representados por la clase  XElement) que en el documento (representado en la clase Xdocument ).&lt;br /&gt;En este listado creamos el documento XML de una manera declarativa anidando varias objetos XElement dentro de un objeto  Xdocument , al final llamamos al método Save para guardar el XML en el disco.&lt;br /&gt;Construimos la aplicación pulsando la tecla F8 y al ejecutarse veremos el resultado en la ventana de salida de &lt;i&gt;MonoDevelop&lt;/i&gt; como se muestra en la imagen siguiente.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;img src="http://www.humansharp.com/picture_library/linqxml/linqxml4.png"&gt;&lt;br /&gt;&lt;h3&gt;&lt;a href="http://www.humansharp.com/Code/PrimerLinqXML.zip"&gt;&lt;img src="http://www.humansharp.com/picture_library/dw.jpg" border="0"&gt;&amp;nbsp;Descarga el código fuente&lt;/a&gt;&lt;/h3&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6494419861240446187-2192253697786049020?l=xomalli.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/2192253697786049020'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/2192253697786049020'/><link rel='alternate' type='text/html' href='http://xomalli.blogspot.com/2010/05/trabajando-linq-para-xml-con.html' title='Trabajando LINQ para XML con Monodevelop Parte I de II'/><author><name>Martín Márquez</name><uri>http://www.blogger.com/profile/10939957618126542300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_j4WRR9G9bfY/SV2_nw3UxeI/AAAAAAAAAAM/nT3SYp94IHo/s1600-R/photo.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-6494419861240446187.post-2165184010529626232</id><published>2010-05-19T20:51:00.000-07:00</published><updated>2010-05-19T23:59:27.261-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><title type='text'>El patrón singleton con Monodevelop y PostgreSQL</title><content type='html'>&lt;p align="justify"&gt;&lt;br /&gt;En el post anterior mostré un ejemplo utilizando el patrón Singleton con conexiones a bases de datos SQL Server ejecutándonse bajo Microsoft Windows, ahora mostraré las modificaciones que tuve que realizar a ese ejemplo para que funcione con  &lt;br /&gt;PostgreSQL como base de datos y Linux como sistema operativo.&lt;br /&gt;Primeramente abrí el proyecto en &lt;a href="http://monodevelop.com/"&gt;Monodevelop&lt;/a&gt;, después descargue la última versión de la biblioteca &lt;a href="http://npgsql.projects.postgresql.org/"&gt;Npgsql&lt;/a&gt; para tener actualizado los últimos cambios de esta biblioteca, lo cuál es recomendable ya que además de arreglar los errores el equipo responsable agrega nuevas funcionalidades, una vez descargada la biblioteca comence con las siguientes modificaciones:&lt;br /&gt;&lt;br&gt;&lt;br /&gt;1-.Quitar la referencia al ensamblado de Sql Server (System.Data.SqlClient) y reemplazarlo por el de PostgreSQL (Npgsql), esto se hace dentro del explorador de la solución, haciendo click derecho sobre las referencias como se muestra en la imagen.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;img src="http://www.humansharp.com/picture_library/singlemono/sinlin0.png"&gt;&lt;br /&gt;&lt;p align="justify"&gt;&lt;br /&gt;Nos aparecerá la ventana "edit references", ahí escogemos la pestaña que dice "Ensamblado .Net" para buscar en el sistema de archivos en la ruta donde descargamos y descomprimimos la biblioteca &lt;i&gt;Npgsql&lt;/i&gt;,esto para seleccionar el ensamblado &lt;i&gt;Npgsql.dll&lt;/i&gt; como se muestra en la siguiente imagen.&lt;/p&gt;&lt;br /&gt;&lt;img src="http://www.humansharp.com/picture_library/singlemono/sinlin5.png"&gt;&lt;br /&gt;&lt;p align="justify"&gt;2-. Reemplazar en el código de las clases &lt;tt&gt;DataBase&lt;/tt&gt; y &lt;tt&gt;DataBase2&lt;/tt&gt; respectivamente el &lt;span class="using"&gt;namespace&lt;/span&gt; &lt;tt&gt;System.Data.SqlClient&lt;/tt&gt; por &lt;tt&gt;Npgsql&lt;/tt&gt;&lt;br /&gt;&lt;span class="using"&gt;using&lt;/span&gt; System.Data.SqlClient;&lt;br /&gt;por&lt;br /&gt;&lt;span class="using"&gt;using&lt;/span&gt; Npgsql;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p align="justify"&gt;3-. También en el código de esas clases reemplazar las líneas donde se hace la declaración del objeto que representa la conexión y donde se realiza la creación de dicho objeto, reemplazar las siguientes líneas:&lt;br /&gt;&lt;pre&gt;SqlConnection _conn = null;&lt;br /&gt;_conn = new SqlConnection();&lt;/pre&gt;&lt;br /&gt;por&lt;br /&gt;&lt;pre&gt;NpgsqlConnection _conn = null;&lt;br /&gt;_conn = new NpgsqlConnection();&lt;/pre&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p align="justify"&gt;&lt;br /&gt;4-. En estas mismas clases cambiar el tipo de excepción en el catch del try del metódo &lt;tt&gt;GetConnection()&lt;/tt&gt;.&lt;br /&gt;&lt;span class="reserved"&gt;catch&lt;/span&gt;(SqlException x)&lt;br /&gt;por&lt;br /&gt;&lt;span class="reserved"&gt;catch&lt;/span&gt;(NpgsqlException x)&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p align="justify"&gt;&lt;br /&gt;5-. Reemplazar el evento &lt;tt&gt;StateChange&lt;/tt&gt; del objeto &lt;tt&gt;NpgsqlConnection&lt;/tt&gt; y el delegado asociado al evento, por una propiedad de tipo &lt;tt&gt;string&lt;/tt&gt;&lt;br /&gt;que infome de las características de la conexión, esto debido a que aún el proveedor de datos de postgreSQL no cuenta con esta característica.&lt;br /&gt;&lt;pre&gt;&lt;span class="reserved"&gt;StateChange += delegate&lt;/span&gt;(object o,StateChangeEventArgs args){&lt;br /&gt;    Info = String.Format(" {1}| {2}| {3}|",args.CurrentState.ToString(),&lt;br /&gt;System.DateTime.Now.ToLocalTime(),_conn.DataSource,_conn.Database);&lt;/pre&gt;&lt;br /&gt;por &lt;br /&gt;&lt;pre&gt;Info = &lt;span class="reserved"&gt;String.Format&lt;/span&gt;(" {0}|{1}| {2}| {3}|",GetCurrentState,System.DateTime.Now.ToLocalTime(),_conn.DataSource ,_conn.Database);&lt;/pre&gt;&lt;br /&gt;Agregando la siguiente propiedad&lt;br /&gt;&lt;pre&gt;&lt;span class="reserved"&gt;public string&lt;/span&gt; GetCurrentState{ get {return (IsOpen == true ? "Open" : "Closed");}}&lt;/pre&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p align="justify"&gt;&lt;br /&gt;Terminando los cambios debemos de configurar MonoDevelop para que al ejecutar la aplicación el programa se ejecute en una terminal propia y no en la ventana de salida (output) de MonoDevelop, esto se hace en el menú principal en la opción &lt;i&gt;"Proyecto"&lt;/i&gt; eligiendo el submenú &lt;i&gt;"Opciones"&lt;/i&gt;, nos mostrará una pantalla como la siguiente imagen. &lt;/p&gt;&lt;br /&gt;&lt;img src="http://www.humansharp.com/picture_library/singlemono/sinlin6.png"&gt;&lt;br /&gt;&lt;p align="justify"&gt;Después de estos cambios podemos observar el resultado, de forma idéntica al resultado logrado en la plataforma Microsoft.&lt;br /&gt;Ingreso de los parámetros de conexión&lt;br /&gt;&lt;img src="http://www.humansharp.com/picture_library/singlemono/sinlin1.png"&gt;&lt;br /&gt;Sin el uso del patrón Singleton, cambian los tiempos en la conexión&lt;br /&gt;&lt;img src="http://www.humansharp.com/picture_library/singlemono/sinlin2.png"&gt;&lt;br /&gt;Usando el patrón Singleton, el tiempo es único.&lt;br /&gt;&lt;img src="http://www.humansharp.com/picture_library/singlemono/sinlin4.png"&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;h3&gt;&lt;a href="http://www.humansharp.com/Code/MonoSingleton.zip"&gt;&lt;img src="http://www.humansharp.com/picture_library/dw.jpg" border="0"&gt;&amp;nbsp;Descarga el código fuente&lt;/a&gt;&lt;/h3&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6494419861240446187-2165184010529626232?l=xomalli.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/2165184010529626232'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/2165184010529626232'/><link rel='alternate' type='text/html' href='http://xomalli.blogspot.com/2010/05/el-patron-singleton-con-monodevelop-y.html' title='El patrón singleton con Monodevelop y PostgreSQL'/><author><name>Martín Márquez</name><uri>http://www.blogger.com/profile/10939957618126542300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_j4WRR9G9bfY/SV2_nw3UxeI/AAAAAAAAAAM/nT3SYp94IHo/s1600-R/photo.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-6494419861240446187.post-6059267102243853658</id><published>2010-05-03T16:29:00.000-07:00</published><updated>2010-05-03T20:04:16.011-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Ingeniería de software'/><title type='text'>El patrón singleton</title><content type='html'>&lt;p align="justify"&gt;&lt;br /&gt;Muchos problemas de rendimiento (performance) y de escalabilidad (scalability) ocurren si no manejamos correctamente las conexiones a las bases de datos, hay que tener en presente que las conexiones para acceder a una base de datos son un recurso que consume memoria y tiempo de procesador, por lo que solo se deben crear las conexiones necesarias para el funcionamiento de las aplicaciones  y estas deben cerrarse tan pronto hayan sido ocupadas.&lt;br /&gt;Una buena práctica es que todas las clases que acceden a los recursos de la base de datos utilicen siempre una única conexión sin importar el número de instancias que estas clases generen al ser ejecutadas dentro de una aplicación, una solución recomendada a este escenario es utilizar los &lt;a href="http://es.wikipedia.org/wiki/Patr%C3%B3n_de_dise%C3%B1o"&gt;patrones de diseño&lt;/a&gt; de software.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Conectarse a una base de datos con el patrón Singleton&lt;/span&gt;&lt;br /&gt;&lt;p align="Justify"&gt;&lt;br /&gt;Es un patrón de diseño del tipo creacional que nos asegura la creación de únicamente la instancia de un objeto sin importar el número de veces  que se intenten crear más instancias de ese objeto.&lt;br /&gt;citando el clásico libro de &lt;a href="http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612"&gt;the gang of four &lt;/a&gt; &lt;b&gt;Design Patterns:Elements of Reusable Object-Oriented Software&lt;/b&gt;, &lt;i&gt;1995&lt;/i&gt;, &lt;i&gt;Pearson Addison Wesley&lt;/i&gt; "The Singleton design pattern must ensure a class only has one instance, and provide a global point of access to it"&lt;br&gt;&lt;br /&gt;Este patrón se utiliza para representar un objeto de hardware (por ejemplo una impresora), un componente del sistema operativo (un archivo o un directorio) o bien un recurso externo limitado (como una conexión a una base de datos), esta instancia revisará si ya ha sido creada, atenderá las peticiones de los objetos que la utilicen como un punto global de acceso (similar a una variable global) y sera responsable del mantener el seguimiento de su estado.&lt;br /&gt;El esqueleto clásico de un Singleton es el siguiente:&lt;/p&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;span class="reserved"&gt;class&lt;/span&gt; Singleton {&lt;br /&gt;public static Singleton Instance() {&lt;br /&gt;&lt;span class="comment"&gt;&lt;br /&gt;//Aqui aseguramos que solamente sea creada una sola vez&lt;br /&gt;//si la instancia es null&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="reserved"&gt;if&lt;/span&gt;(_instance == null) {&lt;br /&gt; lock(typeof(Singleton)) {&lt;br /&gt; &lt;span class="reserved"&gt;if&lt;/span&gt;(_instance == null) {&lt;br /&gt; _instance = new Singleton();&lt;br /&gt;     }&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;return _instance;&lt;br /&gt;}&lt;br /&gt;&lt;span class="comment"&gt;&lt;br /&gt;//el constructor protected o private evita que se creen instancias&lt;br /&gt;//por fuera del control de la clase&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="reserved"&gt;protected&lt;/span&gt; Singleton() { }&lt;br /&gt;&lt;span class="comment"&gt;&lt;br /&gt;//garantiza que todos los subprocesos siempre tengan&lt;br /&gt;//la (única) instancia más actual&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="reserved"&gt;private&lt;/span&gt; static volatile Singleton _instance = null;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p align="Justify"&gt;&lt;br /&gt;A continuación voy a mostrar el ejemplo de una clase que representa una conexión a una base de datos sin utilizar el patrón Singleton, para mostrar como se crea una conexión por cada ocasión que nosotros llamamos a la clase lo cual repercute en la escalabilidad y el desempeño de la aplicación si se tuvieran que invocar decenas o cientos las ejecuciones a esta clase.&lt;/p&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;span class="using"&gt;using&lt;/span&gt; System;&lt;br /&gt;&lt;span class="using"&gt;using&lt;/span&gt; System.Data;&lt;br /&gt;&lt;span class="using"&gt;using&lt;/span&gt; System.Data.SqlClient;&lt;br /&gt;&lt;br /&gt;&lt;span class="using"&gt;namespace&lt;/span&gt; PostSingleton&lt;br /&gt;{&lt;br /&gt;&lt;span class="reserved"&gt;&lt;span class="reserved"&gt;public&lt;/span&gt;&lt;/span&gt; class DataBase&lt;br /&gt;{&lt;br /&gt;        SqlConnection _conn = null;&lt;br /&gt; &lt;span class="reserved"&gt;public&lt;/span&gt; DataBase(string conString){&lt;br /&gt; ConnectionString = conString;&lt;br /&gt;    GetConnection(); &lt;br /&gt; }&lt;br /&gt;  &lt;span class="reserved"&gt;public&lt;/span&gt; &lt;span class="void"&gt;void&lt;/span&gt; GetConnection(){&lt;br /&gt;    try{&lt;br /&gt;    _conn = new SqlConnection();&lt;br /&gt;    _conn.StateChange += delegate(object o,StateChangeEventArgs args){&lt;br /&gt;    Info = String.Format(" {1}| {2}| {3}|",args.CurrentState.ToString(),&lt;br /&gt;System.DateTime.Now.ToLocalTime(),_conn.DataSource,_conn.Database);&lt;br /&gt;    };&lt;br /&gt;    _conn.ConnectionString = ConnectionString;&lt;br /&gt;    _conn.Open();&lt;br /&gt;    IsOpen = true;&lt;br /&gt;    }&lt;br /&gt;    catch(SqlException x){&lt;br /&gt; Close();&lt;br /&gt;    throw x;&lt;br /&gt;    }&lt;br /&gt;    }&lt;br /&gt; &lt;br /&gt; &lt;span class="reserved"&gt;public&lt;/span&gt; &lt;span class="void"&gt;void&lt;/span&gt; Close(){&lt;br /&gt;     if (_conn.State == System.Data.ConnectionState.Open){&lt;br /&gt;          _conn.Close();&lt;br /&gt;         IsOpen = false;&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;    string ConnectionString {set;get;}&lt;br /&gt;    &lt;span class="reserved"&gt;public&lt;/span&gt; bool IsOpen {set;get;}&lt;br /&gt;    &lt;span class="reserved"&gt;public&lt;/span&gt; string Info {set;get;}&lt;br /&gt;}}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;A continuación el programa principal:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;span class="using"&gt;using&lt;/span&gt; System;&lt;br /&gt;&lt;span class="using"&gt;using&lt;/span&gt; System.Collections.Generic;&lt;br /&gt;&lt;span class="using"&gt;using&lt;/span&gt; System.Linq;&lt;br /&gt;&lt;br /&gt;&lt;span class="using"&gt;namespace&lt;/span&gt; PostSingleton&lt;br /&gt;{&lt;br /&gt;&lt;span class="reserved"&gt;public&lt;/span&gt; class Program&lt;br /&gt;{&lt;br /&gt;&lt;span class="void"&gt;static&lt;/span&gt; List&lt;DataBase&gt; _conns = null;&lt;br /&gt;&lt;span class="reserved"&gt;public&lt;/span&gt; &lt;span class="void"&gt;static&lt;/span&gt; int Main(string[] args)&lt;br /&gt;{&lt;br /&gt;  _conns = new List&lt;DataBase&gt;();&lt;br /&gt;  string op = null;&lt;br /&gt;  Console.ForegroundColor = ConsoleColor.White;&lt;br /&gt;  &lt;span class="reserved"&gt;do&lt;/span&gt;{&lt;br /&gt; Console.Write("\n");&lt;br /&gt; Console.WriteLine("+-------------------------------+");&lt;br /&gt; Console.WriteLine(" Ejemplo del patron singleton para conexiones");&lt;br /&gt; Console.Write("\n");&lt;br /&gt; Console.WriteLine("a) Conexión DB");&lt;br /&gt; Console.WriteLine("b) Ver Conexiones");&lt;br /&gt; Console.WriteLine("q) Salir");&lt;br /&gt; Console.Write("\n");&lt;br /&gt; Console.ForegroundColor = ConsoleColor.Yellow;&lt;br /&gt; Console.Write("Elija su opción y pulse &lt;ENTER&gt; : ");&lt;br /&gt; Console.ForegroundColor = ConsoleColor.White;&lt;br /&gt; op = Console.ReadLine().ToLower();&lt;br /&gt; &lt;span class="reserved"&gt;switch&lt;/span&gt;(op){&lt;br /&gt;  case "a":&lt;br /&gt;   ConectarDB();&lt;br /&gt;   break;&lt;br /&gt;  case "b":&lt;br /&gt;   VerConexiones();&lt;br /&gt;   break;&lt;br /&gt; }&lt;br /&gt;  }while(op != "q");&lt;br /&gt;  Console.WriteLine("\nHasta luego");&lt;br /&gt; return 0;&lt;br /&gt; &lt;br /&gt;}&lt;br /&gt;&lt;span class="void"&gt;static&lt;/span&gt; void VerConexiones(){&lt;br /&gt;try{&lt;br /&gt;Console.Clear();&lt;br /&gt;Console.WriteLine("\nListado de conexiones");&lt;br /&gt;Console.Write("\n");&lt;br /&gt;Console.WriteLine("+------------------------------------+");&lt;br /&gt;Console.WriteLine("| CONEXIONES ACTIVAS                 |");&lt;br /&gt;Console.WriteLine("+------------------------------------+\n");&lt;br /&gt;&lt;span class="reserved"&gt;if&lt;/span&gt;(_conns.Count &gt; 0){&lt;br /&gt;var q = from c in _conns where c.IsOpen == true select c;&lt;br /&gt;&lt;span class="reserved"&gt;foreach&lt;/span&gt;(var i in q){&lt;br /&gt; Console.WriteLine("{0}",i.Info);&lt;br /&gt;}}else Console.WriteLine("NO HAY CONEXIONES ACTIVAS");&lt;br /&gt;}catch(Exception x){ Console.WriteLine("Excepcion " + x.Message); }&lt;br /&gt;}  &lt;br /&gt;&lt;span class="void"&gt;static&lt;/span&gt; void ConectarDB(){&lt;br /&gt; try{&lt;br /&gt; Console.Clear();&lt;br /&gt; Console.WriteLine("Datos de la cadena de conexion ");&lt;br /&gt;    Console.ForegroundColor = ConsoleColor.Yellow;&lt;br /&gt;    Console.Write("Servidor y pulse &lt;ENTER&gt; : ");&lt;br /&gt;    string server = @Console.ReadLine();&lt;br /&gt;    Console.Write("Base de datos y pulse &lt;ENTER&gt; : ");&lt;br /&gt;    string database = @Console.ReadLine();&lt;br /&gt;    Console.Write("Usuario y pulse &lt;ENTER&gt; : ");&lt;br /&gt;    string user = @Console.ReadLine();&lt;br /&gt;    Console.Write("Password y pulse &lt;ENTER&gt; : ");&lt;br /&gt;    string password = @Console.ReadLine();&lt;br /&gt; Console.ForegroundColor = ConsoleColor.White;&lt;br /&gt; string connStr = String.Format(&lt;br /&gt;    "Data Source={0};Initial Catalog={1};User ID={2};Password={3};",&lt;br /&gt;    server,database,user,password);&lt;br /&gt;    Console.WriteLine("Intentando conexión...");&lt;br /&gt;   DataBase db = new DataBase(connStr);&lt;br /&gt;    _conns.Add(db);&lt;br /&gt;  VerConexiones();&lt;br /&gt;}catch(Exception x){&lt;br /&gt; Console.WriteLine("Excepción " + x.Message);&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;span class="void"&gt;&lt;span class="void"&gt;static&lt;/span&gt;&lt;/span&gt; void Exit(){&lt;br /&gt;Environment.Exit(0);&lt;br /&gt;}}}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Al compilar y ejecutar la aplicación se mostrará el siguiente menú.&lt;br /&gt;&lt;img src="http://www.humansharp.com/picture_library/singleton/single1.png" border="0"/&gt;&lt;br /&gt;&lt;p align="justify"&gt;Escogiendo la opción (a) nos mostrará el menú para solicitarnos los parámetros de la cadena de conexión, si repetimos este procedimiento nos mostrará&lt;br /&gt;las conexiones hechas hacia el servidor, una por cada vez que hayamos completado la opción (a) como se muestra en la siguiente imagen.&lt;/p&gt;&lt;br /&gt;&lt;img src="http://www.humansharp.com/picture_library/singleton/single2.png" border="0"/&gt;&lt;br /&gt;&lt;p align="justify"&gt;Observamos en la imagen como es diferente el tiempo entre cada una de las conexiones ya que se crea una conexión por cada llamado.&lt;/p&gt;&lt;br /&gt;&lt;img src="http://www.humansharp.com/picture_library/singleton/single3.png" border="0"/&gt;&lt;br /&gt;&lt;p align="justify"&gt;Bien ahora mostraremos el mismo ejercicio utilizando el patrón Singleton en el código de la clase &lt;tt&gt;DataBase&lt;/tt&gt;, pero para no sobrescribir la clase &lt;tt&gt;DataBase&lt;/tt&gt; del ejercicio anterior, nombraremos la clase Singleton como &lt;tt&gt;DataBase2.&lt;/tt&gt;&lt;/p&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;span class="using"&gt;using&lt;/span&gt; System;&lt;br /&gt;&lt;span class="using"&gt;using&lt;/span&gt; System.Data;&lt;br /&gt;&lt;span class="using"&gt;using&lt;/span&gt; System.Data.SqlClient;&lt;br /&gt;&lt;br /&gt;&lt;span class="using"&gt;namespace&lt;/span&gt; PostSingleton&lt;br /&gt;{&lt;br /&gt;&lt;span class="reserved"&gt;public&lt;/span&gt; class DataBase2&lt;br /&gt;{&lt;br /&gt;&lt;span class="void"&gt;static&lt;/span&gt; DataBase2 Instance = null;&lt;br /&gt;&lt;span class="void"&gt;static&lt;/span&gt; SqlConnection _conn = null;&lt;br /&gt;&lt;span class="reserved"&gt;private&lt;/span&gt; DataBase2(){  }&lt;br /&gt;&lt;span class="reserved"&gt;private&lt;/span&gt; &lt;span class="void"&gt;static&lt;/span&gt; void CreateInstance(){&lt;br /&gt;    &lt;span class="reserved"&gt;if&lt;/span&gt;(Instance == null)&lt;br /&gt;    { Instance = new DataBase2();}&lt;br /&gt;    }&lt;br /&gt;    &lt;span class="reserved"&gt;public&lt;/span&gt; &lt;span class="void"&gt;static&lt;/span&gt; DataBase2 GetInstance(string conStr){&lt;br /&gt;    &lt;span class="reserved"&gt;if&lt;/span&gt;(Instance == null){&lt;br /&gt;    CreateInstance();&lt;br /&gt;    Instance.ConnectionString = conStr;&lt;br /&gt;    Instance.GetConnection();}&lt;br /&gt;    return Instance;&lt;br /&gt;    }&lt;br /&gt;    void GetConnection(){&lt;br /&gt;    try{&lt;br /&gt;    _conn = new SqlConnection();&lt;br /&gt;     _conn.StateChange += delegate(object o,StateChangeEventArgs args){&lt;br /&gt;    Info = String.Format(" {1}| {2}| {3}|",args.CurrentState.ToString(),&lt;br /&gt;    System.DateTime.Now.ToLocalTime(),_conn.DataSource,_conn.Database);&lt;br /&gt;    };&lt;br /&gt;    _conn.ConnectionString = ConnectionString;&lt;br /&gt;    _conn.Open();&lt;br /&gt;    IsOpen = true;&lt;br /&gt;    }&lt;br /&gt;    catch(SqlException x){&lt;br /&gt;        &lt;span class="reserved"&gt;if&lt;/span&gt; (_conn.State == System.Data.ConnectionState.Open)&lt;br /&gt;              _conn.Close();&lt;br /&gt;    throw x;&lt;br /&gt;    }&lt;br /&gt;    }&lt;br /&gt;    &lt;span class="reserved"&gt;public&lt;/span&gt; void Close(){&lt;br /&gt;  &lt;span class="reserved"&gt;if&lt;/span&gt; (_conn.State == System.Data.ConnectionState.Open){&lt;br /&gt;              _conn.Close();&lt;br /&gt;              IsOpen = false;&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt; string ConnectionString {set;get;}&lt;br /&gt; &lt;span class="reserved"&gt;public&lt;/span&gt; bool IsOpen {set;get;}&lt;br /&gt; &lt;span class="reserved"&gt;public&lt;/span&gt; string Info {set;get;} &lt;br /&gt;}}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Analizamos la clase y vemos el uso de los modificadores &lt;tt&gt;private&lt;/tt&gt; y &lt;tt&gt;static&lt;/tt&gt; en el constructor hace que no se pueda crear la clase de forma directa, sino solo a traves del método &lt;tt&gt;public GetInstance(string conStr)&lt;/tt&gt;  que regresa la instancia creada y por ende sus propiedades y métodos públicos.&lt;br /&gt;Antes de ejecutar el programa principal para que utilice la clase con el singleton, hay que modificar la líneas donde se crea la lista de conexiones&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;static List&lt;DataBase2&gt; _conns = null;&lt;br /&gt;_conns = new List&lt;DataBase2&gt;();&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;y tambien donde se invoca la conexión con la base de datos.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;_conns.Add(DataBase2.GetInstance(connStr));&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Haciendo estos cambios, ejecutando la aplicación, seleccionando la opción (a) para conectarse a una base de datos y creando varias conexiones debemos de ver &lt;br /&gt;la salida del programa como en la siguiente pantalla:&lt;br /&gt;&lt;img src="http://www.humansharp.com/picture_library/singleton/single4.png" border="0"/&gt;&lt;br /&gt;Observamos en la imagen como el tiempo entre cada una de las conexiones es siempre el mismo, ya que se crea una sola instancia global de acceso.&lt;br /&gt;&lt;h3&gt;&lt;a href="http://www.humansharp.com/Code/PostSingleton.zip"&gt;&lt;img src="http://www.humansharp.com/picture_library/dw.jpg" border="0"&gt;&amp;nbsp;Descarga el código fuente&lt;/a&gt;&lt;/h3&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6494419861240446187-6059267102243853658?l=xomalli.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/6059267102243853658'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/6059267102243853658'/><link rel='alternate' type='text/html' href='http://xomalli.blogspot.com/2010/05/el-patron-singleton.html' title='El patrón singleton'/><author><name>Martín Márquez</name><uri>http://www.blogger.com/profile/10939957618126542300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_j4WRR9G9bfY/SV2_nw3UxeI/AAAAAAAAAAM/nT3SYp94IHo/s1600-R/photo.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-6494419861240446187.post-1962308739279179531</id><published>2010-04-26T22:10:00.000-07:00</published><updated>2010-05-03T20:05:18.418-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><title type='text'>Uso de funciones PL/SQL en postgreSQL</title><content type='html'>Una función (function) en PostgreSQL son sentencias SQL agrupadas y precompiladas para ejecutarse en bloque dentro del servidor,  a diferencia de las consultas SQL donde cada consulta es procesada en tiempo de ejecución por el servidor ,  las funciones procedurales son compilados cuando son creados, ya que el servidor asume que serán ejecutados más de una vez,  un función ofrece las siguientes ventajas:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;No sobrecarga la comunicación cliente/servidor al evitar enviar una consulta tras otra, en su lugar procesa una consulta tras otra y envía únicamente el resultado.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Cuando y se ejecuta la primera vez se crea un plan preparado de ejecución, las  siguientes  ejecuciones reutilizan el plan preparado.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Agrega estructuras de control y capacidad de calculo al lenguaje SQL.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Las mismas consultas están disponibles para varias aplicaciones.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Seguridad los datos solo estan accesibles mediante las funciones y evita el uso de SQL injection.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;p align="justify"&gt;&lt;br /&gt;De los lenguajes más utilizados para crear funciones en postgreSQL, se encuentra PL/pgSQL, el cual se distribuye como un módulo cargable junto con postgreSQL, para emplearlo en nuestra base de datos es necesario darlo de alta, de la siguiente manera.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;img src="http://www.humansharp.com/picture_library/post14/ado3_fig1.jpg" /&gt;&lt;br /&gt;&lt;p align="justify"&gt;&lt;br /&gt;Revisamos si ya lo tenemos disponible en nuestra base de datos para utilizarlo&lt;br /&gt;La sintaxis de PL/pgSQL (similar al lenguaje PL/SQL de Oracle)&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;img src="http://www.humansharp.com/picture_library/post14/ado3_fig2.jpg" /&gt;&lt;br /&gt;&lt;b&gt;Utilizando PL/pgSQL con C#&lt;/b&gt;&lt;br /&gt;&lt;p align="justify"&gt;&lt;br /&gt;En este ejemplo usaremos PL/pgSQL y C# para resolver un requerimiento practico como seria relacionar la columna &lt;i&gt;city&lt;/i&gt; de nuestra tabla authors en nuestra base de datos con una tabla llamada &lt;i&gt;cities&lt;/i&gt; donde se encontrará la información de la columna ciudad mas un identificador.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;img src="http://www.humansharp.com/picture_library/post14/ado3_fig3.jpg" /&gt;&lt;br /&gt;&lt;p align="justify"&gt;&lt;br /&gt;La relación deberá de quedar de la siguiente manera, donde la columna &lt;i&gt;city&lt;/i&gt; se debe cambiar por la clave primaria de la tabla &lt;i&gt;cities&lt;/i&gt; que tendrá como clave primaria la clave de la ciudad y una columna adicional llamada &lt;i&gt;city&lt;/i&gt; que contendrá el nombre de la ciudad.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;span class="reserved"&gt;CREATE TABLE&lt;/span&gt; cities(&lt;br /&gt;idcity varchar(5) PRIMARY KEY,&lt;br /&gt;city varchar(20) NOT NULL UNIQUE&lt;br /&gt;);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Ahora usamos la siguiente función&lt;i&gt;function&lt;/i&gt; para tomar los valores de la columna &lt;i&gt;city&lt;/i&gt; en la tabla &lt;i&gt;authors&lt;/i&gt;, crear un identificador único para la llave primaria, insertar ese valor de clave primaria junto con el nombre de la ciudad y por último sustituir los valores en la columna &lt;i&gt;city&lt;/i&gt; y reemplazarlos con el valor de la llave primaria en la tabla &lt;i&gt;cities&lt;/i&gt;.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;span class="reserved"&gt;CREATE FUNCTION&lt;/span&gt; AddCities(varchar) RETURNS VARCHAR AS&lt;br /&gt;&lt;span class="void"&gt;'DECLARE&lt;br /&gt;hay record;&lt;br /&gt;nume varchar;&lt;br /&gt;BEGIN&lt;br /&gt;SELECT INTO hay count(city) FROM cities WHERE city = $1;&lt;br /&gt;IF hay.count = 0&lt;br /&gt;THEN&lt;br /&gt;INSERT INTO cities(idcity,city)&lt;br /&gt;VALUES(substring($1,1,3) || substring(random() * 1000,1,2),$1);&lt;br /&gt;SELECT INTO nume idcity FROM cities WHERE city = $1;&lt;br /&gt;UPDATE authors SET city = nume WHERE city = $1;&lt;br /&gt;RETURN nume;&lt;br /&gt;END IF;&lt;br /&gt;IF hay.count &gt; 0&lt;br /&gt;THEN&lt;br /&gt;SELECT INTO nume idcity FROM cities WHERE city = $1;&lt;br /&gt;UPDATE authors SET city = nume WHERE city = $1;&lt;br /&gt;RETURN nume;&lt;br /&gt;END IF;&lt;br /&gt;END;&lt;br /&gt;'&lt;/span&gt; &lt;span class="reserved"&gt;LANGUAGE&lt;/span&gt; 'plpgsql';&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p align="justify"&gt;Guardamos nuestra función en un archivo llamado store1.sql y lo ejecutamos para crearla dentro del servidor.&lt;/p&gt;&lt;br /&gt;&lt;img src="http://www.humansharp.com/picture_library/post14/ado3_fig4.jpg" /&gt;&lt;br /&gt;&lt;p&gt;Una vez creada nuestra función mostraremos como emplearla desde C# con el siguiente:&lt;/p&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;span class="using"&gt;using&lt;/span&gt; System;&lt;br /&gt;&lt;span class="using"&gt;using&lt;/span&gt; Gtk;&lt;br /&gt;&lt;span class="using"&gt;using&lt;/span&gt; System.Text;&lt;br /&gt;&lt;span class="using"&gt;using&lt;/span&gt; System.Data;&lt;br /&gt;&lt;span class="using"&gt;using&lt;/span&gt; Npgsql;&lt;br /&gt;&lt;span class="using"&gt;using&lt;/span&gt; NpgsqlTypes;&lt;br /&gt;&lt;br /&gt;&lt;span class="using"&gt;namespace&lt;/span&gt; PgForm {&lt;br /&gt;&lt;span class="void"&gt;class&lt;/span&gt; PgForm : Window {&lt;br /&gt;Label lbMsg = new Label("DEBUG: ");&lt;br /&gt;Entry txtNameFunction = new Entry();&lt;br /&gt;Entry txtArg = new Entry();&lt;br /&gt;&lt;br /&gt;&lt;span class="reserved"&gt;public&lt;/span&gt; PgForm() : base("Ejecutar funciones"){&lt;br /&gt;BorderWidth = 8;&lt;br /&gt;SetDefaultSize(208,220);&lt;br /&gt;this.DeleteEvent += new DeleteEventHandler(OnWindowDelete);&lt;br /&gt;Frame frame = new Frame ("Ejecutar funciones");&lt;br /&gt;Add (frame);&lt;br /&gt;VBox MainPanel = new VBox (false, 8);&lt;br /&gt;MainPanel.BorderWidth = 8;&lt;br /&gt;frame.Add (MainPanel);&lt;br /&gt;MainPanel.PackStart(new Label("Nombre de la funcion"),false,false,0);&lt;br /&gt;MainPanel.PackStart(txtNameFunction,false,false,0);&lt;br /&gt;MainPanel.PackStart(new Label("Si recibe un argumento de tipo varchar")&lt;br /&gt;                   ,false,false,0);&lt;br /&gt;MainPanel.PackStart(txtArg,false,false,0);&lt;br /&gt;Button btnSubmit = new Button("Ejecutar funcion");&lt;br /&gt;btnSubmit.Clicked += new EventHandler(btnSubmitClicked);&lt;br /&gt;MainPanel.PackStart(btnSubmit,false,false,0);&lt;br /&gt;MainPanel.PackStart(lbMsg,false,false,0);&lt;br /&gt;lbMsg.LineWrap = true;&lt;br /&gt;ShowAll();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="reserved"&gt;public&lt;/span&gt; &lt;span class="void"&gt;void&lt;/span&gt; OnWindowDelete(object o, DeleteEventArgs args) {&lt;br /&gt;Application.Quit(); &lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="void"&gt;void&lt;/span&gt; btnSubmitClicked(object o, EventArgs args){&lt;br /&gt;string cStr = "Server=127.0.0.1;Port=5432;User Id=postgres;" +&lt;br /&gt; "Password=postgres;Database=pubs;";&lt;br /&gt;try{&lt;br /&gt;&lt;span class="using"&gt;using&lt;/span&gt;(NpgsqlConnection conn = new NpgsqlConnection(cStr))&lt;br /&gt;{&lt;br /&gt;conn.Open();&lt;br /&gt;NpgsqlCommand cmd = new NpgsqlCommand(txtNameFunction.Text, conn);&lt;br /&gt;cmd.CommandType = System.Data.CommandType.StoredProcedure;&lt;br /&gt;//en caso de tener un parametro como en nuestra funcion de ejemplo&lt;br /&gt;&lt;span class="reserved"&gt;if&lt;/span&gt;(txtArg.Text.Length &gt; 0){&lt;br /&gt;cmd.Parameters.Add(new NpgsqlParameter());&lt;br /&gt;cmd.Parameters[0].NpgsqlDbType = NpgsqlDbType.Varchar;&lt;br /&gt;cmd.Parameters[0].Value = txtArg.Text;&lt;br /&gt;}&lt;br /&gt;lbMsg.Text += cmd.ExecuteScalar().ToString();&lt;br /&gt;}}catch(Exception e){&lt;br /&gt;lbMsg.Text += e.Message;&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="void"&gt;static&lt;/span&gt; &lt;span class="void"&gt;void&lt;/span&gt; Main(string[] args) {&lt;br /&gt;Application.Init();&lt;br /&gt;new PgForm();&lt;br /&gt;Application.Run();&lt;br /&gt;}} &lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Compilamos y ejecutamos.&lt;br /&gt;&lt;img src="http://www.humansharp.com/picture_library/post14/ado3_fig5.jpg" /&gt;&lt;br /&gt;Podemos probar nuestro programa invocando la funcion version() predeterminada de PostgreSQL.&lt;br /&gt;&lt;img src="http://www.humansharp.com/picture_library/post14/ado3_fig6.jpg" /&gt;&lt;br /&gt;Al ejecutar la función sin argumentos desde el formulario se vera el mismo resultado.&lt;br /&gt;&lt;img src="http://www.humansharp.com/picture_library/post14/ado3_fig7.jpg" /&gt;&lt;br /&gt;&lt;p align="justify"&gt;Aquí el driver de &lt;a href="http://npgsql.projects.postgresql.org/"&gt;PostgreSQL para .NET&lt;/a&gt; ejecuta la función usando la clase &lt;/p&gt;&lt;pre&gt;NpgsqlCommand&lt;/pre&gt; la cual recibe como argumento el nombre de la función y la conexión al servidor donde se encuentra.&lt;br /&gt;&lt;pre&gt;NpgsqlCommand cmd = new NpgsqlCommand(“version”, conn);&lt;/pre&gt;&lt;br /&gt;Si la función recibe parametros, debemos de crear una instancia de la clase &lt;pre&gt;NpgsqlParameter()&lt;/pre&gt; por cada uno de los parametros que reciba, es muy importante no olvidar indicarle a la clase &lt;pre&gt;NpgsqlCommand&lt;/pre&gt; que el comando que ejecutaremos es un stored procedure o una función pl/sql, esto lo hacemos mediante la instrucción:&lt;br /&gt;&lt;pre&gt;cmd.CommandType = System.Data.CommandType.StoredProcedure;&lt;/pre&gt;&lt;br /&gt;Para mayor referencia no olvidar leer la documentación del data provider para PostgreSQL.&lt;br /&gt;Si todo es ejecutado correctamente, ya podemos probar la función &lt;i&gt;AddCities&lt;/i&gt;  con el argumento del nombre de la ciudad y debe devolvernos la clave primaria de la tabla &lt;i&gt;cities&lt;/i&gt;.&lt;p&gt;&lt;/p&gt;&lt;br /&gt;&lt;img src="http://www.humansharp.com/picture_library/post14/ado3_fig8.jpg" /&gt;&lt;br /&gt;&lt;h3&gt;&lt;a href="http://www.humansharp.com/Code/FuncionPostgres.zip"&gt;&lt;img src="http://www.humansharp.com/picture_library/dw.jpg" border="0"&gt;&amp;nbsp;Descarga el código fuente&lt;/a&gt;&lt;/h3&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6494419861240446187-1962308739279179531?l=xomalli.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/1962308739279179531'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/1962308739279179531'/><link rel='alternate' type='text/html' href='http://xomalli.blogspot.com/2010/04/uso-de-funciones-plsql-en-postgresql.html' title='Uso de funciones PL/SQL en postgreSQL'/><author><name>Martín Márquez</name><uri>http://www.blogger.com/profile/10939957618126542300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_j4WRR9G9bfY/SV2_nw3UxeI/AAAAAAAAAAM/nT3SYp94IHo/s1600-R/photo.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-6494419861240446187.post-3247797275375997216</id><published>2010-04-04T13:46:00.000-07:00</published><updated>2010-04-05T21:08:33.957-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><title type='text'>Tutorial de LINQ con C# y Mono</title><content type='html'>En el número 15 de la revista Atix se publico un tutorial introductorio acerca de la utilización de LINQ (Language Integrated Query) con C#, la revista puede descargarse desde este enlace &lt;a href="http://atix.opentelematics.org/?cat=25"&gt;Revista Atix No 15&lt;/a&gt;.&lt;br /&gt;El pdf de ese tutorial puede descargarse  en este enlace &lt;a href="http://www.humansharp.com/docs/TrabajandoLinq.pdf"&gt;Entendiendo LINQ con Mono y C#&lt;/a&gt; o bien en la sección documentos para descargar.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6494419861240446187-3247797275375997216?l=xomalli.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/3247797275375997216'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/3247797275375997216'/><link rel='alternate' type='text/html' href='http://xomalli.blogspot.com/2010/04/tutorial-de-linq-con-c-y-mono.html' title='Tutorial de LINQ con C# y Mono'/><author><name>Martín Márquez</name><uri>http://www.blogger.com/profile/10939957618126542300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_j4WRR9G9bfY/SV2_nw3UxeI/AAAAAAAAAAM/nT3SYp94IHo/s1600-R/photo.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-6494419861240446187.post-200235375987753578</id><published>2010-04-04T11:26:00.000-07:00</published><updated>2010-04-05T21:04:07.085-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Ingeniería de software'/><title type='text'>Patrones de diseño</title><content type='html'>Los patrones de diseño son soluciones probadas en diferentes contextos que resuelven los problemas comunes de programación  y desde la aparición del libro&lt;br /&gt;"Design Patterns:Elements of Reusable Object Oriented Software"(Pearson Addison Wesley,1995) escrito por la famosisima Gang Of Four GoF (Erich Gamma,Richard Helm,Ralph Johnson, John Vlissides), han estado presentes en el desarrollo de software desde más decada, aunque su utilización es independiente del lenguaje de programación, han sido más conocidos y utilizados por los lenguajes orientados a objetos como C++,Java y por supuesto C#.&lt;br /&gt;En el libro de GoF se describen 23 patrones agrupados en 3 categorías: estructurales, de creacion y de comportamiento.&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;b&gt;De creación&lt;/b&gt;&lt;br /&gt;&lt;li&gt;Singleton&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Factory&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Abstract Factory&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Builder&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Prototype&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;b&gt;Estructurales&lt;/b&gt;&lt;br /&gt;&lt;li&gt;Adapter&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Bridge&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Composite&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Decorator &lt;/li&gt;&lt;br /&gt;&lt;li&gt;Facade&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Flyweight&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Proxy&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;b&gt;De Comportamiento&lt;/b&gt;&lt;br /&gt;&lt;li&gt;Chain of Responsability&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Command&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Interpreter&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Iterator&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Mediator&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Memento&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Observer&lt;/li&gt;&lt;br /&gt;&lt;li&gt;State&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Strategy&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Template Method&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Visitor&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;Los patrones de diseño se aplican en el diseño y en la arquitectura como formulas generales es decir: la idea con los patrones es que cuando se requiera resolver un problema, se identifique el problema y se aplique el patrón o los patrones adecuados para resolverlo, como una forma similar  a los matemáticos que  aplican una formula o varias formulas según se requiera para resolver un problema.&lt;br /&gt;Lo bueno de esto es que una solución basada en patrones es reusable, extensible, mantenible y sobre todo elegante.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6494419861240446187-200235375987753578?l=xomalli.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/200235375987753578'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/200235375987753578'/><link rel='alternate' type='text/html' href='http://xomalli.blogspot.com/2010/04/patrones-de-diseno.html' title='Patrones de diseño'/><author><name>Martín Márquez</name><uri>http://www.blogger.com/profile/10939957618126542300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_j4WRR9G9bfY/SV2_nw3UxeI/AAAAAAAAAAM/nT3SYp94IHo/s1600-R/photo.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-6494419861240446187.post-5343220668260712552</id><published>2009-12-24T20:36:00.000-08:00</published><updated>2010-05-03T20:06:28.098-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><title type='text'>La segunda parte del tutorial de la revista Atix</title><content type='html'>La revista Atix en su &lt;a href="http://atix.opentelematics.org/?p=171"&gt;número 14&lt;/a&gt; publicó la segunda parte del tutorial sobre XML utilizando &lt;a href="http://monodevelop.com/"&gt;MonoDevelop&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Los archivos del  proyecto y el código fuente correspondientes al proyecto de ejemplo del tutorial pueden ser descargados en un archivo comprimido desde este &lt;a href="http://www.humansharp.com/Code/MonoBitacora.zip"&gt;enlace&lt;/a&gt;.&lt;br /&gt;&lt;h3&gt;&lt;a href="http://www.humansharp.com/Code/MonoBitacora.zip"&gt;&lt;img src="http://www.humansharp.com/picture_library/dw.jpg" border="0" /&gt; Descarga el código fuente&lt;/a&gt;&lt;/h3&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6494419861240446187-5343220668260712552?l=xomalli.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/5343220668260712552'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/5343220668260712552'/><link rel='alternate' type='text/html' href='http://xomalli.blogspot.com/2009/12/la-segunda-parte-del-tutorial-de-la.html' title='La segunda parte del tutorial de la revista Atix'/><author><name>Martín Márquez</name><uri>http://www.blogger.com/profile/10939957618126542300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_j4WRR9G9bfY/SV2_nw3UxeI/AAAAAAAAAAM/nT3SYp94IHo/s1600-R/photo.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-6494419861240446187.post-3375576966474785854</id><published>2009-10-05T23:04:00.000-07:00</published><updated>2010-05-03T20:06:55.537-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><title type='text'>Archivos del proyecto de la Revista Atix</title><content type='html'>La  &lt;a href="http://atix.opentelematics.org/?cat=25"&gt;Revista Atix&lt;/a&gt; publicó la primera parte de un tutorial sobre XML utilizando &lt;a href="http://monodevelop.com/"&gt;MonoDevelop&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Desde este &lt;a href="http://www.humansharp.com/Code/AtiXml.zip"&gt;enlace&lt;/a&gt; se puede descargar un archivo comprimido, que contiene el código fuente del ejercicio y los archivos del proyecto.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;&lt;a href="http://www.humansharp.com/Code/AtiXml.zip"&gt;&lt;img src="http://www.humansharp.com/picture_library/dw.jpg" border="0" /&gt; Descarga el código fuente&lt;/a&gt;&lt;/h3&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6494419861240446187-3375576966474785854?l=xomalli.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/3375576966474785854'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/3375576966474785854'/><link rel='alternate' type='text/html' href='http://xomalli.blogspot.com/2009/10/archivos-del-proyecto-de-la-revista.html' title='Archivos del proyecto de la Revista Atix'/><author><name>Martín Márquez</name><uri>http://www.blogger.com/profile/10939957618126542300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_j4WRR9G9bfY/SV2_nw3UxeI/AAAAAAAAAAM/nT3SYp94IHo/s1600-R/photo.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-6494419861240446187.post-1538295282562488951</id><published>2009-05-29T00:32:00.000-07:00</published><updated>2009-05-29T16:02:06.970-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Ingeniería de software'/><title type='text'>Notas de Unified Modeling Language (UML)</title><content type='html'>&lt;p align="justify"&gt;&lt;br /&gt;Hace ya casi un mes que terminé un curso de UML y hace un par de semanas que me llego el número de serie para activar Enterprise Architect, la cual es una herramienta muy útil para  realizar los diagramas UML que sean requeridos por el proyecto, aunque siempre es bueno capacitarse,  lo mejor es practicar. &lt;br /&gt;&lt;br /&gt;Las notas que elaboré del curso son las siguientes:&lt;br /&gt;&lt;br /&gt;Hay que tener en cuenta que para todo proyecto, sobre todo de sistemas existen un ¿qué hacer? (análisis o modelo conceptual) y un ¿cómo hacer? (diseño o modelo de clases), donde hay actores o agentes externos al sistema.&lt;br /&gt;De todas las metodologías hay metodologías que cubren la parte de administración y la parte de ingeniería dentro de la misma metodología,  dos ejemplos de metodologías que cubren estos dos aspectos de los proyectos son: &lt;b&gt;Microsoft Solution Framework (MSF)&lt;/b&gt; y &lt;b&gt;Rational Unified Process (RUP)&lt;/b&gt;, las características principales de este último son:&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;Esta dirigido por casos de uso.&lt;br /&gt;&lt;li&gt;Centrado en la arquitectura (tecnología, hardware, aplicación) y un ciclo de vida  &lt;br /&gt;&lt;li&gt;Es iterativo (cada dos o dos meses y medio entregar algo al cliente funcionando).&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;Este proceso toma una parte de la lógica del ciclo de vida en cascada, que tiene dos principios:&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;No se puede programar algo que no está diseñado.&lt;br /&gt;&lt;li&gt;No se puede probar algo que no está programado.&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;b&gt;Buenas prácticas&lt;/b&gt;&lt;br /&gt;&lt;p align="justify"&gt;&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;solicitar una recomendación para nomenclatura de proceso.&lt;br /&gt;&lt;li&gt;solicitar procedimiento y reglamento.&lt;br /&gt;&lt;li&gt;objetivo del proceso.&lt;br /&gt;&lt;li&gt;usar verbos pasivos más el complemento para el nombre de las actividades.&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;b&gt;Notas sobre los diagramas.&lt;/b&gt;&lt;br /&gt;&lt;p align="justify"&gt;&lt;br /&gt;En los &lt;b&gt;diagramas de actividades&lt;/b&gt; solo puede haber un estado inicial y un estado final.&lt;br /&gt;Los &lt;b&gt;diagramas de secuencia&lt;/b&gt; son uno a uno con los &lt;b&gt;diagramas de casos&lt;/b&gt; de uso, es decir por cada &lt;b&gt;diagrama de caso&lt;/b&gt; de uso debe de existir un &lt;b&gt;diagrama de secuencia&lt;/b&gt;.&lt;br /&gt;Cada diagrama no debe de tener más de nueve elementos en promedio de cinco a siete elementos.&lt;br /&gt;Los actores primarios en el &lt;b&gt;diagrama del caso de uso&lt;/b&gt; van del lado derecho y los actores secundarios van del lado izquierdo.&lt;br /&gt;El término realización se refiere a que cada caso de uso realiza un requerimiento.&lt;br /&gt;Nunca al redactarse un caso de uso se debe poner la palabra etc.&lt;br /&gt;Siempre es bueno acompañar los diagramas con un glosario de términos.&lt;br /&gt;Una forma de estimación de los casos de uso es la clasificación de actores, un ejemplo:&lt;br /&gt;+-------------------------+&lt;br /&gt;| Simple  | 1 | Sistema   |&lt;br /&gt;+-------------------------+&lt;br /&gt;| Mediana | 2 | Máquina   |&lt;br /&gt;+-------------------------+&lt;br /&gt;| Dificíl | 3 | Humano    |&lt;br /&gt;+-------------------------+&lt;br /&gt;&lt;br /&gt;En el &lt;b&gt;modelo conceptual&lt;/b&gt; se muestran tanto las reglas físicas como las reglas de negocio.&lt;br /&gt;El orden del ciclo hasta el diseño deberá ser:&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Modelado del negocio:&lt;/b&gt; diagrama de Stakeholder y diagrama de proceso de negocio.&lt;br /&gt;&lt;br&gt;&lt;br /&gt;&lt;b&gt;Requerimientos:&lt;/b&gt; matriz de requerimientos, matriz de trazabilidad y diagrama de casos de uso.&lt;br /&gt;&lt;br&gt;&lt;br /&gt;&lt;b&gt;Análisis:&lt;/b&gt; descripción de alto nivel y especificación detallada de casos de uso.&lt;br /&gt;&lt;br&gt;&lt;br /&gt;&lt;b&gt;Diseño:&lt;/b&gt; modelo conceptual, diseño detallado y prototipo.&lt;br /&gt;&lt;br&gt;&lt;br /&gt;Para aseguramiento de la calidad usar las revisiones de software y "poner puntos de control" es decir revisar los artefactos creados y regresar con el usuario.&lt;br /&gt;&lt;br /&gt;El &lt;b&gt;diagrama de comunicación&lt;/b&gt; solo muestra cuales son los mensajes.&lt;br /&gt;El &lt;b&gt;diagrama de secuencia&lt;/b&gt; muestra el orden en que deben de invocarse los mensajes.&lt;br /&gt;Un escenario va de un estado inicial al estado final.&lt;br /&gt;Siempre debemos de fijarnos entre la correspondencia entre el &lt;b&gt;diagrama de secuencia&lt;/b&gt; y el &lt;b&gt;diagrama de clases&lt;/b&gt; en cuanto a la multiplicidad, recordando que una multiplicidad se refiere a una colección.&lt;br /&gt;En la nomenclatura de un &lt;b&gt;diagrama de clases&lt;/b&gt; si se tiene dos puntos (:) se refiere a una instancia y si se tiene cuatro puntos (::) se refiere al namespace más la instancia.&lt;br /&gt;Para hacer un &lt;b&gt;diagrama de secuencia&lt;/b&gt; se debe de pensar en operaciones, en tiempo y en la responsabilidad.&lt;br /&gt;Por buenas prácticas en el constructor solo se debe de poner los métodos que se inicialicen y se debe de separar de la invocación de los métodos.&lt;br /&gt;Por estandarización no se ponen los retornos en el diagrama de secuencia, pero solamente si es necesario, la respuesta siempre regresa al actor que invoco el método.&lt;br /&gt;Un caso de uso abstracto es un caso de uso que se utiliza para representar soluciones genéricas y se coloca dentro del paquete de casos de uso, este caso de uso se utiliza para ocurrencias que es una nota dentro del &lt;b&gt;diagrama de secuencia&lt;/b&gt; que va hacia un &lt;b&gt;diagrama de secuencia&lt;/b&gt; que está dentro del caso de uso abstracto.&lt;br /&gt;La diferencia entre un &lt;b&gt;diagrama de clases&lt;/b&gt; y un &lt;i&gt;diagrama conceptual&lt;/i&gt; son los métodos, en el &lt;b&gt;diagrama conceptual&lt;/b&gt; únicamente se muestran los atributos y la relación de los objetos además en el &lt;b&gt;modelo conceptual&lt;/b&gt; se puede omitir el tipo de dato en cambio en el &lt;b&gt;diagrama de clases&lt;/b&gt; es obligatorio poner el tipo de dato.&lt;br /&gt;Una funcionalidad como los hilos (threads) solamente puede diagramarse en el &lt;b&gt;diagrama de secuencia&lt;/b&gt;.&lt;br /&gt;De un &lt;b&gt;diagrama de secuencia&lt;/b&gt; puede sacarse el diagrama de colaboración o viceversa.&lt;br /&gt;En un &lt;b&gt;diagrama de actividades&lt;/b&gt; el estado inicial no es obligatorio.&lt;br /&gt;En el &lt;b&gt;diagrama de componentes&lt;/b&gt; existe el manifest: que indica una relación lógica entre el componente y un archivo físico.&lt;br /&gt;En el &lt;b&gt;diagrama de máquinas de estados&lt;/b&gt;, se ponen los objetos que más relaciones tienen además los &lt;b&gt;diagramas de máquinas de estados&lt;/b&gt; son útiles en la etapa de análisis, aunque también pueden usarse en la etapa de diseño.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p align="justify"&gt;&lt;br /&gt;Esta herramienta también puede auxiliarnos en la etapa de desarrollo creando código desde el diagrama clases, aquí dependerá del lenguaje o los lenguajes que decidimos para el proyecto y por supuesto no olvidar que la notación de UML  ayuda con  un factor importante en los proyectos: &lt;b&gt;la comunicación.&lt;/b&gt;&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6494419861240446187-1538295282562488951?l=xomalli.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/1538295282562488951'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/1538295282562488951'/><link rel='alternate' type='text/html' href='http://xomalli.blogspot.com/2009/05/trabajando-con-unified-modeling.html' title='Notas de Unified Modeling Language (UML)'/><author><name>Martín Márquez</name><uri>http://www.blogger.com/profile/10939957618126542300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_j4WRR9G9bfY/SV2_nw3UxeI/AAAAAAAAAAM/nT3SYp94IHo/s1600-R/photo.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-6494419861240446187.post-1999943785248199787</id><published>2009-05-26T15:46:00.000-07:00</published><updated>2009-05-29T01:14:51.866-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Ingeniería de software'/><title type='text'>Ingeniería de software</title><content type='html'>Hace un par de semanas me solicitaron la elaboración de dos propuestas, una para la migración y otra para un nuevo desarrollo por lo me solicitaron hacer un resumen general sobre Metodologías RUP, MSF y XP, el mismo para ambas propuestas, el resultado fue el siguiente: &lt;br /&gt;&lt;p align="justify"&gt;&lt;br /&gt;&lt;b&gt;&lt;i&gt;Microsoft Solution Framework (MSF)&lt;/i&gt;&lt;/b&gt; proporciona un conjunto de modelos, principios, y guías para diseñar y desarrollar soluciones empresariales de una manera que asegura que todos los elementos del proyecto tal como gente, procesos y herramientas, puedan ser exitosamente conducidos. No solamente es aplicable a los proyectos de desarrollo sino igualmente a los de infraestructura o redes. MSF actualmente tiene dos instancias: MSF for Agile Software Development y MSF for CMMI (Capability Maturity Model Integration) Process Improvement.MSF contiene un meta-modelo que estaba basado en la filosofía de que un proceso esta creado para ayudar y no para estorba, este modelo es compartido para procesos agiles y maduros que ocupen MSF.MSF consta de cinco fases: Previsión, Planificación, Desarrollo, Estabilización e Implementación y es continuamente refinado por clientes, consultores, grupos de producto y partners de Microsoft.&lt;/p&gt;&lt;br /&gt;&lt;p align="justify"&gt;&lt;br /&gt;&lt;b&gt;&lt;i&gt;Rational United Process (RUP)&lt;/i&gt;&lt;/b&gt; Es un refinamiento del proceso unificado, sus características principales son combinar las prácticas comúnmente aceptadas de los procesos incremental e iterativo. Su objetivo principal es entregar artefactos verificables por el cliente. El énfasis en el desarrollo iterativo e incremental previene muchos de los riesgos comunes en los proyectos al animar al equipo a desarrollar en principio lo más riesgoso del proyecto, además de que los artefactos y los roles de los participantes están bien definidos y que el proceso esta soportado por muchas herramientas de desarrollo, el proceso toma en cuenta que cada proyecto es diferente, con necesidades diferentes y habilita para que cada fase del proyecto sea personalizada para lo requerido por el proyecto. Este proceso comienza con la toma de requerimientos, el análisis y el diseño para todo el proyecto incluyendo el modelado de datos y de objetos antes de la construcción. En este sentido toma un enfoque de proceso en cascada para el análisis y el diseño y un enfoque iterativo para la construcción y la liberación.&lt;/p&gt;&lt;br /&gt;&lt;p align="justify"&gt;&lt;br /&gt;&lt;b&gt;&lt;i&gt;Extreme Programming (XP)&lt;/i&gt;&lt;/b&gt; Los procesos ágiles mueven el enfoque de desarrollo de software hacia lo que se considera la importancia del desarrollo de software: ejecutar software. Esto es posible si se acepta que el desarrollo de software es un trabajo creativo hecho por seres humanos individuales, por eso este proceso anima a la comunicación, interacción y diversión. XP se distingue de otras metodologías en: es inmediato, concreto y se retroalimenta en ciclos muy cortos, tiene flexibilidad para programar las funcionalidades en acuerdo con los cambios en los requerimientos, se confía de pruebas automatizadas escritas por los programadores y clientes para monitorear el progreso del desarrollo que permite una detección de pruebas tempranas, se confía de la comunicación oral y el código fuente para mostrar la estructura del programa, tiene confianza en la cercana colaboración de los programadores con habilidades ordinarias. XP es diseñado para trabajar con proyectos que pueden ser construidos por equipos de dos a diez programadores.&lt;/p&gt;&lt;br /&gt;&lt;p align="justify"&gt;&lt;br /&gt;En la revisión de las propuestas por parte del cliente, se selecciono la metodología MSF para el nuevo desarrollo y RUP para la migración, lo interesante de esta elección es que la tecnología empleada por el cliente en ambos proyectos es .NET, por lo que la elección natural hubiera sido MSF sin miramientos.&lt;br /&gt;&lt;br /&gt;Pero bueno el cliente es el cliente y sus razones tendrá, aunque esta decisión no es tan dispar como pudiera parecerse, ya que MSF y RUP comparten una gran cantidad de artefactos, por lo que solo deberé que usar lo común a las dos metodologías.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6494419861240446187-1999943785248199787?l=xomalli.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/1999943785248199787'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/1999943785248199787'/><link rel='alternate' type='text/html' href='http://xomalli.blogspot.com/2009/05/ingenieria-de-software.html' title='Ingeniería de software'/><author><name>Martín Márquez</name><uri>http://www.blogger.com/profile/10939957618126542300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_j4WRR9G9bfY/SV2_nw3UxeI/AAAAAAAAAAM/nT3SYp94IHo/s1600-R/photo.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-6494419861240446187.post-3110761612922516134</id><published>2009-04-12T07:38:00.000-07:00</published><updated>2009-05-29T01:15:44.957-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Lenguajes .NET'/><title type='text'>Prueba de conocimientos</title><content type='html'>Hace un par de meses con motivo de una consultoría una empresa transnacional me hizo un examen sobre conocimientos en C#, este examen me ha llamado la atención por el tipo de preguntas, que me da la impresión que era de un examen de Java y solo ajustaron las preguntas para C#, incluso en algunas preguntas decian "In Java we can .....bla,bla in C# how to .....bla,bla", como si asumieran que el entrevistado además de C# conoce Java, casos que no siempre es asi, algunas preguntas son en verdad muy buenas para conocer el nivel de programación.&lt;br /&gt;&lt;br /&gt;Entre las preguntas se encontraban algunas que bien se podria responder dependiendo de la situación:&lt;br /&gt;&lt;br /&gt;If you need to modify a value parameter to a function, which of the following can you do to achieve this?&lt;br /&gt;&lt;br /&gt;1-. use a ref keyword&lt;br /&gt;2-. use an out keyword&lt;br /&gt;3-. use the return keyword&lt;br /&gt;4-. All of Above&lt;br /&gt;&lt;br /&gt;True or false Like in C++, using exception does carry some performance penalty.&lt;br /&gt;1-. true&lt;br /&gt;2-. false&lt;br /&gt;&lt;br /&gt;if we want to hide a non virtual method, public void Print(), was the way to declare the method in the derived class?&lt;br /&gt;&lt;br /&gt;1-.public void Print();&lt;br /&gt;2-.public virtual void Print();&lt;br /&gt;3-.public override void Print();&lt;br /&gt;4-.public new void Print();&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;To catch all exceptions, which of the following would you declare?&lt;br /&gt;1-.catch(...)&lt;br /&gt;2-.catch(exception e)&lt;br /&gt;3-.catch(throwable t)&lt;br /&gt;4-.catch&lt;br /&gt;&lt;br /&gt;En lo particular me gusta este tipo de exámenes ya que todas las respuestas son soluciones y solo es correcta la mejor, es decir la que es considerada como una buena práctica (best practice).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6494419861240446187-3110761612922516134?l=xomalli.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/3110761612922516134'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/3110761612922516134'/><link rel='alternate' type='text/html' href='http://xomalli.blogspot.com/2009/04/prueba-de-conocimientos.html' title='Prueba de conocimientos'/><author><name>Martín Márquez</name><uri>http://www.blogger.com/profile/10939957618126542300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_j4WRR9G9bfY/SV2_nw3UxeI/AAAAAAAAAAM/nT3SYp94IHo/s1600-R/photo.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-6494419861240446187.post-4804946079835069298</id><published>2009-03-05T19:42:00.000-08:00</published><updated>2009-05-29T01:14:15.118-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Windows'/><title type='text'>Code Access Security CAS, la seguridad en el código</title><content type='html'>CAS (Code Access Security), es la forma en que los ensamblados solicitan permisos para acceder a ciertos recursos para su ejecución en el CLR, esto proporciona seguridad a nivel código,como una forma complementaria y adicional a la seguridad del sistema operativo.&lt;br /&gt;Esta seguridad debe estar presente sobre todo si de desarrollan componentes, plugins, add-ons o juegos que serán ejecutados en diferentes ambientes que no conocemos ni controlamos.&lt;br /&gt;Señalo que esta seguridad es complementaria y en ningún momento deberá reemplazar la seguridad del sistema operativo.&lt;br /&gt;Para explicar voy a usar un ejemplo, un banco nos solicito realizar un aplicación donde el usuario genera unos archivos de estados de cuenta esta aplicación en un diseño inicial esta compuesta por un formulario y un ensamblado que se encarga de generar el estado de cuenta en un archivo XML.&lt;br /&gt;Obviamente una aplicación de esta naturaleza, necesitaría una disciplina de análisis y diseño, pero para fines ilustrativos, logramos llegar a la etapa de construcción sin la utilización del CAS.&lt;br /&gt;La aplicación se mostraría más o menos así,&lt;br /&gt;&lt;br&gt;&lt;br /&gt;&lt;img src="http://humansharp.com/picture_library/post5/CAS.jpg" border="0" alt="" width="290px" height="264"/&gt;&lt;br /&gt;&lt;br&gt;&lt;br /&gt;La operación de la aplicación consiste que cuando el usuario presione el botón de generar, se generaría un archivo XML en una carpeta restringida para ciertos usuarios, el código del método del ensamblado es el siguiente:&lt;br /&gt;&lt;br&gt;&lt;br /&gt;&lt;span class="sc5"&gt;public&lt;/span&gt;&lt;span class="sc0"&gt; &lt;/span&gt;&lt;span class="sc5"&gt;void&lt;/span&gt;&lt;span class="sc0"&gt; &lt;/span&gt;&lt;span class="sc11"&gt;WriteBank&lt;/span&gt;&lt;span class="sc10"&gt;(&lt;/span&gt;&lt;span class="sc5"&gt;string&lt;/span&gt;&lt;span class="sc0"&gt; &lt;/span&gt;&lt;span class="sc11"&gt;fileName&lt;/span&gt;&lt;span class="sc10"&gt;)&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;       &lt;/span&gt;&lt;span class="sc10"&gt;{&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;           &lt;/span&gt;&lt;span class="sc5"&gt;try&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;           &lt;/span&gt;&lt;span class="sc10"&gt;{&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;               &lt;/span&gt;&lt;span class="sc5"&gt;string&lt;/span&gt;&lt;span class="sc0"&gt; &lt;/span&gt;&lt;span class="sc11"&gt;rootpath&lt;/span&gt;&lt;span class="sc0"&gt; &lt;/span&gt;&lt;span class="sc10"&gt;=&lt;/span&gt;&lt;span class="sc0"&gt; &lt;/span&gt;&lt;span class="sc5"&gt;string&lt;/span&gt;&lt;span class="sc10"&gt;.&lt;/span&gt;&lt;span class="sc11"&gt;Format&lt;/span&gt;&lt;span class="sc10"&gt;(&lt;/span&gt;&lt;span class="sc13"&gt;@"C:{0}Banks{0}"&lt;/span&gt;&lt;span class="sc10"&gt;,&lt;/span&gt;&lt;span class="sc11"&gt;Path&lt;/span&gt;&lt;span class="sc10"&gt;.&lt;/span&gt;&lt;span class="sc11"&gt;DirectorySeparatorChar&lt;/span&gt;&lt;span class="sc10"&gt;);&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;               &lt;/span&gt;&lt;span class="sc5"&gt;if&lt;/span&gt;&lt;span class="sc10"&gt;(!&lt;/span&gt;&lt;span class="sc11"&gt;Directory&lt;/span&gt;&lt;span class="sc10"&gt;.&lt;/span&gt;&lt;span class="sc11"&gt;Exists&lt;/span&gt;&lt;span class="sc10"&gt;(&lt;/span&gt;&lt;span class="sc11"&gt;rootpath&lt;/span&gt;&lt;span class="sc10"&gt;))&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;                   &lt;/span&gt;&lt;span class="sc11"&gt;Directory&lt;/span&gt;&lt;span class="sc10"&gt;.&lt;/span&gt;&lt;span class="sc11"&gt;CreateDirectory&lt;/span&gt;&lt;span class="sc10"&gt;(&lt;/span&gt;&lt;span class="sc11"&gt;rootpath&lt;/span&gt;&lt;span class="sc10"&gt;);&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;               &lt;/span&gt;&lt;span class="sc11"&gt;XmlTextWriter&lt;/span&gt;&lt;span class="sc0"&gt; &lt;/span&gt;&lt;span class="sc11"&gt;tw&lt;/span&gt;&lt;span class="sc0"&gt; &lt;/span&gt;&lt;span class="sc10"&gt;=&lt;/span&gt;&lt;span class="sc0"&gt; &lt;/span&gt;&lt;span class="sc5"&gt;new&lt;/span&gt;&lt;span class="sc0"&gt; &lt;/span&gt;&lt;span class="sc11"&gt;XmlTextWriter&lt;/span&gt;&lt;span class="sc10"&gt;(&lt;/span&gt;&lt;span class="sc11"&gt;rootpath&lt;/span&gt;&lt;span class="sc0"&gt; &lt;/span&gt;&lt;span class="sc10"&gt;+&lt;/span&gt;&lt;span class="sc0"&gt;  &lt;/span&gt;&lt;span class="sc11"&gt;fileName&lt;/span&gt;&lt;span class="sc10"&gt;,&lt;/span&gt;&lt;span class="sc11"&gt;Encoding&lt;/span&gt;&lt;span class="sc10"&gt;.&lt;/span&gt;&lt;span class="sc11"&gt;UTF8&lt;/span&gt;&lt;span class="sc10"&gt;);&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;               &lt;/span&gt;&lt;span class="sc11"&gt;tw&lt;/span&gt;&lt;span class="sc10"&gt;.&lt;/span&gt;&lt;span class="sc11"&gt;Formatting&lt;/span&gt;&lt;span class="sc0"&gt; &lt;/span&gt;&lt;span class="sc10"&gt;=&lt;/span&gt;&lt;span class="sc0"&gt; &lt;/span&gt;&lt;span class="sc11"&gt;Formatting&lt;/span&gt;&lt;span class="sc10"&gt;.&lt;/span&gt;&lt;span class="sc11"&gt;Indented&lt;/span&gt;&lt;span class="sc10"&gt;;&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;               &lt;/span&gt;&lt;span class="sc11"&gt;tw&lt;/span&gt;&lt;span class="sc10"&gt;.&lt;/span&gt;&lt;span class="sc11"&gt;WriteStartDocument&lt;/span&gt;&lt;span class="sc10"&gt;();&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;               &lt;/span&gt;&lt;span class="sc11"&gt;tw&lt;/span&gt;&lt;span class="sc10"&gt;.&lt;/span&gt;&lt;span class="sc11"&gt;WriteStartElement&lt;/span&gt;&lt;span class="sc10"&gt;(&lt;/span&gt;&lt;span class="sc6"&gt;"BankStatement"&lt;/span&gt;&lt;span class="sc10"&gt;);&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;               &lt;/span&gt;&lt;span class="sc11"&gt;tw&lt;/span&gt;&lt;span class="sc10"&gt;.&lt;/span&gt;&lt;span class="sc11"&gt;WriteElementString&lt;/span&gt;&lt;span class="sc10"&gt;(&lt;/span&gt;&lt;span class="sc6"&gt;"Date"&lt;/span&gt;&lt;span class="sc10"&gt;,&lt;/span&gt;&lt;span class="sc11"&gt;Fecha&lt;/span&gt;&lt;span class="sc10"&gt;);&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;               &lt;/span&gt;&lt;span class="sc11"&gt;tw&lt;/span&gt;&lt;span class="sc10"&gt;.&lt;/span&gt;&lt;span class="sc11"&gt;WriteElementString&lt;/span&gt;&lt;span class="sc10"&gt;(&lt;/span&gt;&lt;span class="sc6"&gt;"Bank"&lt;/span&gt;&lt;span class="sc10"&gt;,&lt;/span&gt;&lt;span class="sc11"&gt;Banco&lt;/span&gt;&lt;span class="sc10"&gt;);&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;               &lt;/span&gt;&lt;span class="sc11"&gt;tw&lt;/span&gt;&lt;span class="sc10"&gt;.&lt;/span&gt;&lt;span class="sc11"&gt;WriteElementString&lt;/span&gt;&lt;span class="sc10"&gt;(&lt;/span&gt;&lt;span class="sc6"&gt;"MovementType"&lt;/span&gt;&lt;span class="sc10"&gt;,&lt;/span&gt;&lt;span class="sc11"&gt;TipoMovimiento&lt;/span&gt;&lt;span class="sc10"&gt;);&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;               &lt;/span&gt;&lt;span class="sc11"&gt;tw&lt;/span&gt;&lt;span class="sc10"&gt;.&lt;/span&gt;&lt;span class="sc11"&gt;WriteElementString&lt;/span&gt;&lt;span class="sc10"&gt;(&lt;/span&gt;&lt;span class="sc6"&gt;"Description"&lt;/span&gt;&lt;span class="sc10"&gt;,&lt;/span&gt;&lt;span class="sc11"&gt;Descripcion&lt;/span&gt;&lt;span class="sc10"&gt;);&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;               &lt;/span&gt;&lt;span class="sc11"&gt;tw&lt;/span&gt;&lt;span class="sc10"&gt;.&lt;/span&gt;&lt;span class="sc11"&gt;WriteElementString&lt;/span&gt;&lt;span class="sc10"&gt;(&lt;/span&gt;&lt;span class="sc6"&gt;"Amount"&lt;/span&gt;&lt;span class="sc10"&gt;,&lt;/span&gt;&lt;span class="sc11"&gt;Monto&lt;/span&gt;&lt;span class="sc10"&gt;);&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;               &lt;/span&gt;&lt;span class="sc11"&gt;tw&lt;/span&gt;&lt;span class="sc10"&gt;.&lt;/span&gt;&lt;span class="sc11"&gt;WriteEndDocument&lt;/span&gt;&lt;span class="sc10"&gt;();&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;               &lt;/span&gt;&lt;span class="sc11"&gt;tw&lt;/span&gt;&lt;span class="sc10"&gt;.&lt;/span&gt;&lt;span class="sc11"&gt;Flush&lt;/span&gt;&lt;span class="sc10"&gt;();&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;               &lt;/span&gt;&lt;span class="sc11"&gt;tw&lt;/span&gt;&lt;span class="sc10"&gt;.&lt;/span&gt;&lt;span class="sc11"&gt;Close&lt;/span&gt;&lt;span class="sc10"&gt;();&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;           &lt;/span&gt;&lt;span class="sc10"&gt;}&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;           &lt;/span&gt;&lt;span class="sc5"&gt;catch&lt;/span&gt;&lt;span class="sc10"&gt;{&lt;/span&gt;&lt;span class="sc0"&gt; &lt;/span&gt;&lt;span class="sc5"&gt;throw&lt;/span&gt;&lt;span class="sc10"&gt;;}&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;       &lt;/span&gt;&lt;span class="sc10"&gt;}&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;       &lt;/span&gt;&lt;br /&gt;&lt;br&gt;&lt;br /&gt;El método de la aplicación para invocar el método del ensamblado es el siguiente:&lt;br /&gt;&lt;br&gt;&lt;br /&gt;&lt;span class="sc5"&gt;void&lt;/span&gt;&lt;span class="sc0"&gt; &lt;/span&gt;&lt;span class="sc11"&gt;BtnGenerarClick&lt;/span&gt;&lt;span class="sc10"&gt;(&lt;/span&gt;&lt;span class="sc5"&gt;object&lt;/span&gt;&lt;span class="sc0"&gt; &lt;/span&gt;&lt;span class="sc11"&gt;sender&lt;/span&gt;&lt;span class="sc10"&gt;,&lt;/span&gt;&lt;span class="sc0"&gt; &lt;/span&gt;&lt;span class="sc11"&gt;EventArgs&lt;/span&gt;&lt;span class="sc0"&gt; &lt;/span&gt;&lt;span class="sc11"&gt;e&lt;/span&gt;&lt;span class="sc10"&gt;)&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span class="sc10"&gt;{&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;            &lt;/span&gt;&lt;span class="sc5"&gt;try&lt;/span&gt;&lt;span class="sc10"&gt;{&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;            &lt;/span&gt;&lt;span class="sc11"&gt;Ensamblado1&lt;/span&gt;&lt;span class="sc0"&gt; &lt;/span&gt;&lt;span class="sc11"&gt;ensamblado1&lt;/span&gt;&lt;span class="sc0"&gt; &lt;/span&gt;&lt;span class="sc10"&gt;=&lt;/span&gt;&lt;span class="sc0"&gt; &lt;/span&gt;&lt;span class="sc5"&gt;new&lt;/span&gt;&lt;span class="sc0"&gt; &lt;/span&gt;&lt;span class="sc11"&gt;Ensamblado1&lt;/span&gt;&lt;span class="sc10"&gt;();&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;            &lt;/span&gt;&lt;span class="sc11"&gt;ensamblado1&lt;/span&gt;&lt;span class="sc10"&gt;.&lt;/span&gt;&lt;span class="sc11"&gt;Banco&lt;/span&gt;&lt;span class="sc0"&gt; &lt;/span&gt;&lt;span class="sc10"&gt;=&lt;/span&gt;&lt;span class="sc0"&gt; &lt;/span&gt;&lt;span class="sc11"&gt;cbBanco&lt;/span&gt;&lt;span class="sc10"&gt;.&lt;/span&gt;&lt;span class="sc11"&gt;SelectedItem&lt;/span&gt;&lt;span class="sc10"&gt;.&lt;/span&gt;&lt;span class="sc11"&gt;ToString&lt;/span&gt;&lt;span class="sc10"&gt;();&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;            &lt;/span&gt;&lt;span class="sc11"&gt;ensamblado1&lt;/span&gt;&lt;span class="sc10"&gt;.&lt;/span&gt;&lt;span class="sc11"&gt;TipoMovimiento&lt;/span&gt;&lt;span class="sc0"&gt; &lt;/span&gt;&lt;span class="sc10"&gt;=&lt;/span&gt;&lt;span class="sc0"&gt; &lt;/span&gt;&lt;span class="sc11"&gt;cbTipoMovimiento&lt;/span&gt;&lt;span class="sc10"&gt;.&lt;/span&gt;&lt;span class="sc11"&gt;SelectedItem&lt;/span&gt;&lt;span class="sc10"&gt;.&lt;/span&gt;&lt;span class="sc11"&gt;ToString&lt;/span&gt;&lt;span class="sc10"&gt;();&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;            &lt;/span&gt;&lt;span class="sc11"&gt;ensamblado1&lt;/span&gt;&lt;span class="sc10"&gt;.&lt;/span&gt;&lt;span class="sc11"&gt;Descripcion&lt;/span&gt;&lt;span class="sc0"&gt; &lt;/span&gt;&lt;span class="sc10"&gt;=&lt;/span&gt;&lt;span class="sc0"&gt; &lt;/span&gt;&lt;span class="sc11"&gt;txtDescripcion&lt;/span&gt;&lt;span class="sc10"&gt;.&lt;/span&gt;&lt;span class="sc11"&gt;Text&lt;/span&gt;&lt;span class="sc10"&gt;;&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;            &lt;/span&gt;&lt;span class="sc11"&gt;ensamblado1&lt;/span&gt;&lt;span class="sc10"&gt;.&lt;/span&gt;&lt;span class="sc11"&gt;Monto&lt;/span&gt;&lt;span class="sc0"&gt; &lt;/span&gt;&lt;span class="sc10"&gt;=&lt;/span&gt;&lt;span class="sc0"&gt; &lt;/span&gt;&lt;span class="sc11"&gt;txtMonto&lt;/span&gt;&lt;span class="sc10"&gt;.&lt;/span&gt;&lt;span class="sc11"&gt;Text&lt;/span&gt;&lt;span class="sc10"&gt;;&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;            &lt;/span&gt;&lt;span class="sc11"&gt;ensamblado1&lt;/span&gt;&lt;span class="sc10"&gt;.&lt;/span&gt;&lt;span class="sc11"&gt;WriteBank&lt;/span&gt;&lt;span class="sc10"&gt;(&lt;/span&gt;&lt;span class="sc5"&gt;string&lt;/span&gt;&lt;span class="sc10"&gt;.&lt;/span&gt;&lt;span class="sc11"&gt;Format&lt;/span&gt;&lt;span class="sc10"&gt;(&lt;/span&gt;&lt;span class="sc6"&gt;"{0}{1}.xml"&lt;/span&gt;&lt;span class="sc10"&gt;,&lt;/span&gt;&lt;span class="sc11"&gt;ensamblado1&lt;/span&gt;&lt;span class="sc10"&gt;.&lt;/span&gt;&lt;span class="sc11"&gt;Banco&lt;/span&gt;&lt;span class="sc10"&gt;,&lt;/span&gt;&lt;span class="sc11"&gt;ensamblado1&lt;/span&gt;&lt;span class="sc10"&gt;.&lt;/span&gt;&lt;span class="sc11"&gt;Fecha&lt;/span&gt;&lt;span class="sc10"&gt;.&lt;/span&gt;&lt;span class="sc11"&gt;Replace&lt;/span&gt;&lt;span class="sc10"&gt;(&lt;/span&gt;&lt;span class="sc6"&gt;"/"&lt;/span&gt;&lt;span class="sc10"&gt;,&lt;/span&gt;&lt;span class="sc6"&gt;"_"&lt;/span&gt;&lt;span class="sc10"&gt;)));&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;            &lt;/span&gt;&lt;span class="sc10"&gt;}&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;            &lt;/span&gt;&lt;span class="sc5"&gt;catch&lt;/span&gt;&lt;span class="sc10"&gt;(&lt;/span&gt;&lt;span class="sc11"&gt;ApplicationException&lt;/span&gt;&lt;span class="sc0"&gt; &lt;/span&gt;&lt;span class="sc11"&gt;appex&lt;/span&gt;&lt;span class="sc10"&gt;){&lt;/span&gt;&lt;span class="sc0"&gt; &lt;/span&gt;&lt;span class="sc11"&gt;MessageBox&lt;/span&gt;&lt;span class="sc10"&gt;.&lt;/span&gt;&lt;span class="sc11"&gt;Show&lt;/span&gt;&lt;span class="sc10"&gt;(&lt;/span&gt;&lt;span class="sc11"&gt;appex&lt;/span&gt;&lt;span class="sc10"&gt;.&lt;/span&gt;&lt;span class="sc11"&gt;Message&lt;/span&gt;&lt;span class="sc10"&gt;);}&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;            &lt;/span&gt;&lt;span class="sc5"&gt;catch&lt;/span&gt;&lt;span class="sc10"&gt;(&lt;/span&gt;&lt;span class="sc11"&gt;Exception&lt;/span&gt;&lt;span class="sc0"&gt; &lt;/span&gt;&lt;span class="sc11"&gt;ex&lt;/span&gt;&lt;span class="sc10"&gt;){&lt;/span&gt;&lt;span class="sc11"&gt;MessageBox&lt;/span&gt;&lt;span class="sc10"&gt;.&lt;/span&gt;&lt;span class="sc11"&gt;Show&lt;/span&gt;&lt;span class="sc10"&gt;(&lt;/span&gt;&lt;span class="sc11"&gt;ex&lt;/span&gt;&lt;span class="sc10"&gt;.&lt;/span&gt;&lt;span class="sc11"&gt;Message&lt;/span&gt;&lt;span class="sc10"&gt;);}&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span class="sc10"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br&gt;&lt;br /&gt;La aplicación es utilizada sin ningún problema hasta que varios archivos de estados de cuenta no coinciden al utilizarlos en la contabilidad, se encuentran localizados en una ubicación que no es la ruta predeterminada y el sistema operativo no indica ninguna excepción en las bitácoras de seguridad.&lt;br /&gt;Supongamos que un usuario autenticado construye un programa malintencionado que ejecuta el método de nuestro ensamblado para escribir los estados de cuenta afuera de la carpeta predeterminada un código como el siguiente:&lt;br /&gt;&lt;br&gt;&lt;br /&gt;&lt;span class="sc5"&gt;using&lt;/span&gt;&lt;span class="sc0"&gt; &lt;/span&gt;&lt;span class="sc11"&gt;System&lt;/span&gt;&lt;span class="sc10"&gt;;&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="sc5"&gt;namespace&lt;/span&gt;&lt;span class="sc0"&gt; &lt;/span&gt;&lt;span class="sc11"&gt;Godel&lt;/span&gt;&lt;span class="sc10"&gt;.&lt;/span&gt;&lt;span class="sc11"&gt;Posts&lt;/span&gt;&lt;span class="sc0"&gt; &lt;/span&gt;&lt;span class="sc10"&gt;{&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;    &lt;/span&gt;&lt;span class="sc5"&gt;class&lt;/span&gt;&lt;span class="sc0"&gt; &lt;/span&gt;&lt;span class="sc11"&gt;SinPermiso&lt;/span&gt;&lt;span class="sc0"&gt; &lt;/span&gt;&lt;span class="sc10"&gt;{&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span class="sc10"&gt;[&lt;/span&gt;&lt;span class="sc11"&gt;STAThread&lt;/span&gt;&lt;span class="sc10"&gt;]&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span class="sc5"&gt;static&lt;/span&gt;&lt;span class="sc0"&gt; &lt;/span&gt;&lt;span class="sc5"&gt;void&lt;/span&gt;&lt;span class="sc0"&gt; &lt;/span&gt;&lt;span class="sc11"&gt;Main&lt;/span&gt;&lt;span class="sc10"&gt;()&lt;/span&gt;&lt;span class="sc0"&gt; &lt;/span&gt;&lt;span class="sc10"&gt;{&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;            &lt;/span&gt;&lt;span class="sc5"&gt;try&lt;/span&gt;&lt;span class="sc0"&gt; &lt;/span&gt;&lt;span class="sc10"&gt;{&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;                &lt;/span&gt;&lt;span class="sc11"&gt;Console&lt;/span&gt;&lt;span class="sc10"&gt;.&lt;/span&gt;&lt;span class="sc11"&gt;WriteLine&lt;/span&gt;&lt;span class="sc10"&gt;(&lt;/span&gt;&lt;span class="sc6"&gt;"Creando estado de cuenta..."&lt;/span&gt;&lt;span class="sc10"&gt;);&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;                &lt;/span&gt;&lt;span class="sc11"&gt;Ensamblado1&lt;/span&gt;&lt;span class="sc0"&gt; &lt;/span&gt;&lt;span class="sc11"&gt;ensamblado1&lt;/span&gt;&lt;span class="sc0"&gt; &lt;/span&gt;&lt;span class="sc10"&gt;=&lt;/span&gt;&lt;span class="sc0"&gt; &lt;/span&gt;&lt;span class="sc5"&gt;new&lt;/span&gt;&lt;span class="sc0"&gt; &lt;/span&gt;&lt;span class="sc11"&gt;Ensamblado1&lt;/span&gt;&lt;span class="sc10"&gt;();&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;                &lt;/span&gt;&lt;span class="sc11"&gt;ensamblado1&lt;/span&gt;&lt;span class="sc10"&gt;.&lt;/span&gt;&lt;span class="sc11"&gt;Banco&lt;/span&gt;&lt;span class="sc0"&gt; &lt;/span&gt;&lt;span class="sc10"&gt;=&lt;/span&gt;&lt;span class="sc0"&gt; &lt;/span&gt;&lt;span class="sc6"&gt;"BankHack"&lt;/span&gt;&lt;span class="sc10"&gt;;&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;                &lt;/span&gt;&lt;span class="sc11"&gt;ensamblado1&lt;/span&gt;&lt;span class="sc10"&gt;.&lt;/span&gt;&lt;span class="sc11"&gt;Descripcion&lt;/span&gt;&lt;span class="sc0"&gt; &lt;/span&gt;&lt;span class="sc10"&gt;=&lt;/span&gt;&lt;span class="sc0"&gt; &lt;/span&gt;&lt;span class="sc6"&gt;"Deposito para pagar todas mis deudas"&lt;/span&gt;&lt;span class="sc10"&gt;;&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;                &lt;/span&gt;&lt;span class="sc11"&gt;ensamblado1&lt;/span&gt;&lt;span class="sc10"&gt;.&lt;/span&gt;&lt;span class="sc11"&gt;Monto&lt;/span&gt;&lt;span class="sc0"&gt; &lt;/span&gt;&lt;span class="sc10"&gt;=&lt;/span&gt;&lt;span class="sc0"&gt; &lt;/span&gt;&lt;span class="sc6"&gt;"10000"&lt;/span&gt;&lt;span class="sc10"&gt;;&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;                &lt;/span&gt;&lt;span class="sc11"&gt;ensamblado1&lt;/span&gt;&lt;span class="sc10"&gt;.&lt;/span&gt;&lt;span class="sc11"&gt;TipoMovimiento&lt;/span&gt;&lt;span class="sc0"&gt; &lt;/span&gt;&lt;span class="sc10"&gt;=&lt;/span&gt;&lt;span class="sc0"&gt; &lt;/span&gt;&lt;span class="sc6"&gt;"Deposito"&lt;/span&gt;&lt;span class="sc10"&gt;;&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;                &lt;/span&gt;&lt;span class="sc11"&gt;ensamblado1&lt;/span&gt;&lt;span class="sc10"&gt;.&lt;/span&gt;&lt;span class="sc11"&gt;WriteBank&lt;/span&gt;&lt;span class="sc10"&gt;(&lt;/span&gt;&lt;span class="sc5"&gt;string&lt;/span&gt;&lt;span class="sc10"&gt;.&lt;/span&gt;&lt;span class="sc11"&gt;Format&lt;/span&gt;&lt;span class="sc10"&gt;(&lt;/span&gt;&lt;span class="sc6"&gt;"..\\{0}{1}.xml"&lt;/span&gt;&lt;span class="sc10"&gt;,&lt;/span&gt;&lt;span class="sc11"&gt;ensamblado1&lt;/span&gt;&lt;span class="sc10"&gt;.&lt;/span&gt;&lt;span class="sc11"&gt;Banco&lt;/span&gt;&lt;span class="sc10"&gt;,&lt;/span&gt;&lt;span class="sc11"&gt;ensamblado1&lt;/span&gt;&lt;span class="sc10"&gt;.&lt;/span&gt;&lt;span class="sc11"&gt;Fecha&lt;/span&gt;&lt;span class="sc10"&gt;.&lt;/span&gt;&lt;span class="sc11"&gt;Replace&lt;/span&gt;&lt;span class="sc10"&gt;(&lt;/span&gt;&lt;span class="sc6"&gt;"/"&lt;/span&gt;&lt;span class="sc10"&gt;,&lt;/span&gt;&lt;span class="sc6"&gt;"_"&lt;/span&gt;&lt;span class="sc10"&gt;)));&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;                &lt;/span&gt;&lt;span class="sc11"&gt;Console&lt;/span&gt;&lt;span class="sc10"&gt;.&lt;/span&gt;&lt;span class="sc11"&gt;WriteLine&lt;/span&gt;&lt;span class="sc10"&gt;(&lt;/span&gt;&lt;span class="sc6"&gt;"Estado de cuenta creado"&lt;/span&gt;&lt;span class="sc10"&gt;);&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;            &lt;/span&gt;&lt;span class="sc10"&gt;}&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;            &lt;/span&gt;&lt;span class="sc5"&gt;catch&lt;/span&gt;&lt;span class="sc10"&gt;(&lt;/span&gt;&lt;span class="sc11"&gt;Exception&lt;/span&gt;&lt;span class="sc0"&gt; &lt;/span&gt;&lt;span class="sc11"&gt;ex&lt;/span&gt;&lt;span class="sc10"&gt;){&lt;/span&gt;&lt;span class="sc0"&gt; &lt;/span&gt;&lt;span class="sc11"&gt;Console&lt;/span&gt;&lt;span class="sc10"&gt;.&lt;/span&gt;&lt;span class="sc11"&gt;WriteLine&lt;/span&gt;&lt;span class="sc10"&gt;(&lt;/span&gt;&lt;span class="sc11"&gt;ex&lt;/span&gt;&lt;span class="sc10"&gt;.&lt;/span&gt;&lt;span class="sc11"&gt;StackTrace&lt;/span&gt;&lt;span class="sc10"&gt;);}&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;            &lt;/span&gt;&lt;span class="sc11"&gt;Console&lt;/span&gt;&lt;span class="sc10"&gt;.&lt;/span&gt;&lt;span class="sc11"&gt;Read&lt;/span&gt;&lt;span class="sc10"&gt;();&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span class="sc10"&gt;}&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;    &lt;/span&gt;&lt;span class="sc10"&gt;}&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="sc10"&gt;}&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Para compilar este código usamos:&lt;br /&gt;&lt;tt&gt;&lt;b&gt;csc /r:Ensamblado1.dll SinPermiso.cs&lt;/b&gt;&lt;/tt&gt;&lt;br /&gt;Con la opción &lt;b&gt;/r&lt;/b&gt; le indicamos al compilador, que haga referencia al metadata del ensamblado indicado, en este caso al Ensamblado1 donde se encuentra el método para generar estados de cuenta.&lt;br /&gt;Al revisar los códigos observamos que el método esta implementado para generar los archivos debajo de una carpeta llamada [Banks] en la partición [C:\\] y que la protección de los valores del ensamblado dependerá de las validaciones que implementemos en el formulario de la aplicación, mas no del ensamblado mismo, por eso al invocar el método y pasar le la cadena con una secuencia ..\\ indicamos al ensamblado que escriba el archivo un nivel arriba.&lt;br /&gt;&lt;br /&gt;Más que buscar un culpable a nivel usuario, la pregunta se plantea a nivel código:&lt;br /&gt;¿como podemos evitar que el código realice operaciones para las que no fue diseñado?&lt;br /&gt;La respuesta sin duda alguna es uno de los objetivos del CAS.&lt;br /&gt;Usando CAS podemos evitar que un usuario o un proceso autenticado utilice los métodos del ensamblado para realizar acciones que no están consideradas en la lógica del programa.&lt;br /&gt;Para lograr ese objetivo CAS utiliza permisos encapsulados como objetos que pueden ser usados a nivel de métodos o ensamblados, estos permisos pueden ser de manera declarativa usados  como o como atributos dentro del código, en este ejemplo usaremos un permiso de forma declarativa para nuestro método.&lt;br /&gt;&lt;span class="sc10"&gt;[&lt;/span&gt;&lt;span class="sc11"&gt;FileIOPermission&lt;/span&gt;&lt;span class="sc10"&gt;(&lt;/span&gt;&lt;span class="sc11"&gt;SecurityAction&lt;/span&gt;&lt;span class="sc10"&gt;.&lt;/span&gt;&lt;span class="sc11"&gt;PermitOnly&lt;/span&gt;&lt;span class="sc10"&gt;,&lt;/span&gt;&lt;span class="sc11"&gt;Write&lt;/span&gt;&lt;span class="sc10"&gt;=&lt;/span&gt;&lt;span class="sc6"&gt;"C:\\Banks"&lt;/span&gt;&lt;span class="sc10"&gt;)]&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;br /&gt;  &lt;span class="sc5"&gt;public&lt;/span&gt;&lt;span class="sc0"&gt; &lt;/span&gt;&lt;span class="sc5"&gt;void&lt;/span&gt;&lt;span class="sc0"&gt; &lt;/span&gt;&lt;span class="sc11"&gt;WriteBank&lt;/span&gt;&lt;span class="sc10"&gt;(&lt;/span&gt;&lt;span class="sc5"&gt;string&lt;/span&gt;&lt;span class="sc0"&gt; &lt;/span&gt;&lt;span class="sc11"&gt;fileName&lt;/span&gt;&lt;span class="sc10"&gt;)&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span class="sc10"&gt;{&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;            &lt;/span&gt;&lt;span class="sc5"&gt;try&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;            &lt;/span&gt;&lt;span class="sc10"&gt;{&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;                &lt;/span&gt;&lt;span class="sc5"&gt;string&lt;/span&gt;&lt;span class="sc0"&gt; &lt;/span&gt;&lt;span class="sc11"&gt;rootpath&lt;/span&gt;&lt;span class="sc0"&gt; &lt;/span&gt;&lt;span class="sc10"&gt;=&lt;/span&gt;&lt;span class="sc0"&gt; &lt;/span&gt;&lt;span class="sc5"&gt;string&lt;/span&gt;&lt;span class="sc10"&gt;.&lt;/span&gt;&lt;span class="sc11"&gt;Format&lt;/span&gt;&lt;span class="sc10"&gt;(&lt;/span&gt;&lt;span class="sc13"&gt;@"C:{0}Banks{0}"&lt;/span&gt;&lt;span class="sc10"&gt;,&lt;/span&gt;&lt;span class="sc11"&gt;Path&lt;/span&gt;&lt;span class="sc10"&gt;.&lt;/span&gt;&lt;span class="sc11"&gt;DirectorySeparatorChar&lt;/span&gt;&lt;span class="sc10"&gt;);&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;                &lt;/span&gt;&lt;span class="sc5"&gt;if&lt;/span&gt;&lt;span class="sc10"&gt;(!&lt;/span&gt;&lt;span class="sc11"&gt;Directory&lt;/span&gt;&lt;span class="sc10"&gt;.&lt;/span&gt;&lt;span class="sc11"&gt;Exists&lt;/span&gt;&lt;span class="sc10"&gt;(&lt;/span&gt;&lt;span class="sc11"&gt;rootpath&lt;/span&gt;&lt;span class="sc10"&gt;))&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;                    &lt;/span&gt;&lt;span class="sc11"&gt;Directory&lt;/span&gt;&lt;span class="sc10"&gt;.&lt;/span&gt;&lt;span class="sc11"&gt;CreateDirectory&lt;/span&gt;&lt;span class="sc10"&gt;(&lt;/span&gt;&lt;span class="sc11"&gt;rootpath&lt;/span&gt;&lt;span class="sc10"&gt;);&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;                &lt;/span&gt;&lt;span class="sc11"&gt;XmlTextWriter&lt;/span&gt;&lt;span class="sc0"&gt; &lt;/span&gt;&lt;span class="sc11"&gt;tw&lt;/span&gt;&lt;span class="sc0"&gt; &lt;/span&gt;&lt;span class="sc10"&gt;=&lt;/span&gt;&lt;span class="sc0"&gt; &lt;/span&gt;&lt;span class="sc5"&gt;new&lt;/span&gt;&lt;span class="sc0"&gt; &lt;/span&gt;&lt;span class="sc11"&gt;XmlTextWriter&lt;/span&gt;&lt;span class="sc10"&gt;(&lt;/span&gt;&lt;span class="sc11"&gt;rootpath&lt;/span&gt;&lt;span class="sc0"&gt; &lt;/span&gt;&lt;span class="sc10"&gt;+&lt;/span&gt;&lt;span class="sc0"&gt;  &lt;/span&gt;&lt;span class="sc11"&gt;fileName&lt;/span&gt;&lt;span class="sc10"&gt;,&lt;/span&gt;&lt;span class="sc11"&gt;Encoding&lt;/span&gt;&lt;span class="sc10"&gt;.&lt;/span&gt;&lt;span class="sc11"&gt;UTF8&lt;/span&gt;&lt;span class="sc10"&gt;);&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;                &lt;/span&gt;&lt;span class="sc11"&gt;tw&lt;/span&gt;&lt;span class="sc10"&gt;.&lt;/span&gt;&lt;span class="sc11"&gt;Formatting&lt;/span&gt;&lt;span class="sc0"&gt; &lt;/span&gt;&lt;span class="sc10"&gt;=&lt;/span&gt;&lt;span class="sc0"&gt; &lt;/span&gt;&lt;span class="sc11"&gt;Formatting&lt;/span&gt;&lt;span class="sc10"&gt;.&lt;/span&gt;&lt;span class="sc11"&gt;Indented&lt;/span&gt;&lt;span class="sc10"&gt;;&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;                &lt;/span&gt;&lt;span class="sc11"&gt;tw&lt;/span&gt;&lt;span class="sc10"&gt;.&lt;/span&gt;&lt;span class="sc11"&gt;WriteStartDocument&lt;/span&gt;&lt;span class="sc10"&gt;();&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;                &lt;/span&gt;&lt;span class="sc11"&gt;tw&lt;/span&gt;&lt;span class="sc10"&gt;.&lt;/span&gt;&lt;span class="sc11"&gt;WriteStartElement&lt;/span&gt;&lt;span class="sc10"&gt;(&lt;/span&gt;&lt;span class="sc6"&gt;"BankStatement"&lt;/span&gt;&lt;span class="sc10"&gt;);&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;                &lt;/span&gt;&lt;span class="sc11"&gt;tw&lt;/span&gt;&lt;span class="sc10"&gt;.&lt;/span&gt;&lt;span class="sc11"&gt;WriteElementString&lt;/span&gt;&lt;span class="sc10"&gt;(&lt;/span&gt;&lt;span class="sc6"&gt;"Date"&lt;/span&gt;&lt;span class="sc10"&gt;,&lt;/span&gt;&lt;span class="sc11"&gt;Fecha&lt;/span&gt;&lt;span class="sc10"&gt;);&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;                &lt;/span&gt;&lt;span class="sc11"&gt;tw&lt;/span&gt;&lt;span class="sc10"&gt;.&lt;/span&gt;&lt;span class="sc11"&gt;WriteElementString&lt;/span&gt;&lt;span class="sc10"&gt;(&lt;/span&gt;&lt;span class="sc6"&gt;"Bank"&lt;/span&gt;&lt;span class="sc10"&gt;,&lt;/span&gt;&lt;span class="sc11"&gt;Banco&lt;/span&gt;&lt;span class="sc10"&gt;);&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;                &lt;/span&gt;&lt;span class="sc11"&gt;tw&lt;/span&gt;&lt;span class="sc10"&gt;.&lt;/span&gt;&lt;span class="sc11"&gt;WriteElementString&lt;/span&gt;&lt;span class="sc10"&gt;(&lt;/span&gt;&lt;span class="sc6"&gt;"MovementType"&lt;/span&gt;&lt;span class="sc10"&gt;,&lt;/span&gt;&lt;span class="sc11"&gt;TipoMovimiento&lt;/span&gt;&lt;span class="sc10"&gt;);&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;                &lt;/span&gt;&lt;span class="sc11"&gt;tw&lt;/span&gt;&lt;span class="sc10"&gt;.&lt;/span&gt;&lt;span class="sc11"&gt;WriteElementString&lt;/span&gt;&lt;span class="sc10"&gt;(&lt;/span&gt;&lt;span class="sc6"&gt;"Description"&lt;/span&gt;&lt;span class="sc10"&gt;,&lt;/span&gt;&lt;span class="sc11"&gt;Descripcion&lt;/span&gt;&lt;span class="sc10"&gt;);&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;                &lt;/span&gt;&lt;span class="sc11"&gt;tw&lt;/span&gt;&lt;span class="sc10"&gt;.&lt;/span&gt;&lt;span class="sc11"&gt;WriteElementString&lt;/span&gt;&lt;span class="sc10"&gt;(&lt;/span&gt;&lt;span class="sc6"&gt;"Amount"&lt;/span&gt;&lt;span class="sc10"&gt;,&lt;/span&gt;&lt;span class="sc11"&gt;Monto&lt;/span&gt;&lt;span class="sc10"&gt;);&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;                &lt;/span&gt;&lt;span class="sc11"&gt;tw&lt;/span&gt;&lt;span class="sc10"&gt;.&lt;/span&gt;&lt;span class="sc11"&gt;WriteEndDocument&lt;/span&gt;&lt;span class="sc10"&gt;();&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;                &lt;/span&gt;&lt;span class="sc11"&gt;tw&lt;/span&gt;&lt;span class="sc10"&gt;.&lt;/span&gt;&lt;span class="sc11"&gt;Flush&lt;/span&gt;&lt;span class="sc10"&gt;();&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;                &lt;/span&gt;&lt;span class="sc11"&gt;tw&lt;/span&gt;&lt;span class="sc10"&gt;.&lt;/span&gt;&lt;span class="sc11"&gt;Close&lt;/span&gt;&lt;span class="sc10"&gt;();&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;            &lt;/span&gt;&lt;span class="sc10"&gt;}&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;            &lt;/span&gt;&lt;span class="sc5"&gt;catch&lt;/span&gt;&lt;span class="sc10"&gt;{&lt;/span&gt;&lt;span class="sc0"&gt; &lt;/span&gt;&lt;span class="sc5"&gt;throw&lt;/span&gt;&lt;span class="sc10"&gt;;}&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span class="sc10"&gt;}&lt;/span&gt;&lt;br /&gt;Los permisos representan acciones que son revisadas cada vez que el CLR carga el ensamblado para ejecutarse, estos permisos son controlados por el CAS.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;UIPermission&lt;/b&gt;   Controla la manipulación a la interfaz de usuario y el portapapeles.&lt;br /&gt;&lt;b&gt;ResourcePermissionBase&lt;/b&gt; Controla el acceso a los recursos de Windows&lt;br /&gt;&lt;b&gt;RegistryPermission&lt;/b&gt;  Controla el acceso al Registro de Windows&lt;br /&gt;&lt;b&gt;ReflectionPermission&lt;/b&gt;  Controla el acceso a la funcionalidad de la reflexión proporcionada por el CLR&lt;br /&gt;&lt;b&gt;IsolatedStoragePermission&lt;/b&gt; Controla el acceso a  isolated storage&lt;br /&gt;&lt;b&gt;FileIOPermission&lt;/b&gt;  Controla el acceso de escritura o lectura al disco duro&lt;br /&gt;&lt;b&gt;FileDialogPermission&lt;/b&gt;  Controla el acceso a archivos o carpetas.&lt;br /&gt;&lt;b&gt;EnviromentPermission&lt;/b&gt;  Controla el acceso a leer, modificar y crear variables de ambiente.&lt;br /&gt;&lt;br /&gt;Si ejecutamos nuevamente el código para escribir los estados de cuenta fuera de la carpeta predeterminada con el ensamblado modificado, se mostrará el siguiente error.&lt;br /&gt;&lt;br /&gt;&lt;img src="http://humansharp.com/picture_library/post5/msg.jpg" border="0" alt="" width="500px" height="94"/&gt;&lt;br /&gt;&lt;br /&gt;Ahora nuestro ensamblado esta protegido por la seguridad del CAS y no depende de la validación que implementen las clases que invoquen sus métodos.&lt;br /&gt;&lt;br /&gt;Para habilitar o des habilitar  la seguridad del CAS se utiliza la herramienta caspol con el siguiente argumento:&lt;br /&gt;&lt;tt&gt;&lt;b&gt;caspol -s on&lt;/b&gt;&lt;/tt&gt;&lt;br /&gt;Siempre es recomendable habilitar la seguridad del CAS.&lt;br /&gt;Para compilar la aplicación:&lt;br /&gt;&lt;tt&gt;&lt;b&gt;csc /r:Ensamblado1.dll EstadosCuenta.cs EstadosCuenta.Designer.cs&lt;/b&gt;&lt;/tt&gt;&lt;br /&gt;&lt;br&gt;&lt;br /&gt;&lt;a href="http://www.humansharp.com/Code/EstadosCuenta.zip"&gt;&lt;img src="http://www.humansharp.com/picture_library/dw.jpg" border="0"&gt;&amp;nbsp;Descarga el código fuente&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6494419861240446187-4804946079835069298?l=xomalli.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/4804946079835069298'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/4804946079835069298'/><link rel='alternate' type='text/html' href='http://xomalli.blogspot.com/2009/03/code-access-security-cas-la-seguridad.html' title='Code Access Security CAS, la seguridad en el código'/><author><name>Martín Márquez</name><uri>http://www.blogger.com/profile/10939957618126542300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_j4WRR9G9bfY/SV2_nw3UxeI/AAAAAAAAAAM/nT3SYp94IHo/s1600-R/photo.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-6494419861240446187.post-6403710674161376111</id><published>2009-02-23T21:46:00.000-08:00</published><updated>2009-05-29T21:24:22.884-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Windows'/><title type='text'>70-340 Implementando seguridad de aplicaciones C#</title><content type='html'>El día sábado presente el examen de certificación "70-340 Implementing Security applications with C#" que trata sobre seguridad de las aplicaciones .NET independientemente si son de tipo escritorio,Web o de consola, los temas igualmente aplican para las aplicaciones desarrolladas con Mono.&lt;br /&gt;&lt;br /&gt;Este examen esta basado en el FrameWork .NET 1.1 (Visual Studio 2003, Mono 1.1) por lo que los temas y su ejemplos los ejecuté en mi vieja portátil que conserva este ambiente.&lt;br /&gt;&lt;br /&gt;Entre los temas que trata están:&lt;br /&gt;&lt;br /&gt;- CAS (Code Access Security)&lt;br /&gt;- Autenticación&lt;br /&gt;- Autorización&lt;br /&gt;- SQL Injection&lt;br /&gt;- Buenas prácticas de codificación (validar todas las entradas del usuario, uso de bloques try/catch/finally, uso de una cuenta con el menor privilegio)&lt;br /&gt;&lt;br /&gt;Al final pase el examen con un mínimo necesario: 721 de 700.&lt;br /&gt;&lt;br /&gt;Este examen se mantendrá hasta el mes de Marzo y sera retirado de las carreras de certificación.&lt;br /&gt;&lt;br /&gt;Bibliografía recomendada:&lt;br /&gt;&lt;br /&gt;Writing Secure Code, Second Edition: Michael Howard and David Leblanc&lt;br /&gt;&lt;img src="http://humansharp.com/picture_library/libro1.png" border="0" alt="" width="100" height="100"/&gt;&lt;br /&gt;&lt;br /&gt;Professional C# 3rd Edition: Simon Robinson, Christian Nagel, Karli Watson, Jay Glynn, Morgan Skinner, Bill Evjen&lt;br /&gt;&lt;img src="http://humansharp.com/picture_library/libro2.png" border="0" alt="" width="100" height="100"/&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6494419861240446187-6403710674161376111?l=xomalli.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/6403710674161376111'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6494419861240446187/posts/default/6403710674161376111'/><link rel='alternate' type='text/html' href='http://xomalli.blogspot.com/2009/02/70-340-implementando-seguridad-de.html' title='70-340 Implementando seguridad de aplicaciones C#'/><author><name>Martín Márquez</name><uri>http://www.blogger.com/profile/10939957618126542300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_j4WRR9G9bfY/SV2_nw3UxeI/AAAAAAAAAAM/nT3SYp94IHo/s1600-R/photo.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-6494419861240446187.post-1832422737697571259</id><published>2009-01-11T10:48:00.000-08:00</published><updated>2009-05-29T01:11:55.826-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><title type='text'>Usandos controles de validación ASP .NET III (RegularExpressionValidator)</title><content type='html'>&lt;P align="justify"&gt;Este control es verdaderamente útil, si necesitamos comparar el valor de un campo con una expresión regular , este control aplica esencialmente si queremos comparar el formato de una dirección de correo electrónico,una fecha o un código postal entre o bien para buscar un patrón dentro del texto.&lt;/P&gt;&lt;br /&gt;Veamos el siguiente formulario como ejemplo:&lt;br /&gt;&lt;pre&gt;&lt;span class="sc15"&gt;&amp;lt;%@&lt;/span&gt;&lt;span class="sc16"&gt;Page Language="C#" AutoEventWireup="false" &lt;br /&gt;CodeBehind="RegularExpression.aspx.cs" &lt;br /&gt;Inherits="blog.listings.RegularExpression"&lt;/span&gt;&lt;span class="sc15"&gt;%&amp;gt;&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="sc1"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="sc1"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="sc1"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;&lt;span class="sc0"&gt;Expresiones Regulares&lt;/span&gt;&lt;span class="sc1"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="sc1"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="sc1"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="sc1"&gt;&amp;lt;form&lt;/span&gt;&lt;span class="sc8"&gt; &lt;/span&gt;&lt;span class="sc3"&gt;id&lt;/span&gt;&lt;span class="sc8"&gt;=&lt;/span&gt;&lt;span class="sc6"&gt;"form1"&lt;/span&gt;&lt;span class="sc8"&gt; &lt;/span&gt;&lt;span class="sc4"&gt;runat&lt;/span&gt;&lt;span class="sc8"&gt;=&lt;/span&gt;&lt;span class="sc6"&gt;"server"&lt;/span&gt;&lt;span class="sc1"&gt;&amp;gt;&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="sc1"&gt;&amp;lt;table&amp;gt;&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="sc1"&gt;&amp;lt;tr&amp;gt;&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="sc1"&gt;&amp;lt;td&amp;gt;&lt;/span&gt;&lt;span class="sc0"&gt;Fecha (dd/mm/yyyy)&lt;/span&gt;&lt;span class="sc1"&gt;&amp;lt;/td&amp;gt;&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="sc1"&gt;&amp;lt;td&amp;gt;&lt;/span&gt;&lt;span class="sc2"&gt;&amp;lt;asp:TextBox ID="txtDate" runat="server"&amp;gt;&amp;lt;/asp:TextBox&amp;gt;&lt;/span&gt;&lt;span class="sc1"&gt;&amp;lt;/td&amp;gt;&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="sc1"&gt;&amp;lt;td&amp;gt;&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="sc2"&gt;&amp;lt;asp:RequiredFieldValidator ID="reqvtxtDate" runat="server" &lt;br /&gt;ErrorMessage="* Obligatorio" ControlToValidate="txtDate"&amp;gt;&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="sc2"&gt;&amp;lt;/asp:RequiredFieldValidator&amp;gt;&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="sc2"&gt;&amp;lt;asp:RegularExpressionValidator ID="rexpvtxtDate" runat="server" &lt;br /&gt;ErrorMessage="* Invalida" &lt;br /&gt;ValidationExpression="(0[1-9]|[12][0-9]|3[01])[- /.]&lt;br /&gt;(0[1-9]|1[012])[- /.](19|20)\d\d" ControlToValidate="txtDate"&amp;gt;&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="sc2"&gt;&amp;lt;/asp:RegularExpressionValidator&amp;gt;&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="sc1"&gt;&amp;lt;/td&amp;gt;&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt; &lt;/span&gt;&lt;span class="sc1"&gt;&amp;lt;/tr&amp;gt;&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt; &lt;/span&gt;&lt;span class="sc1"&gt;&amp;lt;tr&amp;gt;&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="sc1"&gt;&amp;lt;td&amp;gt;&lt;/span&gt;&lt;span class="sc0"&gt;Teclea un URL&lt;/span&gt;&lt;span class="sc1"&gt;&amp;lt;/td&amp;gt;&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt; &lt;/span&gt;&lt;span class="sc1"&gt;&amp;lt;td&amp;gt;&lt;/span&gt;&lt;span class="sc2"&gt;&amp;lt;asp:TextBox ID="txtUrl" runat="server"&amp;gt;&amp;lt;/asp:TextBox&amp;gt;&lt;/span&gt;&lt;span class="sc1"&gt;&amp;lt;/td&amp;gt;&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="sc1"&gt;&amp;lt;td&amp;gt;&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="sc2"&gt;&amp;lt;asp:RequiredFieldValidator ID="reqvtxtUrl" runat="server" &lt;br /&gt;ErrorMessage="* Obligatorio" ControlToValidate="txtUrl"&amp;gt;&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="sc2"&gt;&amp;lt;/asp:RequiredFieldValidator&amp;gt;&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="sc2"&gt;&amp;lt;asp:RegularExpressionValidator ID="rexpvtxtUrl" runat="server" &lt;br /&gt;ErrorMessage="* Invalida" &lt;br /&gt;ValidationExpression="http://([\w-]+\.)+[\w-]+(/[\w- ./?%&amp;amp;amp;=]*)?" &lt;br /&gt;ControlToValidate="txtUrl"&amp;gt;&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="sc2"&gt;&amp;lt;/asp:RegularExpressionValidator&amp;gt;&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="sc1"&gt;&amp;lt;/td&amp;gt;&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="sc1"&gt;&amp;lt;/tr&amp;gt;&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="sc1"&gt;&amp;lt;tr&amp;gt;&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="sc1"&gt;&amp;lt;td&amp;gt;&lt;/span&gt;&lt;span class="sc0"&gt;Teclea un código postal&lt;/span&gt;&lt;span class="sc1"&gt;&amp;lt;/td&amp;gt;&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="sc1"&gt;&amp;lt;td&amp;gt;&lt;/span&gt;&lt;span class="sc2"&gt;&amp;lt;asp:TextBox ID="txtCp" runat="server"&amp;gt;&amp;lt;/asp:TextBox&amp;gt;&lt;/span&gt;&lt;span class="sc1"&gt;&amp;lt;/td&amp;gt;&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="sc1"&gt;&amp;lt;td&amp;gt;&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="sc2"&gt;&amp;lt;asp:RequiredFieldValidator ID="reqvtxtCp" runat="server" &lt;br /&gt;ErrorMessage="*Obligatorio" ControlToValidate="txtCp"&amp;gt;&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="sc2"&gt;&amp;lt;/asp:RequiredFieldValidator&amp;gt;&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="sc2"&gt;&amp;lt;asp:RegularExpressionValidator ID="rexptxtCp" runat="server" &lt;br /&gt;ErrorMessage="* Invalido" &lt;br /&gt;ValidationExpression="\d{5}(-\d{4})?" &lt;br /&gt;ControlToValidate="txtCp"&amp;gt;&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="sc2"&gt;&amp;lt;/asp:RegularExpressionValidator&amp;gt;&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="sc1"&gt;&amp;lt;/td&amp;gt;&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="sc1"&gt;&amp;lt;/tr&amp;gt;&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="sc1"&gt;&amp;lt;tr&amp;gt;&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="sc1"&gt;&amp;lt;td&amp;gt;&lt;/span&gt;&lt;span class="sc0"&gt;Correo Electrónico&lt;/span&gt;&lt;span class="sc1"&gt;&amp;lt;/td&amp;gt;&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="sc1"&gt;&amp;lt;td&amp;gt;&lt;/span&gt;&lt;span class="sc2"&gt;&amp;lt;asp:TextBox ID="txtEmail" runat="server"&amp;gt;&amp;lt;/asp:TextBox&amp;gt;&lt;/span&gt;&lt;span class="sc1"&gt;&amp;lt;/td&amp;gt;&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="sc1"&gt;&amp;lt;td&amp;gt;&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="sc2"&gt;&amp;lt;asp:RequiredFieldValidator ID="reqvtxtEmail" runat="server" &lt;br /&gt;ControlToValidate="txtEmail" ErrorMessage="* Obligatorio"&amp;gt;&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="sc2"&gt;&amp;lt;/asp:RequiredFieldValidator&amp;gt;&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="sc2"&gt;&amp;lt;asp:RegularExpressionValidator ID="rexptxtEmail" runat="server" &lt;br /&gt;ErrorMessage="* Invalido" ControlToValidate="txtEmail" ValidationExpression="\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*"&amp;gt;&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="sc2"&gt;&amp;lt;/asp:RegularExpressionValidator&amp;gt;&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="sc1"&gt;&amp;lt;/td&amp;gt;&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="sc1"&gt;&amp;lt;/tr&amp;gt;&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="sc1"&gt;&amp;lt;/table&amp;gt;&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="sc1"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;&lt;span class="sc2"&gt;&amp;lt;asp:Button ID="btnSubmit" runat="server" Text="Enviar"&amp;gt;&amp;lt;/asp:Button&amp;gt;&lt;/span&gt;&lt;span class="sc1"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="sc2"&gt;&amp;lt;asp:Label ID="lbMsg" runat="server"&amp;gt;&amp;lt;/asp:Label&amp;gt;&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="sc1"&gt;&amp;lt;/form&amp;gt;&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="sc1"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="sc1"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;y su correspondiente código de clase:&lt;br /&gt;&lt;pre&gt;&lt;span class="sc5"&gt;using&lt;/span&gt;&lt;span class="sc0"&gt; &lt;/span&gt;&lt;span class="sc11"&gt;System&lt;/span&gt;&lt;span class="sc10"&gt;;&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="sc5"&gt;using&lt;/span&gt;&lt;span class="sc0"&gt; &lt;/span&gt;&lt;span class="sc11"&gt;System&lt;/span&gt;&lt;span class="sc10"&gt;.&lt;/span&gt;&lt;span class="sc11"&gt;Web&lt;/span&gt;&lt;span class="sc10"&gt;.&lt;/span&gt;&lt;span class="sc11"&gt;UI&lt;/span&gt;&lt;span class="sc10"&gt;;&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="sc5"&gt;using&lt;/span&gt;&lt;span class="sc0"&gt; &lt;/span&gt;&lt;span class="sc11"&gt;System&lt;/span&gt;&lt;span class="sc10"&gt;.&lt;/span&gt;&lt;span class="sc11"&gt;Web&lt;/span&gt;&lt;span class="sc10"&gt;.&lt;/span&gt;&lt;span class="sc11"&gt;UI&lt;/span&gt;&lt;span class="sc10"&gt;.&lt;/span&gt;&lt;span class="sc11"&gt;WebControls&lt;/span&gt;&lt;span class="sc10"&gt;;&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="sc5"&gt;namespace&lt;/span&gt;&lt;span class="sc0"&gt; &lt;/span&gt;&lt;span class="sc11"&gt;blog&lt;/span&gt;&lt;span class="sc10"&gt;.&lt;/span&gt;&lt;span class="sc11"&gt;listings&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="sc10"&gt;{&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="sc5"&gt;public&lt;/span&gt;&lt;span class="sc0"&gt; &lt;/span&gt;&lt;span class="sc2"&gt;class&lt;/span&gt;&lt;span class="sc0"&gt; &lt;/span&gt;&lt;span class="sc11"&gt;RegularExpression&lt;/span&gt;&lt;span class="sc0"&gt; &lt;/span&gt;&lt;span class="sc10"&gt;:&lt;/span&gt;&lt;span class="sc0"&gt; &lt;/span&gt;&lt;span class="sc11"&gt;Page&lt;/span&gt;&lt;span class="sc0"&gt; &lt;/span&gt;&lt;span class="sc10"&gt;{&lt;/span&gt;&lt;span class="sc0"&gt;&lt;br /&gt;    &lt;/span&gt;&lt;span class="sc5"&gt;protected&lt;/span&gt;&lt;span class="sc0"&gt; &lt;/span&gt;&lt;span class="sc11"&gt;TextBox&lt;/span&gt;&lt;span class="sc0"&gt; &lt;/span&gt;&lt;span class="sc11"&gt;
