Saltar al contenido

Artículos, tutoriales, trucos, curiosidades, reflexiones y links sobre programación web ASP.NET Core, MVC, Blazor, SignalR, Entity Framework, C#, Azure, Javascript... y lo que venga ;)

17 años online

el blog de José M. Aguilar

Inicio El autor Contactar

Artículos, tutoriales, trucos, curiosidades, reflexiones y links sobre programación web
ASP.NET Core, MVC, Blazor, SignalR, Entity Framework, C#, Azure, Javascript...

¡Microsoft MVP!
domingo, 30 de marzo de 2008
MundoVía Dirson me entero de que Google ha publicado recientemente el API que permite, a base de Ajax, realizar traducciones de textos entre los idiomas contemplados por la herramienta, más de una decena.

Google nos tiene acostumbrados a implementar APIs muy sencillas de usar, y en este caso no podía ser menos. Para demostrarlo, vamos a crear una página web con un sencillo traductor en Javascript, comentando paso por paso lo que hay que hacer para que podáis adaptarlo a vuestras necesidades.

Paso 1: Incluir el API

La inclusión de las funciones necesarias para realizar la traducción es muy sencilla. Basta con incluir el siguiente código, por ejemplo, en la sección HEAD de la página:
  <script type="text/javascript"
src="http://www.google.com/jsapi">
</script>
<script type="text/javascript">
google.load("language", "1");
</script>
 
El primer bloque descarga a cliente la librería javascript Ajax API Loader, el cargador genérico de librerías Ajax utilizado por Google. Éste se usa en el segundo bloque script para cargar, llamando a la función google.load el API "language" (traductor), en su versión 1 (el segundo parámetro).

Paso 2: Creamos el interfaz

Nuestro traductor será realmente simple. Además, vamos a contemplar un pequeño subconjunto de los idiomas permitidos para no complicar mucho el código, aunque podéis añadir todos los que consideréis necesarios.

El resultado será como el mostrado en la siguiente imagen.

Interfaz del traductor

El código fuente completo lo encontraréis al final del post, por lo que no voy a repetirlo aquí. Simplemente indicar que tendremos un TextArea donde el usuario introducirá el texto a traducir, dos desplegables con los idiomas origen y destino de la traducción, y un botón que iniciará la acción a través del evento onclick. Por último, se reservará una zona en la que insertaremos el resultado de la traducción.

Ah, un detalle interesante: en el desplegable de idiomas de origen se ha creado un elemento en el desplegable "Auto", cuyo valor es un string vacío; esto indicará al motor de traducción que infiera el idioma a partir del texto enviado.

Paso 3: ¡Traducimos!

La pulsación del botón provocará la llamada a la función Onclick(), desde donde se realizará la traducción del texto introducido en el TextArea.

Como podréis observar en el código, en primer lugar obtendremos los valores de los distintos parámetros, el texto a traducir y los idiomas origen y destino, y lo introducimos en variables para facilitar su tratamiento.
  var text    = document.getElementById("text").value;
var srcLang = document.getElementById("srcLang").value;
var dstLang = document.getElementById("dstLang").value;
 
Acto seguido, realizamos la llamada al traductor. El primer parámetro será el texto a traducir, seguido de los idiomas (origen y destino), y por último se introduce la función callback que será invocada cuando finalice la operación; hay que tener en cuenta que la traducción es realizada a través de una llamada asíncrona a los servidores de Google:

google.language.translate(text, srcLang, dstLang, function(result)
{
if (!result.error)
{
var resultado = document.getElementById("result");
resultado.innerHTML = result.translation;
}
else alert(result.error.message);
}
);
 
Como podéis observar, y es quizás lo único extraño que tiene esta instrucción, el callback se ha definido como una función anónima definida en el espacio del mismo parámetro (podéis ver otro ejemplo de este tipo de funciones cuando explicaba cómo añadir funciones con parámetros al evento OnLoad).

Para los queráis jugar con esto directamente, ahí va el código listo para un copiar y pegar.

<html>
<head>
<title>Traductor</title>
<script type="text/javascript" src="http://www.google.com/jsapi"></script>
<script type="text/javascript">
google.load("language", "1");
</script>
</head>

