<?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'><id>tag:blogger.com,1999:blog-32128398</id><updated>2010-03-13T16:29:15.849-03:00</updated><title type='text'>José Selesan</title><subtitle type='html'>Un espacio sobre .Net, desarrollo ágil y algunas cosas más</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://jose-selesan.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/32128398/posts/default'/><link rel='alternate' type='text/html' href='http://jose-selesan.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/32128398/posts/default?start-index=26&amp;max-results=25'/><author><name>Jose Selesan</name><uri>http://www.blogger.com/profile/06083003603043488677</uri><email>noreply@blogger.com</email></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>28</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-32128398.post-4913974855378049725</id><published>2008-11-26T15:15:00.003-02:00</published><updated>2008-11-26T16:08:13.294-02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MVC'/><category scheme='http://www.blogger.com/atom/ns#' term='Web 2.0'/><title type='text'>ASP.Net MVC, routing y URL amigables</title><content type='html'>&lt;span style="font-family:verdana;"&gt;Creo que una de las cosas que más le gusta a los webmasters son las URL amigables, por todo el tema de Google y de posicionar la página. Para los que no saben de qué estoy hablando, lo resumo fácilmente: una URL del tipo www.dominio.com/productos?id=4525 no dice mucho en sí misma sobre qué es el producto y es difícil de recordar, por eso se dice que "no es amigable", una URL amigable en cambio, sería de la forma www.dominio.com/catalogo/navegadores/gps-nuvi-200. En esta url claramente vemos que se trata de un producto dentro de la categoría "navegadores" y su descripción es "gps-nuvi-200". Además de ser lindas para los simples mortales, las URL amigables son muy buenas para los motores de búsqueda. En wikipedia hay &lt;/span&gt;&lt;a style="font-family: verdana;" href="http://es.wikipedia.org/wiki/URL_sem%C3%A1nticas"&gt;más información&lt;/a&gt;&lt;span style="font-family:verdana;"&gt; (note usted la URL amigable en la mismísima wikipedia).&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:verdana;"&gt;Ahora bien, implementar URL amigables en ASP.Net nunca fue tarea fácil hasta la llegada de ASP.Net MVC. Con este nuevo framework podemos crear rutas, que no son más que formas de indicarle al motor como traducir una url en una llamada a una acción de un controlador.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:verdana;"&gt;Para ilustrar mejor vamos a ver un pequeño ejemplo. Supongamos que tenemos un controller llamado ProductosController, con una acción llamada Ver que tiene como objetivo mostrar un producto cuyo &lt;/span&gt;código único recibe como parámetro&lt;/span&gt;. &lt;span style="font-family:verdana;"&gt;Sin usar rutas, una url típica sería de la forma /productos/ver/4525&lt;/span&gt;. &lt;span style="font-family:verdana;"&gt;Vamos entonces a crear una ruta para hacerla más amigable.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:verdana;"&gt;En ASP.Net MVC, las rutas se registran en el evento Application_Start y se evalúan de la primera a la última, cuando una corresponde ("matchea" se podría decir, aunque no me guste hablar así) con la url, es esa la que se usa. Para nuestro caso, la ruta quedaría así:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt; &lt;div class="code"&gt;&lt;br /&gt;&lt;span style="color:black;"&gt;routes.MapRoute(&lt;br /&gt;&lt;br /&gt;  &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;"Catalogo"&lt;/span&gt;&lt;span style="color:black;"&gt;,&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;"catalogo/{id}/{descripcion}"&lt;/span&gt;&lt;span style="color:black;"&gt;,&lt;br /&gt;    &lt;/span&gt;&lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:black;"&gt;{ controller &lt;/span&gt;&lt;span style="color:blue;"&gt;= &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;"Productos"&lt;/span&gt;&lt;span style="color:black;"&gt;, action &lt;/span&gt;&lt;span style="color:blue;"&gt;= &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;"Ver"&lt;/span&gt;&lt;span style="color:black;"&gt;, id &lt;/span&gt;&lt;span style="color:blue;"&gt;= &lt;/span&gt;&lt;span style="color:maroon;"&gt;0 &lt;/span&gt;&lt;span style="color:black;"&gt;},&lt;br /&gt;    &lt;/span&gt;&lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:black;"&gt;{ id &lt;/span&gt;&lt;span style="color:blue;"&gt;= &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;@"\d+" &lt;/span&gt;&lt;span style="color:black;"&gt;}&lt;br /&gt;&lt;br /&gt;)&lt;/span&gt;&lt;br /&gt; &lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:verdana;"&gt;El primer parámetro es el nombre de la ruta (que debe ser único", el segundo es el patrón de la url y el tercero es el que indica los valores por defecto. El cuarto parámetro lo veremos luego.  En los valores por defecto le estamos diciendo que si no puede detectar el nombre del controlador en la url, que use "Productos" y que si no puede encontrar la acción, que use "Ver". Con esta ruta, al llamar a la url /catalogo/4525/gps-nuvi-200 en realidad se estará llamando al método Ver de la clase ProductosController, pasandole el valor 4525 como parámetro.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:verdana;"&gt;Vamos a hacer un poco más interesante la url. Supongamos que queremos dar la posibilidad de colocar la categoría del producto en la url, o sea algo de la forma /catalogo/navegadores-satelitales/4525/gps-nuvi-200. Para hacerlo, basta con agregar otra ruta más de la siguiente forma:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="code"&gt;&lt;br /&gt;&lt;span style="color:black;"&gt;routes.MapRoute(&lt;br /&gt;&lt;br /&gt;    &lt;/span&gt;&lt;span style="color:#808080;"&gt;"CatalogoConCategoria"&lt;/span&gt;&lt;span style="color:black;"&gt;,&lt;br /&gt;      &lt;/span&gt;&lt;span style="color:#808080;"&gt;"catalogo/{categoria}/{id}/{descripcion}"&lt;/span&gt;&lt;span style="color:black;"&gt;,&lt;br /&gt;      &lt;/span&gt;&lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:black;"&gt;{ controller &lt;/span&gt;&lt;span style="color:blue;"&gt;= &lt;/span&gt;&lt;span style="color:#808080;"&gt;"Home"&lt;/span&gt;&lt;span style="color:black;"&gt;, action &lt;/span&gt;&lt;span style="color:blue;"&gt;= &lt;/span&gt;&lt;span style="color:#808080;"&gt;"Prueba"&lt;/span&gt;&lt;span style="color:black;"&gt;, id &lt;/span&gt;&lt;span style="color:blue;"&gt;= &lt;/span&gt;&lt;span style="color:maroon;"&gt;0 &lt;/span&gt;&lt;span style="color:black;"&gt;},&lt;br /&gt;      &lt;/span&gt;&lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:black;"&gt;{ id &lt;/span&gt;&lt;span style="color:blue;"&gt;= &lt;/span&gt;&lt;span style="color:#808080;"&gt;@"\d+" &lt;/span&gt;&lt;span style="color:black;"&gt;}&lt;br /&gt;&lt;br /&gt;)&lt;/span&gt;&lt;span style="color:blue;"&gt;;&lt;/span&gt;&lt;br /&gt; &lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: verdana;"&gt;En esta nueva ruta, hacemos casi lo mismo que en la anterior, con la diferencia que ahora estamos esperando urls con la categoría antes del ID de producto. Lo importante de esto es el cuarto parámetro que no expliqué hoy. Ese parámetro no es más que una restricción sobre los elementos de la URL, y le indica al motor de ruteo que la url corresponde con esa ruta si se cumple esa condición. En nuestro caso, le estamos diciendo que el ID debe ser un número. Esto es muy importante porque si no lo hacemos, al recorrer las rutas en orden, el motor tomaría la categoría como ID de producto, dando un comportamiento que no es el esperado.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32128398-4913974855378049725?l=jose-selesan.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jose-selesan.blogspot.com/feeds/4913974855378049725/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=32128398&amp;postID=4913974855378049725' title='3 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/32128398/posts/default/4913974855378049725'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/32128398/posts/default/4913974855378049725'/><link rel='alternate' type='text/html' href='http://jose-selesan.blogspot.com/2008/11/aspnet-mvc-routing-y-url-amigables.html' title='ASP.Net MVC, routing y URL amigables'/><author><name>Jose Selesan</name><uri>http://www.blogger.com/profile/06083003603043488677</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='15604937777563746127'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-32128398.post-5411589809356684637</id><published>2008-11-14T21:56:00.002-02:00</published><updated>2008-11-14T22:02:25.774-02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='de poco un todo'/><category scheme='http://www.blogger.com/atom/ns#' term='Libros'/><title type='text'>Error inesperado</title><content type='html'>&lt;span style="font-family:verdana;"&gt;Por esas cosas locas que tiene el destino, saqué de nuestra biblioteca una vieja edición de "Sobre héroes y tumbas" y entre sus maravillosas páginas había un pequeño trozo de papel escrito por mí y que quizá en su momento sirvió de señalador, con el texto "&lt;em&gt;A class named TInterfacedPersistent already exists&lt;/em&gt;", y se me dió por pensar no sólo los años que debe llevar eso ahí, sino también por qué lo abré anotado y en qué habré estado trabajando en ese momento. Por la T al principio del nombre de clase se me ocurre que es Delphi, pero vaya uno a saber.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:verdana;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:verdana;"&gt;Es interesante lo que uno puede encontrar abriendo un libro...&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32128398-5411589809356684637?l=jose-selesan.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jose-selesan.blogspot.com/feeds/5411589809356684637/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=32128398&amp;postID=5411589809356684637' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/32128398/posts/default/5411589809356684637'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/32128398/posts/default/5411589809356684637'/><link rel='alternate' type='text/html' href='http://jose-selesan.blogspot.com/2008/11/error-inesperado.html' title='Error inesperado'/><author><name>Jose Selesan</name><uri>http://www.blogger.com/profile/06083003603043488677</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='15604937777563746127'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-32128398.post-4989191660764627903</id><published>2008-11-14T16:23:00.002-02:00</published><updated>2008-11-14T16:29:17.644-02:00</updated><title type='text'>Advantage Database Server y ASP.Net 2.0</title><content type='html'>&lt;span style="font-family: verdana;"&gt;Estoy trabajando en una aplicación &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;web&lt;/span&gt; con Visual &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;Studio&lt;/span&gt; 2008 y &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;Advantage&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;Database&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;Server&lt;/span&gt; como motor de base de datos y ocasionalmente, al ejecutarla obtenía un error diciendo que no se podía hacer un &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;typecast&lt;/span&gt; entre el tipo de dato System.Web.Compilation.BuildResultCompiledAssembly y el tipo System.Web.Util.ITypedWebObjectFactory. Lo extraño es que recargando la página en el &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;browser&lt;/span&gt; con &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;Shift&lt;/span&gt; presionado para que la traiga toda de nuevo, funcionaba bien.&lt;br /&gt;&lt;br /&gt;Buscando un poco en &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;internet&lt;/span&gt;, encontré &lt;a href="http://support.microsoft.com/kb/924731/en-us/"&gt;este &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_9"&gt;KB&lt;/span&gt; de Microsoft&lt;/a&gt; donde explican las causas y la solución. Aparentemente no le gusta mucho tener ensamblados satélite con información de cultura, así que mirando las propiedades de cada &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_10"&gt;assembly&lt;/span&gt; de mi solución, encontré que las causantes del problema eran tres &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_11"&gt;dlls&lt;/span&gt; que necesita el &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_12"&gt;provider&lt;/span&gt; de &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_13"&gt;ADS&lt;/span&gt; para .&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_14"&gt;Net&lt;/span&gt;: &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_15"&gt;ace&lt;/span&gt;32.&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_16"&gt;dll&lt;/span&gt;, &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_17"&gt;adsloc&lt;/span&gt;32.&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_18"&gt;dll&lt;/span&gt; y &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_19"&gt;axcws&lt;/span&gt;32.&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_20"&gt;dll&lt;/span&gt;. Después de colocarlas en una carpeta llamada en-&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_21"&gt;US&lt;/span&gt; dentro del &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_22"&gt;bin&lt;/span&gt;, todo funcionó de diez, y fuimos felices.&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32128398-4989191660764627903?l=jose-selesan.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jose-selesan.blogspot.com/feeds/4989191660764627903/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=32128398&amp;postID=4989191660764627903' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/32128398/posts/default/4989191660764627903'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/32128398/posts/default/4989191660764627903'/><link rel='alternate' type='text/html' href='http://jose-selesan.blogspot.com/2008/11/advantage-database-server-y-aspnet-20.html' title='Advantage Database Server y ASP.Net 2.0'/><author><name>Jose Selesan</name><uri>http://www.blogger.com/profile/06083003603043488677</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='15604937777563746127'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-32128398.post-3655783240737412730</id><published>2008-10-30T14:30:00.004-02:00</published><updated>2008-10-30T14:52:13.873-02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MVC'/><category scheme='http://www.blogger.com/atom/ns#' term='Trucos'/><category scheme='http://www.blogger.com/atom/ns#' term='ASP.Net'/><title type='text'>ASP.Net MVC y la extensión .mvc</title><content type='html'>&lt;span style="font-family:verdana;"&gt;Como ya deben saber quienes probaron el framework MVC de la muchachada de Microsoft, viene con un motor de ruteo y la posibilidad de usar urls sin extensión, lo cual las hace bastante amigables (por ejemplo: http://sitio/productos/ver/1). Sin embargo, esta última opción solo está disponible (al menos de forma nativa) solo en IIS 7, o sea Windows Server 2008. Para poder correr una aplicación &lt;/span&gt;&lt;span style="font-family:verdana;"&gt;ASP.Net MVC en IIS 6 es necesario que las urls tengan la extensión en la parte del controlador (o sea, algo de la forma http://sitio/productos.mvc/ver/1). La extensión más usada por el momento es mvc, y para que esto funcione, se debe la mapear en IIS con la aspnet_isapi.dll así es el framework el encargado de procesar la solicitud&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:verdana;"&gt;Cuando lo hice por primera vez, fui entusiasmado a correr la aplicación en el server y me encontré con un error 404, lo cual no podía ser porque la url era totalmente válida y el sitio estaba montado correctamente. Después de varias pruebas y naufragios por google, encontré que la forma de que funcione es desmarcando el check "Verificar que el archivo existe" en el diálogo de mapeo de la extensión mvc, para que el IIS no restringa las solicitudes solo a archivos existentes:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_rUxTjmAjGD0/SQnlwH4TA_I/AAAAAAAAALw/5RjNqpU_Gn0/s1600-h/extrensionMvc.PNG"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 228px;" src="http://3.bp.blogspot.com/_rUxTjmAjGD0/SQnlwH4TA_I/AAAAAAAAALw/5RjNqpU_Gn0/s400/extrensionMvc.PNG" alt="" id="BLOGGER_PHOTO_ID_5262990254470792178" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:verdana;"&gt;Hecho esto, el sitio funciona bien. Próximamente voy a tratar de usar urls sin extensión en IIS 6 mediante el agregado de un módulo de reescritura (al estilo mod_rewrite de apache), porque sinceramente este tipo de urls me atraen más que las que tienen extensión, por lo mismo que dije antes.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32128398-3655783240737412730?l=jose-selesan.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jose-selesan.blogspot.com/feeds/3655783240737412730/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=32128398&amp;postID=3655783240737412730' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/32128398/posts/default/3655783240737412730'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/32128398/posts/default/3655783240737412730'/><link rel='alternate' type='text/html' href='http://jose-selesan.blogspot.com/2008/10/aspnet-mvc-y-la-extensin-mvc.html' title='ASP.Net MVC y la extensión .mvc'/><author><name>Jose Selesan</name><uri>http://www.blogger.com/profile/06083003603043488677</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='15604937777563746127'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_rUxTjmAjGD0/SQnlwH4TA_I/AAAAAAAAALw/5RjNqpU_Gn0/s72-c/extrensionMvc.PNG' height='72' width='72'/><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-32128398.post-1255434628735010530</id><published>2008-10-29T16:01:00.002-02:00</published><updated>2008-10-29T16:08:21.447-02:00</updated><title type='text'>Scrum y XP desde las trincheras</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_rUxTjmAjGD0/SQimeFr1gGI/AAAAAAAAALg/me1i3qe7kfY/s1600-h/coverlandingpage.JPG"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer; width: 100px; height: 151px;" src="http://4.bp.blogspot.com/_rUxTjmAjGD0/SQimeFr1gGI/AAAAAAAAALg/me1i3qe7kfY/s200/coverlandingpage.JPG" alt="" id="BLOGGER_PHOTO_ID_5262639200434749538" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="font-family:verdana;"&gt;El título del post corresponde a un libro muy interesante sobre gestión ágil de proyectos. Si bien es un libro bastante corto, lo que lo hace interesante es que no se va por las ramas con mucha teoría de metodologías y demás yerbas sino que trata una serie de consejos prácticos de manera tal que el lector pueda comenzar a utilizar técnicas ágiles apenas leidos unos cuantos capítulos.&lt;br /&gt;&lt;br /&gt;El libro se puede comprar impreso, o bien puede ser descargado de &lt;a href="http://www.infoq.com/minibooks/scrum-xp-from-the-trenches"&gt;aquí&lt;/a&gt;&lt;br /&gt;Quienes no estén muy familiarizados con el inglés, podrán encontrar una traducción (no la leí, así que no puede decir si es buena o no), &lt;a href="http://www.proyectalis.com/wp-content/uploads/2008/02/scrum-y-xp-desde-las-trincheras.pdf"&gt;aquí&lt;/a&gt;, y despues contarme qué le pareció el libro.&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32128398-1255434628735010530?l=jose-selesan.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jose-selesan.blogspot.com/feeds/1255434628735010530/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=32128398&amp;postID=1255434628735010530' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/32128398/posts/default/1255434628735010530'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/32128398/posts/default/1255434628735010530'/><link rel='alternate' type='text/html' href='http://jose-selesan.blogspot.com/2008/10/scrum-y-xp-desde-las-trincheras.html' title='Scrum y XP desde las trincheras'/><author><name>Jose Selesan</name><uri>http://www.blogger.com/profile/06083003603043488677</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='15604937777563746127'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_rUxTjmAjGD0/SQimeFr1gGI/AAAAAAAAALg/me1i3qe7kfY/s72-c/coverlandingpage.JPG' height='72' width='72'/><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-32128398.post-572071549071790973</id><published>2008-10-23T13:59:00.004-02:00</published><updated>2008-10-23T14:04:38.644-02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Cinco estrellas'/><category scheme='http://www.blogger.com/atom/ns#' term='.net'/><category scheme='http://www.blogger.com/atom/ns#' term='DCE'/><title type='text'>5 Estrellas Platinum</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_rUxTjmAjGD0/SQCgVxAd6RI/AAAAAAAAALA/W8Rx9389cfo/s1600-h/DCE+Platino.PNG"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 320px; height: 103px;" src="http://3.bp.blogspot.com/_rUxTjmAjGD0/SQCgVxAd6RI/AAAAAAAAALA/W8Rx9389cfo/s320/DCE+Platino.PNG" alt="" id="BLOGGER_PHOTO_ID_5260380660561733906" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="font-family:verdana;"&gt;Hace unos días salió a la luz la esperada 5ta estrella de Platino del programa de capacitación &lt;/span&gt;&lt;a style="font-family: verdana;" href="http://www.dce2005.com/"&gt;Desarrollador Cinco Estrellas&lt;/a&gt;&lt;span style="font-family:verdana;"&gt;.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: verdana;"&gt;Para alcanzarla se debe tener la 5ta estrella dorada y rendir al menos un curso más, entre dos disponibles: Linq y Silverlight 2.0. Como siempre, el material me parece bastante escaso, aunque hay que reconocer que para un desarrollador que ya llegó a esta instancia del curso, solo necesita una introducción para entender un tema y luego investigar por su cuenta para profundizar y lograr los conocimientos necesarios para utilizarlo en el trabajo diario.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32128398-572071549071790973?l=jose-selesan.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jose-selesan.blogspot.com/feeds/572071549071790973/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=32128398&amp;postID=572071549071790973' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/32128398/posts/default/572071549071790973'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/32128398/posts/default/572071549071790973'/><link rel='alternate' type='text/html' href='http://jose-selesan.blogspot.com/2008/10/5-estrellas-platinum.html' title='5 Estrellas Platinum'/><author><name>Jose Selesan</name><uri>http://www.blogger.com/profile/06083003603043488677</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='15604937777563746127'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_rUxTjmAjGD0/SQCgVxAd6RI/AAAAAAAAALA/W8Rx9389cfo/s72-c/DCE+Platino.PNG' height='72' width='72'/><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-32128398.post-7973682481256204180</id><published>2008-10-03T14:40:00.005-03:00</published><updated>2008-10-03T15:33:51.445-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MVC'/><category scheme='http://www.blogger.com/atom/ns#' term='ASP.Net'/><category scheme='http://www.blogger.com/atom/ns#' term='Linq'/><category scheme='http://www.blogger.com/atom/ns#' term='TDD'/><title type='text'>ASP.Net MVC + System.Linq + Tipos Anonimos = Soluciones Elegantes</title><content type='html'>Hace poco me encargaron el desarrollo de una pequeña aplicación web de uso interno, así que como era un proyecto de bajo riesgo y pocas líneas de código, aproveché para hacerlo con ASP.Net MVC, para aprenderlo y usarlo (ya hice varias aplicaciones con Monorail y necesitaba tener mas herramientas para comparar con el nuevo framework MVC de los muchachos de Microsoft).&lt;br /&gt;&lt;br /&gt;Antes de abordar el tema que motivó este post, algunas consideraciones sobre ASP.Net MVC:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Es excelente el soporte de intellisense para la edición de vistas, lo que facilita mucho la curva de aprendizaje.&lt;/li&gt;&lt;li&gt;Me pareció atinado el uso de ActionResult como resultado de las acciones, ya que permite hacer mejores aserciones en los tests unitarios (recordemos que las acciones en MonoRail son void)&lt;/li&gt;&lt;li&gt;No me pareció tan buena la asociación entre las vistas y la master page. Esto dificulta un poco el uso eventual de ajax. No prové las extensiones que provee MvcContrib, que implementa un atributo Layout al modo Monorail, pero parece que ayuda.&lt;/li&gt;&lt;li&gt;Es fantástico el uso que le dan a los métodos de extensión, que permite agregar lo que necesitemos a los helpers &lt;span style="font-size:100%;"&gt;predefinidos&lt;/span&gt;&lt;/li&gt;&lt;li&gt;También me pareció acertado el uso de Generics y de expresiones Lamda en algunos metodos de los helpers. Por ejemplo, al definir un form con el HtmlHelper, podemos hacer Html.Form&lt;nombrecontroller&gt;(p =&gt; p.MiAccion() ). La gran ventaja de esto, además del intellisense, es la facilidad de refactoring, ya que estamos referenciando tipos y métodos de las clases y no cadenas de caracteres que no representan anda para el IDE ni para el compilador.&lt;/nombrecontroller&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-size:130%;"&gt;Un poco de magia&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Volviendo al tema que da título al post, voy a contar qué tuve que hacer y como lo solucioné. Cuando ya tenía lista la aplicación, me pidieron que se pueda exportar a Excel el resultado de un par de reportes. Inmediatamente recordé como lo hacía con webforms, renderizando la grilla directamente al stream y cambiando un par de headers, pero cuando comencé a pensar como trasladarlo al patrón MVC las cosas se complicaron. Después de un rato en Google, encontré este &lt;a href="http://weblogs.asp.net/stephenwalther/archive/2008/06/16/asp-net-mvc-tip-2-create-a-custom-action-result-that-returns-microsoft-excel-documents.aspx"&gt;excelente post&lt;/a&gt; que me salvó la vida (y le dio otro punto a favor a los ActionResult, ya que hace uso extensivo de la herencia sobre ese tipo).&lt;br /&gt;Obviamente lo primero que hice fue bajarme el código, buscar las dos clases que necesito y agregarlas a mi proyecto. Luego de hacerlo, me puse a ver en más detalle el código y me enconté con que no me servía así como estaba, ya que usaba Linq to SQL y mi proyecto usa ActiveRecord, así que en vez de tener un IQueryable, tenía un IList. Aquí empieza a aparecer la magia, ya que simplemente agregando un using a System.Linq, me apareció el método de extensión AsQueryable() en la interfaz IList, así que pude pasar el parámetro que necesitaba. Hecho esto, tampoco me funcionaba, ya que la clase usaba el mapping de Linq to SQL para descubrir las propiedades o nombres de las columnas para armar la tabla en Excel. Solución rápida: el siempre querido Reflection para indagar las propiedades del tipo de dato guardado en el IList.&lt;br /&gt;Listo, con eso la exportación funcionó bien, pero con un pequeño detalle. Aquellas propiedades que eran un tipo de dato complejo (una clase), se exportaban como el nombre del tipo y no el valor que yo quería. Por ejemplo, la entidad tenía una propiedad del tipo Usuario, y se exportaba como MiEspacioDeNombres.Usuario, en vez de exportar el nombre del usuario. Y acá aparece la potencia del framework 3.5 en todo su explendor, simplemente haciendo una consulta Linq sobre el IList y devolviendo objetos de tipo anónimo con las propiedades que quiero exportar ya resueltas:&lt;br /&gt;var lista = from p in miListado select new { Propiedad1 = p.P1, Propiedad2 = p.P2, Usuario = p.Usuario.Nombre }&lt;br /&gt;&lt;br /&gt;Esto es todo. Simplemente quedé asombrado por las posibilidades que brindan las nuevas características del lenguaje en el framework 3.5 para resolver de manera elegante cuestiones que surgen cuando ya se tiene la aplicación diseñada y no vale la pena hacer mucho refactoring.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32128398-7973682481256204180?l=jose-selesan.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jose-selesan.blogspot.com/feeds/7973682481256204180/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=32128398&amp;postID=7973682481256204180' title='1 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/32128398/posts/default/7973682481256204180'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/32128398/posts/default/7973682481256204180'/><link rel='alternate' type='text/html' href='http://jose-selesan.blogspot.com/2008/10/aspnet-mvc-systemlinq-tipos-anonimos.html' title='ASP.Net MVC + System.Linq + Tipos Anonimos = Soluciones Elegantes'/><author><name>Jose Selesan</name><uri>http://www.blogger.com/profile/06083003603043488677</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='15604937777563746127'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-32128398.post-2809013483955813053</id><published>2008-05-07T13:50:00.002-03:00</published><updated>2008-05-07T14:00:39.332-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='web'/><category scheme='http://www.blogger.com/atom/ns#' term='ser programador'/><title type='text'>Javascript, ASP.Net Ajax y arreglos clonados</title><content type='html'>Para un desarrollo con ASP.Net Ajax necesitaba poder clonar un arreglo devuelto por un webservice (en realidad acabo de aprender que los arreglos en javascript son tipos por referencia). Fue así que después de algunos intentos de escribir una función, opté por buscar en Google y encontré esta opción:&lt;br /&gt;&lt;br /&gt;&lt;div id="out"&gt;Object.prototype.clone  =  &lt;span class="keyword"&gt;function&lt;/span&gt; ()  {&lt;br /&gt;      &lt;span class="keyword"&gt;var&lt;/span&gt; o  =  &lt;span class="keyword"&gt;new&lt;/span&gt; Object();&lt;br /&gt;       &lt;span class="keyword"&gt;for&lt;/span&gt; (&lt;span class="keyword"&gt;var&lt;/span&gt; property in this)  {&lt;br /&gt;             o[property]  =  &lt;span class="keyword"&gt;typeof&lt;/span&gt; (&lt;span class="keyword"&gt;this&lt;/span&gt;[property])  ==  &lt;span class="literal"&gt;'object'&lt;/span&gt;  ?  &lt;span class="keyword"&gt;this&lt;/span&gt;[property].clone()  :  &lt;span class="keyword"&gt;this&lt;/span&gt;[property];&lt;br /&gt;         }&lt;br /&gt;           &lt;span class="keyword"&gt;return&lt;/span&gt; o;&lt;br /&gt;  }&lt;br /&gt;&lt;span class="object"&gt;Array&lt;/span&gt;.prototype.clone  =  &lt;span class="keyword"&gt;function&lt;/span&gt; ()  {&lt;br /&gt;      &lt;span class="keyword"&gt;var&lt;/span&gt; a  =  &lt;span class="keyword"&gt;new&lt;/span&gt; &lt;span class="object"&gt;Array&lt;/span&gt;();&lt;br /&gt;       &lt;span class="keyword"&gt;for&lt;/span&gt; (&lt;span class="keyword"&gt;var&lt;/span&gt; property in this)  {&lt;br /&gt;             a[property]  =  &lt;span class="keyword"&gt;typeof&lt;/span&gt; (&lt;span class="keyword"&gt;this&lt;/span&gt;[property])  ==  &lt;span class="literal"&gt;'object'&lt;/span&gt;  ?  &lt;span class="keyword"&gt;this&lt;/span&gt;[property].clone()  :  &lt;span class="keyword"&gt;this&lt;/span&gt;[property];&lt;br /&gt;         }&lt;br /&gt;       &lt;span class="keyword"&gt;return&lt;/span&gt; a;&lt;br /&gt;  }&lt;br /&gt;            &lt;/div&gt;&lt;br /&gt;Cuando la voy a probar, descubro que la clonación en profundidad (deep clone) la hace perfectamente, sin embargo, por alguna extraña razón que después de una mañana completa no logré comprender, no se lleva bien con los scripts que genera ASP.Net Ajax, y da un error bastante extraño y hace que dejen de funcionar algunas cosas de Ajax. Cosa e' Mandinga. Primero pensé que era un conflicto de nombres, así que le cambié el nombre "clone" por "clonar", y tampoco.&lt;br /&gt;Resumiendo, como necesitaba avanzar con el desarrollo, hice un segundo intento con el amigo Google y encontré esta función acá: &lt;a href="http://bytes.com/forum/thread715567.html"&gt;http://bytes.com/forum/thread715567.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;div id="out"&gt;&lt;span class="keyword"&gt;function&lt;/span&gt; clone_obj(obj)  {&lt;br /&gt;       &lt;span class="keyword"&gt;var&lt;/span&gt; c  =  obj instanceof Array  ?  []  :   {&lt;br /&gt;      };&lt;br /&gt;       &lt;span class="keyword"&gt;for&lt;/span&gt; (&lt;span class="keyword"&gt;var&lt;/span&gt; i in obj)  {&lt;br /&gt;              &lt;span class="keyword"&gt;var&lt;/span&gt; prop  =  obj[i];&lt;br /&gt;              &lt;span class="keyword"&gt;if&lt;/span&gt; (&lt;span class="keyword"&gt;typeof&lt;/span&gt; prop  ==  &lt;span class="literal"&gt;'object'&lt;/span&gt;)  {&lt;br /&gt;                    &lt;span class="keyword"&gt;if&lt;/span&gt; (prop instanceof Array)  {&lt;br /&gt;                           c[i]  =  [];&lt;br /&gt;                           &lt;span class="keyword"&gt;for&lt;/span&gt; (&lt;span class="keyword"&gt;var&lt;/span&gt; j  =  0;  j  &lt;  prop.length;  j++)  {&lt;br /&gt;                                  &lt;span class="keyword"&gt;if&lt;/span&gt; (&lt;span class="keyword"&gt;typeof&lt;/span&gt; prop[j]  !=  &lt;span class="literal"&gt;'object'&lt;/span&gt;)  {&lt;br /&gt;                                         c[i].push(prop[j]);&lt;br /&gt;                                     }&lt;br /&gt;                &lt;span class="keyword"&gt;else&lt;/span&gt;  {&lt;br /&gt;                                         c[i].push(clone_obj(prop[j]));&lt;br /&gt;                                     }&lt;br /&gt;                              }&lt;br /&gt;                       }&lt;br /&gt;          &lt;span class="keyword"&gt;else&lt;/span&gt;  {&lt;br /&gt;                           c[i]  =  clone_obj(prop);&lt;br /&gt;                       }&lt;br /&gt;                 }&lt;br /&gt;       &lt;span class="keyword"&gt;else&lt;/span&gt;  {&lt;br /&gt;                    c[i]  =  prop;&lt;br /&gt;                 }&lt;br /&gt;          }&lt;br /&gt;       &lt;span class="keyword"&gt;return&lt;/span&gt; c;&lt;br /&gt;   }&lt;br /&gt;&lt;span class="object"&gt;Array&lt;/span&gt;.prototype.clonar  =  &lt;span class="keyword"&gt;function&lt;/span&gt; ()  {&lt;br /&gt;       &lt;span class="keyword"&gt;var&lt;/span&gt; a  =  &lt;span class="keyword"&gt;new&lt;/span&gt; &lt;span class="object"&gt;Array&lt;/span&gt;();&lt;br /&gt;        &lt;span class="keyword"&gt;for&lt;/span&gt; (&lt;span class="keyword"&gt;var&lt;/span&gt; property in this)  {&lt;br /&gt;              a[property]  =  &lt;span class="keyword"&gt;typeof&lt;/span&gt; (&lt;span class="keyword"&gt;this&lt;/span&gt;[property])  ==  &lt;span class="literal"&gt;'object'&lt;/span&gt;  ?  &lt;span class="keyword"&gt;this&lt;/span&gt;[property].clonar()  :  &lt;span class="keyword"&gt;this&lt;/span&gt;[property];&lt;br /&gt;          }&lt;br /&gt;        &lt;span class="keyword"&gt;return&lt;/span&gt; a;&lt;br /&gt;   }&lt;br /&gt;             &lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Funciona a la perfección, y no se lleva mal con ASP.Net Ajax. Es así el mágico mundo de la programación.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32128398-2809013483955813053?l=jose-selesan.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jose-selesan.blogspot.com/feeds/2809013483955813053/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=32128398&amp;postID=2809013483955813053' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/32128398/posts/default/2809013483955813053'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/32128398/posts/default/2809013483955813053'/><link rel='alternate' type='text/html' href='http://jose-selesan.blogspot.com/2008/05/javascript-aspnet-ajax-y-arreglos.html' title='Javascript, ASP.Net Ajax y arreglos clonados'/><author><name>Jose Selesan</name><uri>http://www.blogger.com/profile/06083003603043488677</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='15604937777563746127'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-32128398.post-2188389749130405742</id><published>2008-04-18T16:20:00.002-03:00</published><updated>2008-04-18T16:35:58.489-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.net'/><category scheme='http://www.blogger.com/atom/ns#' term='web'/><category scheme='http://www.blogger.com/atom/ns#' term='ser programador'/><title type='text'>Programar para Web es facil</title><content type='html'>&lt;span style="font-family: verdana;"&gt;A esta altura ya me da pena ver como algunos programadores jóvenes (entiéndase programadores que se están iniciando), desembocan la mayoría de las veces en soluciones muy complejas a problemas simples. &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: verdana;"&gt;¿Por qué? Por supuesto que la respuesta no la tengo, pero quizás una aproximación, y es esta: el modelo de Webforms de ASP.Net hace complejo un protocolo simple (como lo es el HTTP).&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: verdana;"&gt;Me explico un poco mejor. El principal objetivo "marketinero" de los webforms fue acercar a los programadores de aplicaciones de escritorio al desarrollo web. Para ello, dotaron a ASP.Net de un complejo ciclo de vida de las páginas, eventos y controles, todo para que los webforms se parezcan lo más posible a los winforms. Y lo que consiguieron es que gente que nunca programó en web comience a hacerlo, pero a hacerlo al estilo windorms. Es así como hoy vemos programadores Web que no saben como funciona HTTP, incluso algunos que no distinguen cuándo están corriendo en el servidor y cuándo en el cliente. Y ni hablemos del mal uso de la sesión, al punto de degradar la aplicación o hacer que los usuarios pierdan trabajo cuando actualizan una dll del stio.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: verdana;"&gt;Hace poco vino un compañero de trabajo a hacerme una pregunta extraña sobre la relación entre el esquema del documento HTML y los Themes de ASP.Net 2.0. Como la pregunta me dejó medio descolocado, empecé a indagar para saber cuál era el problema real. Y el problema real era que quería usar un botón que había programado alguien y aparentemente no se llevaba bien con los temas. Mi sugerencia entonces fue, que si ese botón no funcionaba, que ponga un link o un botón común, a lo que me respondió que no le servía porque tenía que cambiarle el texto del lado del servidor, porque en un momento servía como botón "Buscar" y en otro como botón "Volver". La primera solución que se me ocurrió fue simplemente usar dos páginas distintas, una con los filtros  y otra con los resultados de la búsqueda. Y ahí fue donde me dí cuenta del título de este post: "Programar para la web es fácil, si se piensa en web".&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: verdana;"&gt;Mis consejos para los nuevos programadores (y para los no tan nuevos) que quieran desarrollar aplicaciones basadas en la web son estos:&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: verdana;"&gt;- Conocer como funciona el protocolo HTTP&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: verdana;"&gt;- Saber que aunque los webforms no lo permitan se puede tener más de un tag "form" por página&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: verdana;"&gt;- Saber que se puede trabajar con .Net para la web sin usar los odiosos webforms (estudiar por ejemplo MonoRail o ASP.Net MVC)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: verdana;"&gt;- Buscar siempre la solución más sencilla que funcione. Si algo no se puede resolver de una manera, tirarlo y buscar otra solución&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32128398-2188389749130405742?l=jose-selesan.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jose-selesan.blogspot.com/feeds/2188389749130405742/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=32128398&amp;postID=2188389749130405742' title='1 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/32128398/posts/default/2188389749130405742'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/32128398/posts/default/2188389749130405742'/><link rel='alternate' type='text/html' href='http://jose-selesan.blogspot.com/2008/04/programar-para-web-es-facil.html' title='Programar para Web es facil'/><author><name>Jose Selesan</name><uri>http://www.blogger.com/profile/06083003603043488677</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='15604937777563746127'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-32128398.post-401156634757498249</id><published>2008-04-15T11:06:00.003-03:00</published><updated>2008-04-15T11:08:19.833-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.net patrones'/><title type='text'>Inyección de dependencia en Enterprise Library</title><content type='html'>&lt;span style="font-family:verdana;"&gt;Según publicó InfoQ en &lt;a href="http://www.infoq.com/news/2008/04/microsoft-unity"&gt;este artículo&lt;/a&gt;, Microsoft implementó una librería para inversión de control e inyección de dependencia, que va a salir junto con la nueva versión de Enterprise Library.&lt;br /&gt;&lt;br /&gt;Pareciera que los muchachos de P&amp;amp;P se están avivando de qué es realmente lo que se necesita a la hora de crear una aplicación con una buena arquitectura, y ya se copiaron (porque realmente es así) dos de los componentes del Castle Project, como ser MonoRail para el desarrollo web con MVC y Windsor/Microkernel para la inyección de dependencia. Lo que no termino de entender es cómo para algunas cosas van tan rápido (como las nuevas versiones del framework .net) y para otras van tan lento (recordemos que el proyecto Castle tiene ya un buen tiempito y está bastante maduro aunque no tenga un release formal).&lt;br /&gt;&lt;br /&gt;Creo que ya no quedan dudas de que por la plata baila el mono.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32128398-401156634757498249?l=jose-selesan.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jose-selesan.blogspot.com/feeds/401156634757498249/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=32128398&amp;postID=401156634757498249' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/32128398/posts/default/401156634757498249'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/32128398/posts/default/401156634757498249'/><link rel='alternate' type='text/html' href='http://jose-selesan.blogspot.com/2008/04/inyeccin-de-dependencia-en-enterprise_538.html' title='Inyección de dependencia en Enterprise Library'/><author><name>Jose Selesan</name><uri>http://www.blogger.com/profile/06083003603043488677</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='15604937777563746127'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-32128398.post-3405851238253687941</id><published>2007-12-17T21:56:00.000-03:00</published><updated>2007-12-17T22:00:27.550-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ser programador'/><title type='text'>5 Estrellas .Net</title><content type='html'>&lt;span style="font-family:verdana;"&gt;Bueno, eso, que desde hace unos días tengo las 5 estrellas del programa &lt;/span&gt;&lt;a href="http://www.dce2005.com/"&gt;&lt;span style="font-family:verdana;"&gt;Desarrollador 5 Estrellas&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family:verdana;"&gt;. Para alcanzarla hay que rendir temas de Framework 2.0 y 3.0.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:verdana;"&gt;He aquí el diploma:&lt;/span&gt;&lt;br /&gt;&lt;a href="http://bp3.blogger.com/_rUxTjmAjGD0/R2cbSn4U49I/AAAAAAAAAHA/bcqPGoVJ9to/s1600-h/Diploma.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5145111106050909138" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://bp3.blogger.com/_rUxTjmAjGD0/R2cbSn4U49I/AAAAAAAAAHA/bcqPGoVJ9to/s320/Diploma.JPG" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32128398-3405851238253687941?l=jose-selesan.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jose-selesan.blogspot.com/feeds/3405851238253687941/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=32128398&amp;postID=3405851238253687941' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/32128398/posts/default/3405851238253687941'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/32128398/posts/default/3405851238253687941'/><link rel='alternate' type='text/html' href='http://jose-selesan.blogspot.com/2007/12/5-estrellas-net.html' title='5 Estrellas .Net'/><author><name>Jose Selesan</name><uri>http://www.blogger.com/profile/06083003603043488677</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='15604937777563746127'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp3.blogger.com/_rUxTjmAjGD0/R2cbSn4U49I/AAAAAAAAAHA/bcqPGoVJ9to/s72-c/Diploma.JPG' height='72' width='72'/><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-32128398.post-1978636382718630742</id><published>2007-11-14T19:32:00.000-03:00</published><updated>2007-11-14T19:37:59.567-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Libros'/><category scheme='http://www.blogger.com/atom/ns#' term='Mis Articulos'/><title type='text'>Libro</title><content type='html'>&lt;a href="http://bp2.blogger.com/_rUxTjmAjGD0/Rzt4c0jaKDI/AAAAAAAAAGc/hkjqizd8I64/s1600-h/libro.jpg"&gt;&lt;img id="BLOGGER_PHOTO_ID_5132828636857641010" style="FLOAT: right; MARGIN: 0px 0px 10px 10px; CURSOR: hand" height="228" alt="" src="http://bp2.blogger.com/_rUxTjmAjGD0/Rzt4c0jaKDI/AAAAAAAAAGc/hkjqizd8I64/s200/libro.jpg" width="183" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;div&gt;&lt;span style="font-family:verdana;"&gt;Me había olvidado! Para los que aún no lo saben, ha salido a la calle un libro de mi autoría. Es una guía básica de introducción a la programación. Se abordan brevemente temas desde la resolución de problemas y algoritmos hasta UML, pasando por la programación estructurada y lógicamente Orientación a Objetos.&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;span style="font-family:verdana;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;span style="font-family:verdana;"&gt;La imagen muestra la tapa.&lt;/span&gt;&lt;span style="font-family:Georgia;"&gt; &lt;/span&gt;&lt;span style="font-family:verdana;"&gt;Como siempre, haciendo click podrán ampliarla. Sobre el logo de Visual Studio está mi nombre!&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32128398-1978636382718630742?l=jose-selesan.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jose-selesan.blogspot.com/feeds/1978636382718630742/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=32128398&amp;postID=1978636382718630742' title='2 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/32128398/posts/default/1978636382718630742'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/32128398/posts/default/1978636382718630742'/><link rel='alternate' type='text/html' href='http://jose-selesan.blogspot.com/2007/11/libro.html' title='Libro'/><author><name>Jose Selesan</name><uri>http://www.blogger.com/profile/06083003603043488677</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='15604937777563746127'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp2.blogger.com/_rUxTjmAjGD0/Rzt4c0jaKDI/AAAAAAAAAGc/hkjqizd8I64/s72-c/libro.jpg' height='72' width='72'/><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-32128398.post-1703119859693397620</id><published>2007-11-14T18:24:00.000-03:00</published><updated>2007-11-14T19:19:03.023-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Patrones'/><category scheme='http://www.blogger.com/atom/ns#' term='MonoRail'/><category scheme='http://www.blogger.com/atom/ns#' term='ASP.Net'/><title type='text'>Primeras impresiones de ASP.Net MVC</title><content type='html'>&lt;span style="font-family:verdana;"&gt;En estos días, Scott Gu publicó un &lt;/span&gt;&lt;a style="FONT-FAMILY: verdana" href="http://weblogs.asp.net/scottgu/archive/2007/11/13/asp-net-mvc-framework-part-1.aspx"&gt;breve tutorial&lt;/a&gt;&lt;span style="font-family:verdana;"&gt; sobre el nuevo framework de Microsoft para desarrollar aplicaciónes ASP.Net siguiendo el patrón &lt;a href="http://en.wikipedia.org/wiki/Model-view-controller"&gt;MVC&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Como ya noté en mi anterior post sobre el tema, el parecido con &lt;a href="http://castleproject.org/monorail/index.html"&gt;MonoRail&lt;/a&gt; es realmente impresionante. No encontré un aspecto de la implementación de Microsoft que no esté ya soportado en MonoRail. Si se da la opuesta, hay varios detalles de MonoRail que aun no existen en ASP.Net MVC, como por ejemplo el SmartDispatcherController, aunque según Scott lo van a implementar antes de sacar el release del framework. Tampoco hay aun un soporte para Ajax.&lt;br /&gt;&lt;br /&gt;Un aspecto en el que "se parecen mucho" (no quiero decir que el equipo de Scott haya copiado a los amigos del proyecto Castle, pero...) es la clase Html, que según se puede ver en el ejemplo, viene a cumplir el mismo objetivo que el HtmlHelper de MonoRail.&lt;br /&gt;&lt;br /&gt;Hay algunas cosas que vi y no me gustaron. Una de ellas es la necesidad de especificar en la vista el tipo de datos del objeto que se va a usar para pasar información desde el controlador a la vista (lo que sería el PropertyBag de MonoRail). Obviamente esto da la ventaja del IntelliSense en las vistas, pero igualmente no me convence, creo que es más lo que se pierde que lo que se gana. Otro aspecto que no me gusta del todo es el hecho de poder usar WebControls en las vistas. ¿En qué baso mi postura? En que para interactuar con los WebControls hay que acudir al code behind de la página. Esto puede confundir un poco, haciendo el código menos legible, ya que al código del controlador y al de la vista, se agrega el del code behind. Además existe el riesgo de que un programador poco experimentado termine escribiendo lógica de la aplicación en los manejadores de eventos de los controles, rompiendo claramente el patrón.&lt;br /&gt;&lt;br /&gt;Bueno, ¿como sigue esto? Seguiremos esperando la salida del framework para juzgarlo con más herramientas que un simple artículo.&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32128398-1703119859693397620?l=jose-selesan.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jose-selesan.blogspot.com/feeds/1703119859693397620/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=32128398&amp;postID=1703119859693397620' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/32128398/posts/default/1703119859693397620'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/32128398/posts/default/1703119859693397620'/><link rel='alternate' type='text/html' href='http://jose-selesan.blogspot.com/2007/11/primeras-impreciones-de-aspnet-mvc.html' title='Primeras impresiones de ASP.Net MVC'/><author><name>Jose Selesan</name><uri>http://www.blogger.com/profile/06083003603043488677</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='15604937777563746127'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-32128398.post-4463733919480326599</id><published>2007-10-17T19:42:00.000-03:00</published><updated>2007-10-17T19:51:32.673-03:00</updated><title type='text'>MVC en ASP.Net</title><content type='html'>Hace algunos días ScottGu publicó &lt;a href="http://weblogs.asp.net/scottgu/archive/2007/10/14/asp-net-mvc-framework.aspx"&gt;este&lt;/a&gt; post sobre el nuevo framework de MVC en ASP.Net. Por la imagen que se ve en el post, sigue una estructura muy similar a la de MonoRail, en cuanto a la organización de las carpetas. Todavía no se lo puede bajar para ir viéndolo en acción y tampoco vi los videos donde lo muestran, pero se me vienen algunos pensamientos a partir de la imagen del post:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Al parecer ya hay soporte para pruebas unitarias sobre los Controllers, veremos si es tan bueno como MonoRail (o mejor)&lt;/li&gt;&lt;li&gt;Me inquieta ver como relacionan el modelo de ejecución de los webforms, con sus postbacks y su ciclo de vida complejo con las acciones de los postbacks&lt;/li&gt;&lt;li&gt;Según un comentario que se ve por ahí, a traves de plugins se va a poder usar cualquiera de los engines de renderización de vistas implementados para MonoRail. Eso está bueno!&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Seguiremos esperando y cuando se pueda hacer alguna pequeña aplicación, trataré de hacer una comparación con MonoRail&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32128398-4463733919480326599?l=jose-selesan.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jose-selesan.blogspot.com/feeds/4463733919480326599/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=32128398&amp;postID=4463733919480326599' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/32128398/posts/default/4463733919480326599'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/32128398/posts/default/4463733919480326599'/><link rel='alternate' type='text/html' href='http://jose-selesan.blogspot.com/2007/10/mvc-en-aspnet.html' title='MVC en ASP.Net'/><author><name>Jose Selesan</name><uri>http://www.blogger.com/profile/06083003603043488677</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='15604937777563746127'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-32128398.post-748615782354563742</id><published>2007-10-09T11:07:00.000-03:00</published><updated>2007-10-09T11:57:06.614-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ser programador'/><title type='text'>Separación de responsabilidades</title><content type='html'>Hace unos años (unos cuantos), cuando comencé a programar, aún no se hablaba mucho y no había suficiente documentación ni experiencias sobre separación de responsabilidades a la hora de escribir el código, entonces en el mismo archivo teníamos la lógica para actualizar la interfaz, para validar reglas de negocios y para manipular los datos.&lt;br /&gt;&lt;br /&gt;Con el tiempo, sobre todo ahora con el auge de los blogs, creo que ya se sabe que si se quiere lograr una base de código sólida, mantenible y bien estrucutrada, debemos separar por un lado los datos (que pueden estar en un SGBDR),  la lógica de negocios, la lógica de actualización de la interfaz y la interfaz con el usuario propiamente dicha. Existen patrones y técnicas que colaboran en cada uno de estos aspectos, desde la separación en capas hasta el MVC o el MVP.&lt;br /&gt;&lt;br /&gt;Sin embargo, aun hay gente que hace cosas horribles, sin analizar un solo instante las implicancias de lo que está escribiendo o quiere escribir. Por ejemplo, hoy vi algo que me dejó con la boca abierta, por decirlo de una manera. Me mostraron el código de un trigger en SQL Server, que se encargaba de generar código JavaScript en base a campos de alguna tabla y lo insertaba en otra, para luego tomarlo directamente en una interfaz ASP.Net. Es decir, lógica de interfaz almacenada en la base de datos.&lt;br /&gt;&lt;br /&gt;Le pido a los programadores nuevos: nunca una urgencia debe atentar contra la calidad del código, recordemos que como programadores, el código fuente es el principal documento que tenemos, y que si lo hacemos bien, nos va a evitar más de un problema. Pensemos simplemente que pasa si alguien que nunca tocó esa aplicación, debe corregir un error en el código javascript. ¿Cuánto tiempo le puede insumir llegar hasta el trigger para encontrar el problema? Con suerte, unas cuantas horas, cuando debería haberlo encontrado a los pocos minutos si estuviese donde tiene que estar.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32128398-748615782354563742?l=jose-selesan.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jose-selesan.blogspot.com/feeds/748615782354563742/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=32128398&amp;postID=748615782354563742' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/32128398/posts/default/748615782354563742'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/32128398/posts/default/748615782354563742'/><link rel='alternate' type='text/html' href='http://jose-selesan.blogspot.com/2007/10/separacin-de-responsabilidades.html' title='Separación de responsabilidades'/><author><name>Jose Selesan</name><uri>http://www.blogger.com/profile/06083003603043488677</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='15604937777563746127'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-32128398.post-2835167697136568143</id><published>2007-10-09T09:54:00.000-03:00</published><updated>2007-10-09T11:06:39.115-03:00</updated><title type='text'>Regreso</title><content type='html'>Después de un tiempo de inactividad, estoy tratando de volver a escribir un poco más y con mayor frecuencia. En este tiempo he estado trabajando y escribiendo sobre tecnlogías que si bien no son novedosas (particularmente MonoRail y todo el proyecto Castle), siempre es bueno compartir experiencias.&lt;br /&gt;&lt;br /&gt;Así que aquí estaremos, tratando de aportar un granito más de arena a la gran montaña de confusión que es el mundo del desarrollo de aplicaciones de software.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32128398-2835167697136568143?l=jose-selesan.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jose-selesan.blogspot.com/feeds/2835167697136568143/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=32128398&amp;postID=2835167697136568143' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/32128398/posts/default/2835167697136568143'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/32128398/posts/default/2835167697136568143'/><link rel='alternate' type='text/html' href='http://jose-selesan.blogspot.com/2007/10/regreso.html' title='Regreso'/><author><name>Jose Selesan</name><uri>http://www.blogger.com/profile/06083003603043488677</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='15604937777563746127'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-32128398.post-1855851043032211262</id><published>2007-02-23T20:48:00.001-03:00</published><updated>2007-02-23T20:48:30.087-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Otra categoría sin categorizar'/><title type='text'>Performancing en FireFox</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;Cada día que pasa me gusta más Firefox. Hoy descubrí un addon que se llama &lt;b&gt;Performancing. &lt;/b&gt;Este addon es simplemente un editor para postear en blogs. Qué es lo más interesante? pesa alrededor de 200 kb, se baja en segundos y se configura muy fácil. Acabo de bajarlo y en menos de un minuto ya lo tenía configurado para postear en Blogger. &lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;Hay que reconocer que la gente que está trabajando alrededor de Firefox, está haciendo un trabajo espectacular.&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;&lt;small&gt;&lt;small&gt;Este post fue enviado con Performancing&lt;/small&gt;&lt;/small&gt;&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;&lt;p class='poweredbyperformancing'&gt;powered by &lt;a href='http://performancing.com/firefox'&gt;performancing firefox&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32128398-1855851043032211262?l=jose-selesan.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jose-selesan.blogspot.com/feeds/1855851043032211262/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=32128398&amp;postID=1855851043032211262' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/32128398/posts/default/1855851043032211262'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/32128398/posts/default/1855851043032211262'/><link rel='alternate' type='text/html' href='http://jose-selesan.blogspot.com/2007/02/performancing-en-firefox.html' title='Performancing en FireFox'/><author><name>Jose Selesan</name><uri>http://www.blogger.com/profile/06083003603043488677</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='15604937777563746127'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-32128398.post-7396245211961266155</id><published>2007-01-24T09:05:00.000-03:00</published><updated>2007-01-24T09:29:10.118-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ASP.Net'/><title type='text'>ASP.Net Ajax ya es release</title><content type='html'>&lt;span style="font-family: verdana;"&gt;Así lo anunció ayer Scott Gu' anunció el lanzamiento de la versión 1.0 de ASP.Net Ajax, junto con la correspondiente versión 1.0 de ASP.Net Ajax Toolkit, que incorporó tres controles interesantes: un textbox con calendario (esto se podía simular con las betas y el RC usando el PupUpExtender, pero había que poner algunas líneas de código), un control tipo TabStrip a puro javascript y un MaskEdit para restringir el ingreso de datos, para alegría de los programadores de la vieja escuela (leáse de Clipper, Fox y demás).&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: verdana;"&gt;Como siempre, la página oficial de ASP.Net Ajax está &lt;/span&gt;&lt;a style="font-family: verdana;" href="http://ajax.asp.net"&gt;acá.&lt;/a&gt;&lt;br /&gt;&lt;span style="font-family: verdana;"&gt;El post de Scott con el anuncio, lo pueden encontrar &lt;/span&gt;&lt;a style="font-family: verdana;" href="http://weblogs.asp.net/scottgu/archive/2007/01/23/asp-net-ajax-1-0-released.aspx"&gt;acá&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32128398-7396245211961266155?l=jose-selesan.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jose-selesan.blogspot.com/feeds/7396245211961266155/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=32128398&amp;postID=7396245211961266155' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/32128398/posts/default/7396245211961266155'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/32128398/posts/default/7396245211961266155'/><link rel='alternate' type='text/html' href='http://jose-selesan.blogspot.com/2007/01/aspnet-ajax-ya-es-release.html' title='ASP.Net Ajax ya es release'/><author><name>Jose Selesan</name><uri>http://www.blogger.com/profile/06083003603043488677</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='15604937777563746127'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-32128398.post-6013263318562036020</id><published>2007-01-18T08:59:00.000-03:00</published><updated>2007-01-18T09:03:43.660-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ser programador'/><title type='text'>El tamaño sí importa</title><content type='html'>&lt;span style="font-family:verdana;"&gt;Cada vez que tengo que mantener código de otro, o ayudar a alguien con algún fuente, insisto en lo mismo: escribir métodos pequeños. Me he encontrado con métodos de más de 2000 líneas. En este &lt;a href="http://blog.objectmentor.com/articles/2006/12/21/size-matters"&gt;post en Object Mentor&lt;/a&gt;, se comentan algunas de las razones por las que el tamaño de las clases y métodos sí importa, junto con las implicancias que tiene el código demasiado largo.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32128398-6013263318562036020?l=jose-selesan.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jose-selesan.blogspot.com/feeds/6013263318562036020/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=32128398&amp;postID=6013263318562036020' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/32128398/posts/default/6013263318562036020'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/32128398/posts/default/6013263318562036020'/><link rel='alternate' type='text/html' href='http://jose-selesan.blogspot.com/2007/01/el-tamao-s-importa.html' title='El tamaño sí importa'/><author><name>Jose Selesan</name><uri>http://www.blogger.com/profile/06083003603043488677</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='15604937777563746127'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-32128398.post-6948807713776807649</id><published>2006-10-23T08:27:00.000-03:00</published><updated>2006-10-23T08:48:21.427-03:00</updated><title type='text'>Separación de UI y Logica en Ajax</title><content type='html'>&lt;span style="font-family:verdana;"&gt;Algo que ya muchos criticaron sobre Ajax (en particular sobre Ajax Library, o sea ATLAS) es que implica un uso bastante intensivo de JavaScript del innerHTML&lt;/span&gt;  para actualizar la UI luego de llamar a WebServices desde el lado del cliente.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: verdana;"&gt;En respuesta a eso, Scott Gu escribió este &lt;/span&gt;&lt;a style="font-family: verdana;" href="http://weblogs.asp.net/scottgu/archive/2006/10/22/Tip_2F00_Trick_3A00_-Cool-UI-Templating-Technique-to-use-with-ASP.NET-AJAX-for-non_2D00_UpdatePanel-scenarios.aspx"&gt;excelente post&lt;/a&gt;&lt;span style="font-family: verdana;"&gt; con una propuesta de solución que me pareció muy buena. Sin embargo, despues de bajarme el codigo y darle una mirada, veo que hace uso de Reflection para pasarle datos al control que usa para renderizar la vista. Todos sabemos que Reflection es una gran herramienta, pero puede tener algunos problemas de redimiento y que deberíamos evitarlo siempre que sea posible. Y en este caso es posible.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: verdana;"&gt;Mi solución es la siguiente. Por un lado, definir una interfaz que exponga una propiedad para pasarle los datos al control:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt; &lt;div class="code"&gt;&lt;br /&gt;&lt;span style="color:blue;"&gt;public interface &lt;/span&gt;&lt;span style="color:black;"&gt;IDataView&lt;br /&gt;{&lt;br /&gt;  &lt;/span&gt;&lt;span style="color:blue;"&gt;object &lt;/span&gt;&lt;span style="color:black;"&gt;Data { &lt;/span&gt;&lt;span style="color:blue;"&gt;get; set; &lt;/span&gt;&lt;span style="color:black;"&gt;}&lt;br /&gt;}&lt;/span&gt;&lt;br /&gt; &lt;/div&gt;&lt;br /&gt;&lt;span style="font-family: verdana;"&gt;Luego, cada control que querramos renderizar desde el ViewManager, deberá implementar la interfaz IDataView:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="code"&gt;&lt;br /&gt;&lt;span style="color:blue;"&gt;public &lt;/span&gt;&lt;span style="color:black;"&gt;partial &lt;/span&gt;&lt;span style="color:blue;"&gt;class &lt;/span&gt;&lt;span style="color:black;"&gt;App_Views_Customers : System.Web.UI.UserControl, IDataView&lt;br /&gt;{&lt;br /&gt;   &lt;/span&gt;&lt;span style="color:blue;"&gt;protected void &lt;/span&gt;&lt;span style="color:black;"&gt;Page_Load(&lt;/span&gt;&lt;span style="color:blue;"&gt;object &lt;/span&gt;&lt;span style="color:black;"&gt;sender, EventArgs e)&lt;br /&gt;   {&lt;br /&gt;       Repeater1.DataSource &lt;/span&gt;&lt;span style="color:blue;"&gt;= &lt;/span&gt;&lt;span style="color:black;"&gt;Data&lt;/span&gt;&lt;span style="color:blue;"&gt;;&lt;br /&gt;       &lt;/span&gt;&lt;span style="color:black;"&gt;Repeater1.DataBind()&lt;/span&gt;&lt;span style="color:blue;"&gt;;&lt;br /&gt;   &lt;/span&gt;&lt;span style="color:black;"&gt;}&lt;br /&gt;&lt;br /&gt;   &lt;/span&gt;&lt;span style="color:blue;"&gt;private object &lt;/span&gt;&lt;span style="color:black;"&gt;data&lt;/span&gt;&lt;span style="color:blue;"&gt;;&lt;br /&gt;   public object &lt;/span&gt;&lt;span style="color:black;"&gt;Data&lt;br /&gt;   {&lt;br /&gt;       &lt;/span&gt;&lt;span style="color:blue;"&gt;get &lt;/span&gt;&lt;span style="color:black;"&gt;{ &lt;/span&gt;&lt;span style="color:blue;"&gt;return &lt;/span&gt;&lt;span style="color:black;"&gt;data&lt;/span&gt;&lt;span style="color:blue;"&gt;; &lt;/span&gt;&lt;span style="color:black;"&gt;}&lt;br /&gt;       &lt;/span&gt;&lt;span style="color:blue;"&gt;set &lt;/span&gt;&lt;span style="color:black;"&gt;{ data &lt;/span&gt;&lt;span style="color:blue;"&gt;= value; &lt;/span&gt;&lt;span style="color:black;"&gt;}&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/span&gt; &lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: verdana;"&gt;Por último modifiqué la clase ViewManager para que no use Reflection sino que requiera que el control sea también un IDataView:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="code"&gt;&lt;span style="color:blue;"&gt;public class &lt;/span&gt;&lt;span style="color:black;"&gt;ViewManager&lt;br /&gt;{&lt;br /&gt;    &lt;/span&gt;&lt;span style="color:blue;"&gt;public static string &lt;/span&gt;&lt;span style="color:black;"&gt;RenderView(&lt;/span&gt;&lt;span style="color:blue;"&gt;string &lt;/span&gt;&lt;span style="color:black;"&gt;path)&lt;br /&gt;    {&lt;br /&gt;        &lt;/span&gt;&lt;span style="color:blue;"&gt;return &lt;/span&gt;&lt;span style="color:black;"&gt;RenderView(path, &lt;/span&gt;&lt;span style="color:blue;"&gt;null&lt;/span&gt;&lt;span style="color:black;"&gt;)&lt;/span&gt;&lt;span style="color:blue;"&gt;;&lt;br /&gt;    &lt;/span&gt;&lt;span style="color:black;"&gt;}&lt;br /&gt;&lt;br /&gt;    &lt;/span&gt;&lt;span style="color:blue;"&gt;public static string &lt;/span&gt;&lt;span style="color:black;"&gt;RenderView(&lt;/span&gt;&lt;span style="color:blue;"&gt;string &lt;/span&gt;&lt;span style="color:black;"&gt;path, &lt;/span&gt;&lt;span style="color:blue;"&gt;object &lt;/span&gt;&lt;span style="color:black;"&gt;data)&lt;br /&gt;    {&lt;br /&gt;        Page pageHolder &lt;/span&gt;&lt;span style="color:blue;"&gt;= new &lt;/span&gt;&lt;span style="color:black;"&gt;Page()&lt;/span&gt;&lt;span style="color:blue;"&gt;;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color:black;"&gt;UserControl viewControl &lt;/span&gt;&lt;span style="color:blue;"&gt;= &lt;/span&gt;&lt;span style="color:black;"&gt;(UserControl) pageHolder.LoadControl(path)&lt;/span&gt;&lt;span style="color:blue;"&gt;;&lt;br /&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color:black;"&gt;SetData(viewControl &lt;/span&gt;&lt;span style="color:blue;"&gt;as &lt;/span&gt;&lt;span style="color:black;"&gt;IDataView, data)&lt;/span&gt;&lt;span style="color:blue;"&gt;;&lt;br /&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color:black;"&gt;pageHolder.Controls.Add(viewControl)&lt;/span&gt;&lt;span style="color:blue;"&gt;;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color:black;"&gt;StringWriter output &lt;/span&gt;&lt;span style="color:blue;"&gt;= new &lt;/span&gt;&lt;span style="color:black;"&gt;StringWriter()&lt;/span&gt;&lt;span style="color:blue;"&gt;;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color:black;"&gt;HttpContext.Current.Server.Execute(pageHolder, output, &lt;/span&gt;&lt;span style="color:blue;"&gt;false&lt;/span&gt;&lt;span style="color:black;"&gt;)&lt;/span&gt;&lt;span style="color:blue;"&gt;;&lt;br /&gt;&lt;br /&gt;        return &lt;/span&gt;&lt;span style="color:black;"&gt;output.ToString()&lt;/span&gt;&lt;span style="color:blue;"&gt;;&lt;br /&gt;    &lt;/span&gt;&lt;span style="color:black;"&gt;}&lt;br /&gt;&lt;br /&gt;    &lt;/span&gt;&lt;span style="color:blue;"&gt;private static void &lt;/span&gt;&lt;span style="color:black;"&gt;SetData(IDataView view, &lt;/span&gt;&lt;span style="color:blue;"&gt;object &lt;/span&gt;&lt;span style="color:black;"&gt;data)&lt;br /&gt;    {&lt;br /&gt;        view.Data &lt;/span&gt;&lt;span style="color:blue;"&gt;= &lt;/span&gt;&lt;span style="color:black;"&gt;data&lt;/span&gt;&lt;span style="color:blue;"&gt;;&lt;br /&gt;    &lt;/span&gt;&lt;span style="color:black;"&gt;}&lt;br /&gt;&lt;br /&gt;}&lt;/span&gt;&lt;br /&gt; &lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: verdana;"&gt;Con esto, no solo eliminamos el uso de Reflection sino que el código quedó más claro, más OO y al no acceder a un campo por su nombre como variable, quedó más seguro ya que permite verificar todo en tiempo de compilación.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32128398-6948807713776807649?l=jose-selesan.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jose-selesan.blogspot.com/feeds/6948807713776807649/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=32128398&amp;postID=6948807713776807649' title='1 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/32128398/posts/default/6948807713776807649'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/32128398/posts/default/6948807713776807649'/><link rel='alternate' type='text/html' href='http://jose-selesan.blogspot.com/2006/10/separacin-de-ui-y-logica-en-ajax.html' title='Separación de UI y Logica en Ajax'/><author><name>Jose Selesan</name><uri>http://www.blogger.com/profile/06083003603043488677</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='15604937777563746127'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-32128398.post-5898824883501596240</id><published>2006-10-05T20:51:00.000-03:00</published><updated>2006-10-05T20:54:58.930-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ASP.Net'/><category scheme='http://www.blogger.com/atom/ns#' term='Mis Articulos'/><title type='text'>Artículo sobre ATLAS</title><content type='html'>Hoy vio la luz el número de octubre de &lt;a href="http://www.levelextreme.net"&gt;Level Extreme&lt;/a&gt;, que en esta oportunidad incluye un &lt;a href="http://www.levelextreme.net/wconnect/wc.dll?10,7,10,94"&gt;artículo mío&lt;/a&gt; sobre ASP.Net Ajax Library, es decir, ATLAS.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:verdana;"&gt;Fue muy interesante escribir este artículo porque si bien ya hace un buen tiempo que vengo experimentando con ATLAS, solamente había usado los controles del lado del servidor (principalmente el UpdatePanel), y para poder profundizar un poco en el tema, tuve que hacer unas pruebas con web services y realmente me pareció muy cómodo y sencillo de usar.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32128398-5898824883501596240?l=jose-selesan.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jose-selesan.blogspot.com/feeds/5898824883501596240/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=32128398&amp;postID=5898824883501596240' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/32128398/posts/default/5898824883501596240'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/32128398/posts/default/5898824883501596240'/><link rel='alternate' type='text/html' href='http://jose-selesan.blogspot.com/2006/10/artculo-sobre-atlas.html' title='Artículo sobre ATLAS'/><author><name>Jose Selesan</name><uri>http://www.blogger.com/profile/06083003603043488677</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='15604937777563746127'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-32128398.post-115998469393040969</id><published>2006-10-04T14:32:00.000-03:00</published><updated>2006-10-04T14:58:14.226-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='puntoNet'/><title type='text'>Variables static en VB.Net</title><content type='html'>&lt;span style="font-family:verdana;"&gt;Hoy me hicieron la siguiente pregunta: "¿Que diferencia hay en Visual Basic .Net entre &lt;span style="FONT-STYLE: italic"&gt;shared&lt;/span&gt; y &lt;span style="FONT-STYLE: italic"&gt;static&lt;/span&gt;?". Como soy un programador de C# y no de ese otro lenguaje feo atiné a responder que static es lo mismo que shared, pero en C#. Pero como mi interlocutor no quedó muy satisfecho con la respuesta, tras unos minutos de lectura me vengo a enterar que en VB.Net, una variable local a un método puede tener el modificador &lt;span style="FONT-STYLE: italic"&gt;static&lt;/span&gt;, lo que hace que mantenga el valor entre llamadas. Es decir, si tenemos algo así:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Public&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:courier new;"&gt; Sub Metodo1()&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Static Dim contador as Integer&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;contador = contador + 1&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Console.WriteLine(contador)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;End Sub&lt;br /&gt;&lt;br /&gt;Public Sub Metodo2()&lt;br /&gt;Metodo1()&lt;br /&gt;Metodo1()&lt;br /&gt;End Sub&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:verdana;"&gt;Como resultado, tendremos en la consola los valores 1 y 2, ya que la variable "contador" mantiene su valor entre una y otra llamada al método.&lt;br /&gt;&lt;br /&gt;Ahora bien, ¿de que sirve esto en un leguaje orientado a objetos? La misma funcionalidad se puede resolver perfectamente con el uso de un atributo privado de la clase: (lo escribo en C# porque ya fue suficiente VB.Net por hoy)&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;private int contador;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;public void Metodo1()&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Console.WriteLine(++contador);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;public void Metodo2()&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Metodo1();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Metodo1();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Obviamente, C# que es un leguaje bien hecho, no tiene un equivalente al &lt;span style="FONT-STYLE: italic"&gt;static&lt;/span&gt; de VB.Net. Esto no hace más que reafirmar mi idea de que VB.Net es un leguaje feo, que arrastra todos los problemas de diseño de un lenguaje de programación desde sus primeras versiones y que permite escribir código muy mal estructurado (y que los programadores de VB.Net de alguna manera u otra se las arreglan para usar todas las cosas de VB.Net que no deberían usar para que el código quede bien escrito).&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32128398-115998469393040969?l=jose-selesan.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jose-selesan.blogspot.com/feeds/115998469393040969/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=32128398&amp;postID=115998469393040969' title='3 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/32128398/posts/default/115998469393040969'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/32128398/posts/default/115998469393040969'/><link rel='alternate' type='text/html' href='http://jose-selesan.blogspot.com/2006/10/variables-static-en-vbnet.html' title='Variables static en VB.Net'/><author><name>Jose Selesan</name><uri>http://www.blogger.com/profile/06083003603043488677</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='15604937777563746127'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-32128398.post-115955467348113365</id><published>2006-09-29T15:09:00.000-03:00</published><updated>2006-09-29T15:31:13.490-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Desarrollo Agil'/><title type='text'>Estimar tiempos no es como jugar al golf</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://images.amazon.com/images/P/0201794276.01._AA240_SCLZZZZZZZ_V53286521_.jpg"&gt;&lt;img style="FLOAT: right; MARGIN: 0pt 0pt 10px 10px; WIDTH: 200px; CURSOR: pointer" alt="" src="http://images.amazon.com/images/P/0201794276.01._AA240_SCLZZZZZZZ_V53286521_.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="font-family:verdana;"&gt;Hace unos días empecé a leer &lt;a href="http://www.amazon.com/Extreme-Programming-Projects-Doug-Wallace/dp/0201794276/ref=sr_11_1/104-2339206-5954334?ie=UTF8"&gt;Extreme Programming for Web Projects&lt;/a&gt;&lt;/span&gt;, &lt;span style="font-family:verdana;"&gt;un librito bastante entretenido y de lecutra liviana que, como su título lo indica trata de como enfrentar proyectos de desarrollo de aplicaciones web siguiendo técnicas de desarrollo ágil.&lt;br /&gt;&lt;br /&gt;A grandes rasgos, los temas tratados no difieren en absoluto a los de cualquier libro/articulo/sitio web sobre metodologías ágiles, salvo por los capítulos donde los autores abordan temas relacionados con las particularidades del desarrollo web, como los son el diseño gráfico de la aplicación y el uso de XML.&lt;br /&gt;&lt;br /&gt;Hay un capítulo en el que se hace una analogía entre la estimación de tiempos y un juego de golf y quería comentarla porque me pareció interesante el planteo (aunque no sea más que otra forma de plantear el problema que todos conocemos). Parafraseando (y traduciendo) a los autores, pensemos en el desarrollo de software como un juego de golf en el que tenemos un objetivo (el hoyo), pero está bastante lejos y no podemos verlo. Nuestro cliente puede decirnos que el hoyo está a 130 metros de donde estamos, y al centro de un &lt;a href="http://elmundodeporte.elmundo.es/elmundodeporte/golf/diccionario.html"&gt;dogleg&lt;/a&gt;. Los miembros del equipo ya han jugado al golf antes y nos advierten que en el medio podría haber obstáculos, como lagunas o tramas de arena. Entonces, ¿qué tan fuerte le pegamos a la pelotita?, ¿el viento puede influir?, ¿el cliente realmente sabe donde está el hoyo?, ¿nuestro compañeros de equipo no sabían de un obstaculo que estaba en medio? ¿eh?&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32128398-115955467348113365?l=jose-selesan.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jose-selesan.blogspot.com/feeds/115955467348113365/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=32128398&amp;postID=115955467348113365' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/32128398/posts/default/115955467348113365'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/32128398/posts/default/115955467348113365'/><link rel='alternate' type='text/html' href='http://jose-selesan.blogspot.com/2006/09/estimar-tiempos-no-es-como-jugar-al.html' title='Estimar tiempos no es como jugar al golf'/><author><name>Jose Selesan</name><uri>http://www.blogger.com/profile/06083003603043488677</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='15604937777563746127'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-32128398.post-115808065679212630</id><published>2006-09-12T13:14:00.000-03:00</published><updated>2006-09-12T14:04:24.496-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='puntoNet'/><category scheme='http://www.blogger.com/atom/ns#' term='ASP.Net'/><title type='text'>ATLAS será release en diciembre</title><content type='html'>&lt;span style="font-family:verdana;"&gt;Así es, finalmente el framework ATLAS verá la luz como un producto con soporte y todo a fines de este año, bajo el nombre de "&lt;span style="FONT-WEIGHT: bold"&gt;Microsoft AJAX Library&lt;/span&gt;" y el ATLAS Control Toolkit será bautizado formalmente como &lt;span style="FONT-WEIGHT: bold"&gt;ASP.Net AJAX Control Toolkit.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;Más información en el blog de &lt;a href="http://weblogs.asp.net/scottgu/archive/2006/09/11/_2200_Atlas_2200_-1.0-Naming-and-Roadmap.aspx"&gt;Scott Guthrie&lt;/a&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32128398-115808065679212630?l=jose-selesan.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jose-selesan.blogspot.com/feeds/115808065679212630/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=32128398&amp;postID=115808065679212630' title='1 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/32128398/posts/default/115808065679212630'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/32128398/posts/default/115808065679212630'/><link rel='alternate' type='text/html' href='http://jose-selesan.blogspot.com/2006/09/atlas-ser-release-en-diciembre.html' title='ATLAS será release en diciembre'/><author><name>Jose Selesan</name><uri>http://www.blogger.com/profile/06083003603043488677</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='15604937777563746127'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-32128398.post-115806150806610762</id><published>2006-09-12T08:30:00.000-03:00</published><updated>2006-09-12T08:45:08.076-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='puntoNet'/><category scheme='http://www.blogger.com/atom/ns#' term='Mis Articulos'/><title type='text'>Otro artículo de Mocks</title><content type='html'>&lt;span style="font-family:verdana;"&gt;Ayer salió el nuevo número de &lt;a href="http://www.levelextreme.net"&gt;LevelExtreme&lt;/a&gt;&lt;/span&gt; &lt;span style="font-family:verdana;"&gt;donde salió publicado &lt;a href="http://www.levelextreme.net/wconnect/wc.dll?10,7,10,81"&gt;otro artículo mío&lt;/a&gt;, esta vez sobre pruebas de interacción con mock objects.&lt;br /&gt;&lt;br /&gt;Como podrán ver en el artículo, la idea es parecida a la de otros artículos sobre mocks, pero esta vez, lo que se debe probar es que la aplicación reacciona bien ante los datos enviados por una balanza electrónica de camiones y aplica &lt;/span&gt;&lt;span style="font-family:verdana;"&gt;correctamente las reglas de negocios.&lt;br /&gt;&lt;br /&gt;Despues de leer el artículo (y dejar algún comentarió &lt;span style="FONT-WEIGHT: bold"&gt;acá&lt;/span&gt;), los inviton a que le den una mirada al blog del autor de los Rhino Mocks (&lt;a href="http://www.ayende.com/blog"&gt;www.ayende.com/Blog&lt;/a&gt;), qué está haciendo un excelente trabajo, en especial con la librería RhinoCommons (que dicho sea de paso, ya recibió algunos aportes míos).&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32128398-115806150806610762?l=jose-selesan.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jose-selesan.blogspot.com/feeds/115806150806610762/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=32128398&amp;postID=115806150806610762' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/32128398/posts/default/115806150806610762'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/32128398/posts/default/115806150806610762'/><link rel='alternate' type='text/html' href='http://jose-selesan.blogspot.com/2006/09/otro-artculo-de-mocks.html' title='Otro artículo de Mocks'/><author><name>Jose Selesan</name><uri>http://www.blogger.com/profile/06083003603043488677</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='15604937777563746127'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry></feed>