jueves, 23 de julio de 2009

Mensajes y formato de strings

Ahora que descubrí la función Format() en GeneXus y que la empecé a usar... creo que se le podría hacer una mejora.

La mayoría de las veces, cuando armamos un string, lo queremos para mostrar un mensaje. Muchas veces es para pasárselo a la función msg() o a la función error().

Algo así:
&mensaje = Format('El pedido número %1 fue confirmado', PedidoId.ToString())
msg(&mensaje)
o simplemente
msg( Format('El pedido número %1 fue confirmado', PedidoId.ToString()) )
Sería más práctico e intuitivo, que las funciones msg() y error() recibieran una cantidad variable de parámetros y se comportaran como la función Format().

El código quedaría entonces más simple:
msg( 'El pedido número %1 fue confirmado', PedidoId.ToString() )

lunes, 13 de julio de 2009

Mejoras al lenguaje en C# 3.0 y 4.0

Antes de empezar, conviene aclarar que no me considero un experto en C# ni mucho menos, pero sí tengo algo de experiencia con el lenguaje. De hecho podría decir que C# es mi segundo lenguaje después de GeneXus...

El uso que le he dado principalmente ha sido para desarrollar extensiones de GeneXus o aplicaciones que usan GXPublic. Alguna vez hice algo en ASP.Net pero nada demasiado sofisticado.

El tema es que para el uso que le doy habitualmente, me alcanza con la funcionalidad que tiene Visual Studio 2005, que funciona con C# 2.0, y por lo tanto me he estado perdiendo de las nuevas funcionalidades en C# 3.0 (VS2008) y 4.0 (VS2010, todavía en beta).

Son varias las cosas nuevas en C# 3.0 (LINQ, object initializers, anonymous types, etc.), el artículo de Wikipedia sobre C# explica bastante bien que es cada una de estas cosas.

Hay otras dos funcionalidades nuevas que me gustaron mucho cuando las leí en este artículo de Jomo Fisher (del año 2005, estoy un tanto atrasado): lambda expresions y extension methods. Vale la pena leerlo.

Lo de las expresiones lambda (si reconocen el nombre es porque lo vieron en algún curso de programación funcional) viene como a confirmar lo que decía Paul Graham en Hackers and Painters: que los lenguajes de programación tienden a ir incorporando funcionalidades de LISP...

La otra reflexión es que parece que ahora en C# se podría implementar el algoritmo MapReduce de Google, como lo explica Joel Spolsky en su blog. También vale la pena leerlo.

En C# 4.0 que por lo que se todavía está en beta, agregan soporte para tipos de datos dinámicos, para poder utilizar código generado a partir de lenguajes con tipado dinámico (como ser F# o IronPython). Básicamente el tipo dynamic lo que hace es posponer la resolución de tipos al momento de ejecución.

Otra cosa que está buena son los parámetros opcionales y parámetros por nombre (named parameters, cada uno lo traduce lo mejor que puede...), que permite asignar valores por defecto a algunos de los parámetros que luego no son necesarios en la invocación, y permite pasar los parámetros en cualquier orden siempre que se indique cual es cual por su nombre.

En fin... mucha cosa interesante, hay que tratar de mantenerse actualizado.

martes, 7 de julio de 2009

Global.asax

El problema
Estamos migrando un sitio que estaba generado en .Net en un Windows Server, a uno nuevo generado en Java en un Linux.

El tema es que con el cambio, las URLs cambian, pasan de ser de tipo
http://host/sitio/pagina.aspx?parametros
a ser de tipo
http://host:puerto/sitio/servlet/pagina?parametros
 Entonces, como hacer la migración de forma razonable, sin que haya problemas con los links que llegan al sitio.

Posibles soluciones
Habían varias posibles soluciones:
  • sacar el sitio viejo y en su lugar poner una página de error 404 (not found) con un link al sitio nuevo
  • poner que el IIS haga un redirect al sitio nuevo, pero ahí no se si funciona cuando se accede a una URL que no es la página por defecto
La solución final
En APS.NET existe un archivo de nombre Global.asax, que define algunos métodos que se ejecutan en distintos momentos, como por ejemplo cuando se levanta el sitio, cuando llega un request de una página, cuando se termina de procesar un request, etc.

En particular el evento que me interesa en este caso es el que se dispara cuando se hace un request a una página, ya que ahí puedo hacer el redireccionamiento con inteligencia, mandando al usuario a la página que quería ir con los parámetros que le pasó, pero en el otro sitio.

El archivo Global.asax quedó algo así (*):
<%@ language="C#" %>
<script runat="server">
void Application_BeginRequest(Object sender, EventArgs e)
{
    string request = Request.Url.PathAndQuery;
    int pos = request.LastIndexOf('/');
    request = request.Substring(pos+1);
    request = request.Replace(".aspx", "");
   
    string url = @"http://host:8080/sitio/servlet/" + request;
   
    Response.Redirect(url);
}
</script>

(*) En realidad es un poco más complicada la solución final ya que el host es distinto según se esté dentro de la intranet o fuera, pero eso no viene al caso...