<body>
<textarea id="text" rows="8" cols="40">Hi, how are you?</textarea>
<br />
<button onclick="onClick()">
Traducir</button>
Del idioma
<select id="srcLang">
<option value="">(Auto)</option>
<option value="es">Español</option>
<option value="en">Inglés</option>
<option value="fr">Francés</option>
</select>
Al
<select id="dstLang">
<option value="es">Español</option>
<option value="en">Inglés</option>
<option value="fr">Francés</option>
</select>
<h3>Traducción:</h3>
<div id="result">
(Introduce un texto)
</div>
</body>
<script type="text/javascript">
function onClick()
{
// obtenemos el texto y los idiomas origen y destino
var text = document.getElementById("text").value;
var srcLang = document.getElementById("srcLang").value;
var dstLang = document.getElementById("dstLang").value;

// llamada al traductor
google.language.translate(text, srcLang, dstLang, function(result)
{
if (!result.error)
{
var resultado = document.getElementById("result");
resultado.innerHTML = result.translation;
}
else alert(result.error.message);
}
);
}
</script>
</html>
 


Enlaces: Página oficial de documentación del API

Publicado en: www.variablenotfound.com.
lunes, 24 de marzo de 2008
Actualizado el 25/4/09:
Existe una versión de este post ampliada y actualizada a la versión 1.0 de ASP.NET MVC: ASP.NET MVC: trece preguntas básicas
Varios lectores y amigos me han hecho llegar algunas cuestiones sobre el nuevo ASP.Net MVC Framework, y en vez de responder de forma individual, creo que es más interesante realizar un post recopilatorio e intentar que las respuestas puedan ayudar a más desarrolladores. Aprovecho para añadir cuestiones de mi propia cosecha, esperando que también puedan aclarar algo.

<disclaimer>
Algunas de las respuestas podríamos considerarlas como beta, y pueden variar con el tiempo. Son opiniones, ideas y conjeturas sobre un producto nuevo y que todavía está en desarrollo, así que usadlas con precaución. ;-)
</disclaimer>

1. Empecemos desde el principio, ¿qué es MVC?

Aunque de forma algo simplista, podríamos definir MVC como un patrón arquitectural que describe una forma de desarrollar aplicaciones software separando los componentes en tres grupos (o capas):
  • El Modelo que contiene una representación de los datos que maneja el sistema, su lógica de negocio, y sus mecanismos de persistencia.
  • La Vista, o interfaz de usuario, que compone la información que se envía al cliente y los mecanismos interacción con éste.
  • El Controlador, que actúa como intermediario entre el Modelo y la Vista, gestionando el flujo de información entre ellos y las transformaciones para adaptar los datos a las necesidades de cada uno.
MVC son las siglas de Modelo-Vista-Controlador, y se trata de un modelo muy maduro y que ha demostrado su validez a lo largo de los años en todo tipo de aplicaciones.

Puedes encontrar más información en:

2. ¿Qué ventajas tiene el uso del patrón MVC?

Como siempre, esto de enumerar ventajas es algo subjetivo, por lo que puede que pienses que falta o sobra alguna (¡dímelo!). En un primer asalto, podríamos aportar las siguientes:
  • Clara separación entre interfaz, lógica de negocio y de presentación, que además provoca parte de las ventajas siguientes.
  • Sencillez para crear distintas representaciones de los mismos datos.
  • Facilidad para la realización de pruebas unitarias de los componentes, así como de aplicar desarrollo guiado por pruebas (TDD).
  • Reutilización de los componentes.
  • Simplicidad en el mantenimiento de los sistemas.
  • Facilidad para desarrollar prototipos rápidos.
  • Los desarrollos suelen ser más escalables.
Pero bueno, también se pueden citar algunos inconvenientes:
  • Tener que ceñirse a una estructura predefinida, lo que a veces puede incrementar la complejidad del sistema. Hay problemas que son más difíciles de resolver respetando el patrón MVC.
  • La curva de aprendizaje para los nuevos desarrolladores se estima mayor que la de modelos más simples como Webforms.
  • La distribución de componentes obliga a crear y mantener un mayor número de ficheros.

3. ¿Qué es ASP.Net MVC Framework?

Es un framework, un entorno de trabajo que está creando Microsoft, que nos ayudará a desarrollar aplicaciones que sigan la filosofía MVC sobre ASP.Net. Su versión final incluirá librerías (ensamblados), plantillas y herramientas que se integrarán en Visual Studio 2008. ScottGu, en su presentación del framework el pasado Octubre en las conferencias Alt.Net, ya adelantó las principales características, y puedes ampliar información en la página oficial.

Actualmente (marzo 2008) puede descargarse la Preview 2 del framework, e incluso su código fuente ha sido publicado en CodePlex. Aunque "de fábrica" no soporta las versiones Express de Visual Studio, en este mismo blog puedes encontrar algunas plantillas y ejemplos de ASP.NET MVC. También hay quien la ha echado a andar en Mono.

4. ¿Es el primer framework MVC creado para .Net?

No, ni el único. Existen multitud de frameworks MVC para ASP.Net, como MonoRail, Maverick.Net, ProMesh.Net y muchos otros.

5. Como desarrollador de aplicaciones web con ASP.Net, ¿me afectará la llegada de este framework?

No necesariamente. Puedes seguir desarrollando aplicaciones como hasta ahora, con Webforms. Si así lo decides, este nuevo framework no te afectará nada; simplemente, ignóralo.

De todas formas, ya que has leído hasta aquí, permíteme un consejo: aprende MVC framework. Después podrás decidir con conocimiento de causa si te conviene o no.

6. ¿Significa la aparición del framework MVC la muerte próxima de los Webforms de ASP.Net?

En absoluto. Son simplemente dos filosofías diferentes para conseguir lo mismo, ¡páginas web!.

La tecnología de Webforms es muy útil para asemejar el desarrollo de aplicaciones web a las de escritorio, ocultando la complejidad derivada del entorno desconectado y stateless (sin conservación de estado) del protocolo HTTP a base de complejos roundtrips, postbacks y viewstates, lo que nos permite crear de forma muy productiva formularios impresionantes y que el funcionamiento de nuestra aplicación esté guiado por eventos, como si estuvieramos programando Winforms.

Sin embargo, esta misma potencia a veces hace que las páginas sean pesadas y difícilmente mantenibles, y además se dificultan enormemente la realización de pruebas. Y por no hablar de comportamientos extraños cuando intentamos intervenir en el ciclo de vida de las páginas, por ejemplo para la carga y descarga de controles dinámicos.

ASP.Net MVC propone una forma distinta de trabajar, más cercana a la realidad del protocolo y, curiosamente, más parecida a cómo se hacía unos años atrás, cuando controlábamos cada byte que se enviaba al cliente. No existen, por tanto, conceptos como el mantenimiento del estado en el viewstate, ni el postback, ni nos valdrán los controles de servidor basados en estas características, la mayoría. Sin embargo, dado que el framework está creado sobre ASP.Net, será posible utilizar páginas maestras, codificar las vistas en un .aspx utilizando C# o VB.Net, usar los mecanismos de seguridad internos, control de caché, gestión de sesiones, localización, etc; además, seguro que en un futuro no demasiado lejano comenzarán a surgir miles de componentes o controles reutilizables que nos ayudarán a mejorar la productividad.

7. ¿Vale la pena pasarse a ASP.Net MVC o sigo usando Webforms?

Todavía lo estoy estudiando ;-). Hay muchos aspectos a valorar.

No hay que olvidar que los Webforms son una buena opción, tanto como lo han sido hasta ahora. Sobre todo si el equipo de desarrollo tiene ya experiencia creando aplicaciones con esta tecnología y se dispone de controles reutilizables propios o ajenos, deberíamos pensárnoslo antes de dar el salto a ASP.Net MVC. Tened en cuenta que la productividad, al menos inicialmente, va a caer.

Sin embargo, las ventajas de la arquitectura MVC y del propio framework descritas anteriormente son un buen aliciente para comenzar: testing, URLs amigables, separación de aspectos, mantenibilidad... Por otra parte, todavía es pronto para conocer el nivel de las herramientas de desarrollo (a nivel de IDE, librerías de controles, helpers) que aparecerán con la versión final, y las que surgirán desde la propia comunidad de desarrolladores, por lo que no es posible evaluar el impacto en la productividad que tendrá la adopción de esta nueva forma de trabajar.

Y, por cierto, si te preocupa el futuro de los Webforms, has de saber que Microsoft va a seguir dándoles soporte y mejorándolos, como no podía ser de otra forma. Por tanto, de momento no es necesario que bases tu decisión en esto.

8. ¿Se puede utilizar el ASP.Net Ajax con el framework MVC?

De momento parece que no, o al menos no de la forma en que se hace actualmente, dado que los controles de servidor (runat="server"), como el UpdatePanel, no están integrados en este modelo. De hecho, ya ni siquiera tienen sentido los formularios runat="server", por lo que menos aún los controles que dependían de éstos.

Se prevé que se creará un API específico para permitir desde cliente, mediante scripting, hacer llamadas a los controladores, y actualizar porciones de contenido de la página con el marcado que nos envíe la vista correspondiente. Pero esto son sólo conjeturas de momento, ya se irá aclarando conforme el producto se acerque a su versión final.

9. ¿Puedo usar Linq desarrollando aplicaciones con ASP.Net MVC framework?

Sí, de hecho se complementan a la perfección.

Por ejemplo, las clases del modelo podrán generarse de forma automática (y completa para aplicaciones relativamente simples) con los diseñadores visuales de LinqToSQL o LinqToEntities desde Visual Studio 2008 o de forma externa con herramientas como SQLMetal. Además, el controlador podrán utilizar expresiones de consulta para solicitar datos desde el modelo, o enviar datos actualizados usando las capacidades ORM de estas tecnologías.

10. ¿Será ASP.Net MVC framework software libre?

Pues claro que no ;-). Se podrá acceder al código fuente (de hecho, ya se puede), que será distribuido de la misma forma que el de .Net framework, pero no será software libre. Si buscas una solución open source, revisa la pregunta número 4.


Publicado en: http://www.variablenotfound.com/.
domingo, 23 de marzo de 2008
De todos es conocida la afición de Microsoft por poner nombres clave a sus productos durante la etapa de conceptualización y desarrollo, y la verdad es que tiene su gracia. Pero la verdad, a veces es difícil seguirle la pista a posts o conversaciones en foros donde hacen uso intensivo de ellas.

Por ejemplo, ¿recuerdas el nombre en clave de ASP.NET Ajax? ¿Y de Windows 95? ¿Y sabes que tecnología se esconde detrás de Whistler o de Avalon?

Por suerte, en la Wikipedia, que hay de todo, alguien se ha encargado de recoger, si no todos los Codenames, al menos muchos de ellos.

Enlace: List of Microsoft codenames

Publicado en: http://www.variablenotfound.com/.
viernes, 21 de marzo de 2008
Como ya delantó Scottgu hace unas semanas mientras actualizaba el roadmap de este nuevo producto, desde hace unas horas es posible descargar el código fuente del ASP.Net Preview 2 a través de CodePlex. La descarga es una solución para Visual Studio 2008, desde la que se pueden generar los ensamblados de forma directa.

Aunque su licencia no permite redistribuir los binarios resultantes para evitar que posibles versiones alternativas del framework circulen por ahí, es muy interesante, sin duda, ver las "tripas" de esta nueva criatura.

Y, por cierto, también carga en Visual C# 2008 Express Edition...

Publicado en: http://www.variablenotfound.com/.
domingo, 16 de marzo de 2008
Captura de pantalla de la aplicaciónHe adaptado para Visual Web Developer Express una de las aplicaciones de ejemplo para ASP.NET MVC que publicó hace unos días el gran Scott Hanselman en su blog, pues no hay nada como observar código y verlo funcionar para aprender y profundizar en esta nueva tecnología.

Concretamente, se trata de una adaptación de Phil Haack para la CTP2 de una aplicación creada inicialmente por Brad Abrams que muestra un catálogo de productos categorizado, tomados de la clásica base de datos NorthWind (para SQLServer/Express), y permite la creación, edición y eliminación de los mismos (CRUD); en otras palabras, una mini-aplicación completa. El acceso a datos se realiza mediante Linq, y las clases del Modelo se han generado con el diseñador Linq2SQL.

Aparte de la adaptación, he aprovechado para retocarla un poco, y le he añadido algunas funcionalidades y detalles que no estaban implementados. Faltan algunos flequillos, como las validaciones de formularios que todavía no he visto cómo se resuelven en el framework, pero bueno, lo que hay es una base interesante para comenzar o seguir profundizando en esta tecnología.

Podéis descargar el proyecto desde el enlace que encontraréis más abajo. Una vez descomprimido el archivo, abrid la carpeta desde Visual Web Developer Express (opción "Abrir > Abrir sitio web" o "File > Open web site" si tenéis aún la versión en inglés) y listo, podéis pulsar F5 para ejecutar.

Por cierto, no sé si funcionará bien con las versiones "pro" de Visual Studio 2008. Agradecería que si alguien lo prueba en este entorno, me lo comentara.


Enlaces: Proyecto NorthWind Demo para ASP.NET MVC (~2MB)

Publicado en: http://www.variablenotfound.com/.
sábado, 15 de marzo de 2008
Ayer se anunció oficialmente la aparición de la versión 1.0 a través de la web del Proyecto Mono, en el blog de Miguel de Icaza y por supuesto, en la web del equipo de desarrollo de MonoDevelop.

Se trata de un entorno de desarrollo integrado (IDE) para la plataforma .NET en el que el equipo del proyecto Mono anda trabajando desde hace varios años. Su objetivo inicial era facilitar una herramienta libre y gratuita para Linux, MacOS e incluso Windows, que permita la creación de aplicaciones en C# y otros lenguajes .NET, aunque después ha evolucionado hasta convertirse en una plataforma extensible sobre la que podría encajar cualquier tipo de herramienta de desarrollo.

Las principales características de la herramienta son:


  • Se trata de un entorno muy personalizable, permitiendo la creación de atajos de teclado, la redistribución de elementos en pantalla o inclusión de herramientas externas.
  • Soporta varios lenguajes, como C#, VB.Net o C/C++ o incluso Boo y Java (IKVM) a través de plugins externos.
  • Ayuda en la escritura del código (auto-completar, información de parámetros... al más puro estilo intellisense).
  • Incluye herramientas de refactorización, como renombrado de tipos y miembros, encapsulación de campos, sobreescritura de métodos o autoimplementación de interfaces.
  • Ayudas en la navegación a través del código, como saltar a las declaraciones de variables, o búsquedas de clases derivadas.
  • Diseñador de interfaces para aplicaciones GTK# y soporte para librerías de widgets.
  • Control de versiones integrado, con soporte para Subversion.
  • Pruebas unitarias integradas, utilizando NUnit.
  • Soporte para proyectos ASP.Net.
  • Servidor web integrado (XSP) para pruebas.
  • Explorador y editor de bases de datos integrados (aún en beta).
  • Integración con Monodoc, para la documentación de clases.
  • Soporte para makefiles, tanto para generación como para sincronización.
  • Soporte para formatos de proyecto Visual Studio 2005.
  • Sistema de empaquetado que genera tarballs, código fuente y binarios.
  • Línea de comandos para generar y gestionar proyectos.

  • Soporte para proyectos de localización.
  • Arquitectura extensible a través de plugins.

Información mucho más detallada, eso sí, en inglés, en la web del proyecto.

Publicado en: http://www.variablenotfound.com/.
domingo, 9 de marzo de 2008
Hace unos meses hablaba sobre la posibilidad de manipular la forma en la que el framework almacena por defecto la información para obtener enumeraciones de campos de bits, algo que es muy habitual en programación a bajo nivel. Siguiendo en la misma línea, hoy voy a comentar cómo conseguir uniones en .Net, al más puro estilo C.

Una unión es muy similar a una estructura de datos (struct en C# o Structure en VB.Net), salvo en un detalle: sus componentes se almacenan sobre las mismas posiciones de memoria. O visto desde el ángulo opuesto, una unión podríamos definirla como una porción de memoria donde se guardan varias variables, habitualmente de tipos diferentes. Veamos un ejemplo clásico que nos ayudará a entender el concepto, en un lenguaje cualquiera:
union Ejemplo
{
char caracter; // suponiendo char de 8 bits
byte octeto; // un byte ocupa 8 bits
};

Si declaramos una variable x del tipo Ejemplo, estaremos reservando un espacio de 8 bits al que accederemos desde cualquiera de sus miembros, como vemos a continuación:

x.caracter = 'A';
x.octeto ++;
escribir_char (x.caracter); // mostraría 'B'
escribir_byte (x.octeto); // mostraría 66
 

Pero espera... ¿memoria?... ¿almacenamiento de variables?... ¿pero existe eso en .Net?... Pues sí, aunque lo más normal es que no nos tengamos que enfrentar nunca a ello pues el framework realiza estas tareas por nosotros, hay escenarios en los que es necesario controlar la forma en que la información es almacenada en memoria, como cuando se esté operando a bajo nivel, por ejemplo creando estructuras específicas para llamar al API de Windows, o para facilitar el acceso a posiciones concretas de la información.

Desde la versión 1.1 de la plataforma .Net, disponemos del atributo StructLayout, que nos permite indicar en estructuras y clases cómo queremos representar en memoria la información de sus miembros. Básicamente, podemos indicar que:
  • la información se almacene como el framework considere oportuno (LayoutKind.Auto)
  • que se almacene de forma secuencial, en el mismo orden en el que han sido declarados (LayoutKind.Sequential).
  • que se almacene donde le indiquemos de forma explícita (LayoutKind.Explicit). En este caso, necesitaremos especificar en cada miembro la posición exacta de memoria donde será guardado, utilizando el atributo FieldOffset.

Es este último método el que nos interesa para nuestros propósitos. Si adornamos una estructura con StructLayout(LayoutKind.Explicit) e indicamos en cada uno de sus miembros su desplazamiento (en bytes) dentro del espacio de memoria asignado a la misma, podemos conseguir uniones haciendo que todos ellos comiencen en la misma dirección.

Pasemos a vamos a verlo con un ejemplo en C#. Se trata de una unión a la que podemos acceder tratándola como un carácter unicode, o bien como un entero de 16 bits con signo. Los dos miembros, llamados Caracter y Valor están definidos sobre la misma posición de memoria (desplazamiento cero) en el interior de la estructura:
using System.Runtime.InteropServices;
using System;
namespace PruebaUniones
{
[StructLayout(LayoutKind.Explicit)]
public struct UnionTest
{
[FieldOffset(0)] public char Caracter;
[FieldOffset(0)] public short Valor;
}
class Program
{
public static void Main()
{
UnionTest ut = new UnionTest();
ut.Caracter = 'A';
ut.Valor ++;
Console.WriteLine(ut.Caracter); // Muestra "B"
Console.ReadKey();
return;
}
}
}
 
Ahora usaremos VB.NET para mostrar otro ejemplo un poco más complejo que el anterior, donde usamos una unión para descomponer una palabra de 16 bits en los dos bytes que la componen, permitiendo la manipulación de forma directa e independiente de cada una de las dos visiones del valor almacenado en memoria. Para el ejemplo utilizo una unión dentro de otra, aunque no era estrictamente necesario, para que veáis que esto es posible.

Imports System.Runtime.InteropServices

<StructLayout(LayoutKind.Explicit)> _
Public Structure Union16
<FieldOffset(0)> Dim Word As Int16
<FieldOffset(0)> Dim Bytes As Bytes
End Structure

<StructLayout(LayoutKind.Explicit)> _
Public Structure Bytes
<FieldOffset(0)> Dim Bajo As Byte
<FieldOffset(1)> Dim Alto As Byte
End Structure

Public Class Program
Public Shared Sub main()
Dim u As New Union16
u.Word = 513 ' 513 = 256*1 (Byte alto) + 1 (byte bajo)
u.Bytes.Alto += 1
Console.WriteLine("Word: " & u.Word) ' Muestra 769 (3*256+1)
Console.WriteLine("Byte alto: " & u.Bytes.Alto) ' Muestra 3
Console.WriteLine("Byte bajo: " & u.Bytes.Bajo) ' Muestra 1
Console.ReadKey()
Console.ReadKey()
End Sub
End Class
 
He encontrado un uso muy interesante para esta técnica en Xtreme .Net Talk, donde se muestra un ejemplo de cómo acceder a los componentes de color de un pixel de forma muy eficiente a través de una unión entre el valor ARGB (32 bits) y cada uno de los bytes que lo componen (alfa, rojo, verde y azul).

En cualquier caso no se recomienda el uso de uniones salvo en casos muy concretos, y siempre conociendo bien las implicaciones que puede tener en la estabilidad y mantenibilidad del sistema.

Pero bueno, ¡está bien al menos saber que existen!

Publicado en: http://www.variablenotfound.com/.
jueves, 6 de marzo de 2008
Ayer se publicó la segunda preview del ASP.Net MVC Framework, la plataforma que sin duda será la revolución del año para los desarrolladores de aplicaciones basadas en web sobre tecnología .Net, y he pensado que ya era un buen momento para echarle un vistazo de cerca.

(Para el que todavía ande un poco despistado, puede leer una breve descripción del ASP.Net MVC Framework, convenientemente traducida, en Thinking in .Net).

Una vez descargado el paquete (poca cosa, menos de un mega), procedí a instalarlo, apareciéndome la siguiente ventana de error:

Visual Web Developer Express RTM is not supported by this release. Do you want to continue with the installation?

Esto, además, se confirma en el documento de notas de la versión:
“The new releases provide Visual Studio templates that are not supported in Visual Web Developer 2008 Express Edition. For example, you cannot create an MVC application or Silverlight .xap files by using Visual Web Developer 2008 Express Edition.”

En otras palabras, que la segunda CTP, al igual que la primera, incluye plantillas que no son válidas para la versión Express de Visual Web Developer. Qué contrariedad.

Y es cierto que no está soportada, pero esto no implica que los que utilizamos las versiones light de los entornos de desarrollo estemos condenados a no probar esta nueva tecnología; de hecho es perfectamente posible, aunque no contaremos con todas las ayudas que sí vienen de serie para las versiones más "pro".

Una vez finalizada la instalación, encontré en Google varias páginas (por ejemplo aquí y aquí) donde se facilitaban plantillas, basadas en las originales, que nos permitirían probar la primera CTP sobre la versión express. Lamentablemente, los cambios realizados en la plataforma desde entonces hacen incompatibles estas plantillas con la CTP 2, aunque es posible hacerlas funcionar simplemente siguiendo los pasos detallados en esta página.

Para que no tengáis que perder el tiempo en ello, he creado una plantilla de proyecto Web (en C#) para Visual Web Developer Express 2008 que podéis descargar desde aquí.

Si queréis probar un poco esta tecnología, una vez instalada la segunda preview del ASP.Net MVC Framework, descargad la plantilla y guardarla, sin descomprimir, en la carpeta "Visual Studio 2008/Templates/ProjectTemplates". Lo habitual es que encontréis esta carpeta en "Mis documentos".

Iniciad Visual Web Developer 2008 Express, cread un nuevo sitio web en C# seleccionando la plantilla que habéis incluido, llamada "MVCWebSite", así:

Crear nuevo proyecto seleccionando la plantilla MVCWebSite

Estructura del proyecto ASP.Net MVCEsto creará un proyecto con el web.config correctamente configurado y la estructura de carpetas ideal para una aplicación web de este tipo, lista para salir andando. Por cierto, si al compilar el proyecto os aparece algún problema de referencias a ensamblados de la Preview, sólo debéis añadir a mano (botón derecho sobre el proyecto, añadir referencias) las DLL's que encontraréis en la carpeta donde se haya instalado la CTP, que en mi caso es "C:/Archivos de programa/Microsoft ASP.NET MVC Preview 2/Assemblies"

Y ya no hay nada más que hacer. Si pulsáis la tecla F5, se compilará y en pocos segundos tendréis funcionando un sitio web MVC, con un controlador y algunas vistas, las cuales usan una MasterPage para componer el esqueleto de las páginas. Además, una de ellas, "Links", muestra cómo obtener un parámetro (la lista de enlaces) desde el controlador.



¡Hala, a disfrutarlo!

Publicado en: http://www.variablenotfound.com/.
miércoles, 5 de marzo de 2008
Cuando estamos desarrollando es habitual que tengamos que comentar porciones de código para realizar pruebas. Esto resulta de lo más sencillo cuando programamos en un lenguaje de los habituales como Javascript, C#, Visual Basic o incluso (X)HTML, pues todos ellos disponen de marcadores que hacen que el compilador o intérprete ignore determinadas líneas de código... pero, ¿cómo logramos este efecto si se trata de un archivo .ASPX, donde pueden encontrarse varios de ellos a la vez?

Por ejemplo, dado el siguiente código en el interior de una página ASP.NET, ¿cuál sería la forma correcta de comentarlo?
<script>
var count = <%= borrarRegistros() %>
alert("Borrados: " + count + " registros");
</script>
 
Una primera opción podría ser utilizar la sintaxis Javascript de la siguiente forma:
<script>
/*
var count = <%= borrarRegistros() %>
alert("Borrados: " + count + " registros");
*/
</script>
 
Sin embargo, aunque podría valer en muchas ocasiones, también puede introducir unos efectos laterales considerables. Nótese que aunque el código Javascript (cliente) esté comentado, la función borrarRegistros() sería invocada en el lado del servidor, y su retorno introducido dentro del comentario. De hecho, la página enviada a cliente mostraría un código fuente similar al siguiente (imaginando que el retorno de la función fuera el valor 99):
<script>
/*
var count = 99;
alert("Borrados: " + count + " registros");
*/
</script>
 
Tampoco valdría para nada incluir todo el bloque de script dentro de un comentario HTML (<!-- y -->), por la misma razón que antes. Además, en cualquiera de estos dos casos, estaríamos enviando al cliente la información aunque sea éste el que la ignora a la hora de mostrarla o ejecutarla y, por supuesto, estaríamos ejecutando la función en servidor, lo cual podría causar otros efectos no deseados, como, en nuestro ejemplo, eliminar los registros de una base de datos.

Afortunadamente, ASP.NET dispone de un mecanismo, denominado Server Side Comments (comentarios en el lado del servidor), que permite marcar zonas y hacer que se ignore todo su contenido, sea del tipo que sea, a la hora de procesar la página:
<%-- 
<script>
var count = <%= borrarRegistros() %>
alert("Borrados: " + count + " registros");
</script>

--%>
 
En este caso ni sería ejecutada la función del servidor ni tampoco enviado a cliente el código HTML/Script incluido.

Publicado en: http://www.variablenotfound.com/.
lunes, 3 de marzo de 2008
Manos de afanoso desarrollador trabajandoComo ya venimos comentando hace tiempo, la nueva versión de ambos lenguajes viene repleta de novedades y mejoras pensadas para hacernos la vida más fácil y, por tanto, aumentar la productividad de los desarrolladoradores. Bueno, no sé si fue así o en realidad es que simplemente eran necesarias para Linq y por eso fueron incluidas ;-), pero el caso es que a partir de las versiones 3.0 y 9.0 de C# y VB.NET respectivamente, tenemos a nuestra disposición interesantísimas herramientas que deberíamos conocer para sacar el máximo provecho a nuestro tiempo.

En esta ocasión vamos a centrarnos en los inicializadores de objetos, una nueva característica destinada, entre otras cosas, a ahorrarnos tiempo a la hora de establecer los valores iniciales de los objetos que creemos desde código.

Y es que, hasta ahora, podíamos utilizar dos patrones básicos de inicialización de propiedades al instanciar una clase:
  • que fuera la clase la que realizara esta tarea, ofreciendo al usuario de la misma constructores con distintas sobrecargas cuyos parámetros corresponden con las propiedades a inicializar.
    // Constructor de la clase Persona:
    public Persona(string nombre, string apellidos, int edad, ...)
    {
    this.Nombre = nombre;
    this.Apellidos = apellidos;
    this.Edad = edad;
    ...
    }
    // Uso:
    Persona p = new Persona("Juan", "López", 32, ...);
     
  • o bien dejar esta responsabilidad al usuario, permitiéndole el acceso directo a propiedades o campos del objeto creado.

    // Uso:
    Persona p = new Persona();
    p.Nombre = "Juan";
    p.Apellidos = "López";
    p.Edad = 32;
    ...
     

Cualquiera de las dos formas anteriores, así como de opciones intermedias que combinen ambas ideas, tiene sus ventajas e inconvenientes, pero son igualmente tediosas. Si hablamos de clases con un gran número de propiedades, la cantidad de líneas de código necesarias para realizar una inicialización son realmente importantes.

Los inicializadores de objetos permiten, en C# y VB.Net, realizar esta tarea de forma más sencilla, indicando en la llamada al constructor el valor de las propiedades o campos que deseemos establecer:

// C#:
Persona p = new Persona { Nombre="Juan", Apellidos="López", Edad=32 };


' VB.NET:
Dim p = New Persona With {.Nombre="Luis", .Apellidos="López", .Edad=32 }
 
Los ejemplos anteriores son válidos para clases que admitan constructores sin parámetros, pero, ¿qué ocurre con los demás? Imaginando que el constructor de la clase Persona recibe obligatoriamente dos parámetros, su nombre y apellidos, podríamos instanciar así:

// C#:
Persona p = new Persona ("Luis", "López") { Edad = 32 };


' VB.NET:
Dim p = New Persona ("Luis", "López") With { .Edad = 32 }
 
Aunque es obvio, es importante tener en cuenta que las inicializaciones (la porción de código entre llaves "{" y "}") se ejecutan después del constructor:

// C#:
Persona p = new Persona ("Juan", "Pérez") { Nombre="Luis" };
Console.WriteLine(p.Nombre); // Escribe "Luis"


' VB.NET:
Dim p = New Persona ("Juan", "Pérez") With { .Nombre="Luis" }
Console.WriteLine(p.Nombre); ' Escribe "Luis"
 
Y un último apunte: ¿cómo inicializaríamos propiedades de objetos que a su vez sean objetos que también queremos inicializar? Suponiendo que en nuestra clase Persona hemos incluido una propiedad llamada Domicilio que de tipo Localizacion, podríamos inicializar el bloque completo así:

// C#:
// Se han cortado las líneas para facilitar la lectura
Persona p = new Persona()
{
Nombre = "Juan",
Apellidos = "López",
Edad = 55,
Domicilio = new Localizacion
{
Direccion = "Callejas, 34",
Localidad = "Sevilla",
Provincia = "Sevilla"
}
};


' VB.NET:
' Se han cortado las líneas para facilitar la lectura
Dim p = New Persona() With { _
.Nombre = "Juan", _
.Apellidos = "López", _
.Edad = 55, _
.Domicilio = New Localizacion With { _
.Direccion = "Callejas, 23", _
.Localidad = "Sevilla", _
.Provincia = "Sevilla" _
} _
}
 
En fin, que de nuevo tenemos ante nosotros una característica de estos lenguajes que resulta interesante por sí misma, aunque toda su potencia y utilidad podremos percibirla cuando profundicemos en otras novedades, como los tipos anónimos y Linq... aunque eso será otra historia.

Publicado en: http://www.variablenotfound.com/.