Charla en Second Nug sobre ASP.NET MVC

 

imageLos chicos de Second Nug han tenido la amabilidad de invitarme a dar una charla sobre ASP.NET MVC el próximo martes 6 de octubre, de 19:30 a 21:30 horas, hora peninsular (GMT+2). Y obviamente, no podía rechazar la oportunidad de hablar un rato sobre esta tecnología de desarrollo de aplicaciones web que tanto me gusta. 🙂

Como otros eventos organizados por el grupo, se trata de un Webcast, la asistencia es gratuita y el aforo ilimitado; sólo necesitáis registraros en el sitio web de Microsoft y estar el día de autos frente a un ordenador con conexión a Internet, el software gratuito Live Meeting, y una gran bolsa de palomitas. Dado que el principal objetivo de la sesión será mostrar los conceptos básicos del desarrollo con ASP.NET MVC, no es necesario que contéis con conocimientos previos sobre dicho framework.

La charla será estructurada como entiendo que deben hacerse estas cosas: poca teoría y mucha acción. Primero describiré algo de la filosofía y principios fundamentales, y seguidamente pasaremos a desarrollar una aplicación completa partiendo desde cero (Archivo>Nuevo>Proyecto), aprovechando cada funcionalidad para comentar técnicas y detalles a tener en cuenta al desarrollar con este marco de trabajo.

Espero veros por allí, paso lista 😉

Enlaces:

Publicado en: Variable not found

Inicializar a null propiedades sin tipo

No es algo que ocurra muy frecuentemente, pero en determinadas ocasiones puede ser útil inicializar una propiedad de un tipo anónimo con el valor nulo, por ejemplo:

var conductor = new { Nombre = ”Marisa”, Edad = 34, Auto = “Renault Megane” };
var peaton = new { Nombre = “Juan”, Edad = 43, Auto = null };

En el código anterior se entiende que lo que queremos indicar estableciendo la propiedad Auto a null es que la persona que estamos representando no dispone de automóvil, o bien no conocemos este dato.

Algo muy normal… sino fuera porque el compilador se empeña en abofetearnos con el siguiente error:

Cannot assign <null> to anonymous type property

Y la verdad, en cuanto lo pensamos un poco, tiene sentido. En los casos anteriores, se está instanciando un tipo anónimo cuyas propiedades son generadas en tiempo de compilación. En el caso anterior, el compilador crearía para el tipo anónimo una propiedad “Nombre” de tipo string, una “Edad” de tipo integer, y una “Auto”, de tipo… ¿qué tipo podría asignar el compilador a esta propiedad? Ese es precisamente el problema.

Lo mismo ocurre al intentar inicializar variables implícitamente tipadas con el valor nulo; aunque cambia el error, el concepto idéntico, el compilador no es capaz de inferir el tipo de la variable:

var persona = null; // Error: Cannot assign <null> to an implicitly-typed local variable

La forma de solucionarlo en ambos casos es muy sencilla: basta con informar explícitamente al compilador del tipo de la propiedad, para que pueda crearla sin problema, por ejemplo así:

var peaton = new { Nombre = "Juan", Edad = 43, Auto = (string)null };

var persona = null as Persona;

Publicado en: Variable not found

Más javascript en la red: Microsoft Ajax CDN

 

Logo de ASP.NET Ajax Hace unos meses comentaba la posibilidad de utilizar la infraestructura de Google para alojar las librerías javascript de nuestras aplicaciones. Pues bien, ahora es Microsoft la que ha lanzado un servicio similar, Microsoft Ajax CDN, una red de distribución de contenidos desde donde podemos descargar en tiempo de ejecución las librerías de scripts que utilicemos en nuestras aplicaciones.

O en otras palabras, que podemos hacer uso de forma gratuita de estas librerías, sin limitación de ancho de banda e independientemente de si es para fines comerciales o no. Basta con referenciarlas desde nuestro código:

<script src="http://ajax.microsoft.com/ajax/jquery-1.3.2.min.js" 
type="text/javascript"></script>

La principal ventaja que ofrece este método es la velocidad con la que estos archivos serán servidos, puesto que se usa la infraestructura del gigante de Redmon, a la vez que se comparte la caché con otros sitios web que también las estén utilizando. También brinda la posibilidad de utilizar scripting a sitios web que no disponen de permisos para subir archivos (como la plataforma blogger)

A diferencia del servicio de Google, desde esta CDN sólo podemos encontrar de momento las librerías que oficialmente forman parte de la plataforma de desarrollo de Microsoft, como las propias de ASP.NET Ajax, jQuery y aquellos plugins que vayan añadiéndose. En la dirección http://www.asp.net/ajax/cdn/ pueden consultarse la lista completa de librerías, con sus correspondientes direcciones de descarga.EnableCdn en ScriptManager

Adicionalmente, Scott Guthrie comentaba en su blog que el nuevo control ScriptManager que vendrá con ASP.NET 4.0 incluye una propiedad llamada EnableCdn que permitirá activar la descarga de las librerías Ajax y todas aquellas necesarias para el funcionamiento de controles, directamente desde sus servidores.

Los inconvenientes, pues los mismos que los del servicio de Google: si no disponemos de conexión a la red en tiempo de desarrollo, podemos tenerlo realmente crudo.

Más información en: www.asp.net/ajax/cdn

Publicado en: Variable not found.

Linq para NHibernate, versión 1.0

Logo de NHibernate Hace unas semanas, Oren Eini (o Ayende Raihen, como se le suele conocer) comunicaba la liberación de la versión 1.0 del proveedor de Linq para NHibernate, una característica altamente demandada por los usuarios desde la aparición del lenguaje de consulta integrado en .NET.

Aunque será incluido como parte del producto NHibernate en versiones venideras, han decidido liberar la actual release del proveedor como paquete independiente para que pueda comenzar a utilizarse desde este momento. Está siendo testado en multitud de aplicaciones en producción desde hace varios años, y al parecer el funcionamiento es más que correcto.

¿Y cómo puede ayudarte este proveedor, si eres usuario de NHibernate? El siguiente ejemplo, tomado de Caffeinated Coder muestra cómo una consulta a base de datos puede simplificarse y hacerse mucho más legible utilizando Linq, además de beneficiarse del tipado fuerte, intellisense y comprobaciones en tiempo de compilación:

Utilizando el API de NHibernate:

public IList<Call> GetCallsByDate(DateTime beginDate, int interpreterId)   

{   

    ICriteria criteria = Session.CreateCriteria(typeof(Call))

        .CreateAlias("Customer", "Customer")

        .Add(Restrictions.Gt("StartTime", beginDate))

        .Add(

            Restrictions.Or(

                Restrictions.Lt("EndTime", DateTime.Now), Restrictions.IsNull("EndTime"))

            )

        .Add(Restrictions.Eq("Interpreter.Id", interpreterId))

        .AddOrder(Order.Desc("StartTime"))

        .AddOrder(Order.Desc("Customer.Name")); 

        return criteria.List<Call>() as List<Call>;

}

Utilizando Linq:

public IList<Call> GetCallsByDateWithLinq(DateTime beginDate, int interpreterId)  

{   

    var query = from call in Session.Linq<Call>()

        where call.StartTime > beginDate

            && (call.EndTime == null || call.EndTime < DateTime.Now )   

            && call.Interpreter.Id == interpreterId

        orderby call.StartTime descending, call.Customer.Name

        select call;

 

    return query.ToList();

}

Podéis descargar tanto los binarios como el código fuente desde la página del proyecto en SourceForge.

Publicado en: Variable not found.

Posters sobre ASP.NET MVC

BB&D a través de su iniciativa DRP ha incluido en su ya extenso repositorio de posters que abarcan innumerables temáticas (arquitectura, modelado, desarrollo, sistemas operativos, etc.), cuatro chuletas sobre ASP.NET MVC a las que vale la pena echarles un vistazo:

image ASP.NET MVC Framework Cheat Sheet
Información genérica sobre el framework, que incluye la estructura de carpetas de los proyectos de este tipo, la sintaxis del mapeo de rutas, un diagrama del patrón MVC y el ciclo de vida de las peticiones.
image ASP.NET MVC Controller Cheat Sheet
Muestra los diferentes tipos de ActionResult disponibles, una relación de atributos con sus usos (filtros, selectores de acciones y enlaces de datos), reglas para la definición de métodos de acción
image ASP.NET MVC View Cheat Sheet
Referencia rápida de los helpers Html y Url, las directivas de declaración de vistas, y las distintas formas de enviar contenidos al cliente.
image ASP.NET MVC Proven Practices
Contiene algunos consejos y buenas prácticas al desarrollar una aplicación con el framework.

Así que ya sabéis, si todavía os queda espacio en la pared y necesitáis tener a mano una referencia rápida de ASP.NET MVC, id preparando impresora y chinchetas 😉

Publicado en: Variable not found

ASP.NET MVC versión 2, preview 1

 

A finales del pasado mes de Julio, Haack, Scottgu, y un sinfín de figurillas más, anunciaron la publicación del código fuente e instaladores de la primera preview de la nueva versión de la plataforma ASP.NET MVC.

Tal y como se describe en el Roadmap del producto, el objetivo de la versión 2 es aumentar la productividad de los desarrolladores que trabajen con el framework, así como cubrir determinadas necesidades muy comunes y que no llegaron a introducirse en la primera versión del producto, como las siguientes.

Soporte para “áreas”

Soporte para áreas en ASP.NET MVC 2Las áreas son subproyectos independientes con rutas, vistas y controladores que implementan una sección específica de las funcionalidades de un sistema de forma muy aislada y reutilizable. Ejemplos directos serían un sistema de foros, o un motor de blogs; implementados como áreas, una solución web que necesitara incluir dichas funcionalidades simplemente debería referenciarlas y realizar pequeños ajustes para, a partir de ese momento, poder contar con ellas.

La limpieza del enfoque adoptado favorece la organización, reutilización, el trabajo en equipo y, además, seguro que provoca la aparición de muchos componentes complejos, tanto comerciales como libres, distribuidos de esta forma y listos para ser incluidos en nuestras aplicaciones de forma sencilla.

En cualquier caso, esta primera preview incluye soporte aún muy básico para las áreas, y para utilizarlas hay que tocar a mano los archivos de proyectos (hay un paso a paso en MSDN que describe cómo hacerlo) . Ya en futuras revisiones se irá introduciendo en el IDE las herramientas para gestionarlas, así como nuevas posibilidades para su integración en un proyecto único.

Nuevo conjunto de helpers de interfaz de usuario

Métodos utilizables desde las vistas que seguro que nos harán la vida más fácil al utilizar tipado fuerte para vincular controles de edición y visualización de información a propiedades del modelo, además de permitir el diseño de plantillas para tipos de datos específicos.

En la versión 1 de ASP.NET MVC:
<%= Html.TextBox("Nombre", Model.Nombre) %>        
 
En la versión 2:
<%= Html.EditorFor(persona=>persona.Nombre) %>

Fijaos que desaparecen los nombres mágicos (constantes entrecomilladas) necesarios en la versión 1 para generar los controles de edición, y pasan a ser expresiones lambda que referencian directamente a la propiedad del modelo, por lo que se podría comprobar su corrección en tiempo de compilación.

EditFor() con un tipo complejoPero Html.EditorFor() no sólo es aplicable a tipos “nativos”, también pueden ser estructuras complejas (por ejemplo, la clase Persona), para las que generará por defecto los controles de edición de todas sus propiedades, salvo aquellas en las que se haya indicado expresamente lo contrario. Esto, que en escenarios simples puede resultar suficiente para crear formularios de edición de datos, se realizaría haciendo que la lambda devuelva el propio objeto del modelo:

<% using (Html.BeginForm()) { %>
    <%= Html.EditorFor(persona=>persona) %>
    <input type="submit" value="Enviar" />
<% } %>

Internamente, Html.EditorFor() buscará antes de renderizar ningún resultado HTML si existe una plantilla de edición para el tipo de datos devuelto por la lambda en la carpeta ViewsSharedEditorTemplates, con el nombre NombreDelTipo.ascx (por ejemplo Persona.ascx). También es posible indicarle explícitamente la plantilla que debe usar para renderizar el editor, tanto en el momento de invocar al helper como a nivel de la propia clase del modelo.

Todo lo dicho hasta ahora es válido para la visualización de datos, que utilizará el helper Html.DisplayFor(): de la misma forma, los parámetros fuertemente tipados del método nos ayudarán a detectar errores en fase de compilación, y existe igualmente la posibilidad de definir las plantillas, aunque la carpeta donde se habrán de colocar debe ser en esta ocasión ViewsSharedDisplayTemplates. Hay un buen paso a paso, aunque en inglés, de cómo utilizar este tipo de plantillas.

Un último helper más, LabelFor(), está especialmente creado para generar etiquetas asociadas a controles de edición. Su principal particularidad es que es capaz de tomar la descripción del campo desde los metadatos de la clase del modelo. Esta técnica es la misma que utiliza otra de las grandes novedades de esta versión, el sistema de validación.

Mecanismo de validación integrado

Ese gran ausente en la primera versión del framework MVC que hacía que tuviéramos que encargarnos a mano de comprobar uno por uno los datos de entrada (o utilizar frameworks externos) para que no se colara en el modelo información inválida. La solución viene de mano de las Data Annotations, un conjunto de atributos que podemos aplicar a las entidades de datos para indicar restricciones aplicables a sus valores:

public class Persona
{
    [DisplayName("Nombre")]
    [Required(ErrorMessage = "El nombre es obligatorio!")]
    [StringLength(45)]
    public string Nombre { get; set; }
 
    [DisplayName("Número de hijos")]
    [Range(0, 15)]
    public int NumeroDeHijos { get; set; }
}

En el ejemplo anterior vemos un caso simple en el hemos añadido metadatos a la clase del modelo que describen las particularidades de cada propiedad. ASP.NET MVC Framework versión 2 es capaz de obtener esta información y utilizarla para validar la entrada de datos al recibir un formulario, o incluso en cliente por obra y gracia de un plugin para jQuery que será incluido en la plantilla, aunque esto todavía no está disponible en esta preview.

Un detalle interesante a tener en cuenta es que, dado que las clases de datos son habitualmente generadas por herramientas automáticas, estos los metadatos pueden ser definidos en clases paralelas (clases ‘buddy’). Una solución un poco anti-DRY, pero bueno…

Otras mejoras

Hay otras mejoras de menor calado aunque también interesantes, como la inclusión del nuevo atributo [HttpPost] para acelerar la declaración de acciones restringidas a ese método del protocolo, el soporte para valores por defecto en parámetros (basado en atributos hasta que llegue el nuevo C# 4.0, aunque ya disponible en VB), o algunos cambios en el API (algunos de ellos “rompedores”). Todos estos detalles pueden consultarse en el documento de notas de la revisión.

ASP.NET MVC 1 y 2 al mismo tiempo, vamos a llevarnos bien...Si quieres ir probando en persona las novedades, puedes descargar la preview y jugar con ella desde Visual Studio 2008 SP1 (también funciona para Visual Web Developer Express 2008 SP1, el IDE gratuito) sin peligro alguno. El instalable en ningún momento sobrescribe librerías o componentes de la versión 1.0, sólo creará un nuevo juego de plantillas para esta versión. Eso sí, si eres de los afortunados que están ya exprimiendo la beta 1 de VS2010, has de saber que no son compatibles, tendrás que esperar hasta la beta 2, la cual ya incluirá la próxima preview del framework.

Seguiremos atentos a la evolución del framework, que estos muchachos están que no paran…

Publicado en: Variable not found.

Métodos condicionales en .NET

En la plataforma .NET existen distintas formas de hacer que una llamada a un método sea omitida bajo determinadas circunstancias. Por ejemplo, los métodos parciales permiten, en C# 3.0 y VB 9.0, que el compilador omita la llamada a funciones no implementadas. También existe la posibilidad de utilizar las clásicas directivas (como #if… #endif ) para incluir código cuando existan constantes de compilación.

Es menos conocida, sin embargo, la existencia del atributo ConditionalAttribute, que aplicado a un método hace que las llamadas a éste no sean incluidas en el ensamblado si no existe la constante de compilación cuyo nombre se indica en el parámetro.

Por ejemplo, explorando un poco el espacio de nombres System.Diagnostics, vemos que todos los métodos de la clase Debug, están adornados por este atributo así:

   1: [Conditional("DEBUG")]

   2: public static void WriteLine(string message)

   3: {
   4:     TraceInternal.WriteLine(message);
   5: }

Ahora, imaginad que tenemos un código que usa esta clase, por ejemplo de la siguiente manera:

   1: public static void Main(string[] args)
   2: {
   3:     for(int i=0; i < 1000; i++)
   4:     {
   5:         Debug.WriteLine("Iteración " + i);
   6:         ProcesaAlgoComplejo(i);
   7:         int j = ProcesaOtraCosa(i);
   8:         Debug.WriteLine("Obtenido " + j);
   9:         // ...
  10:     }
  11: }

Si compilamos en modo “debug” (o simplemente está definida la constante de compilación con dicho nombre), las llamadas a estos métodos serán omitidas en el ensamblado resultante, por lo que el código finalmente generado será totalmente equivalente a:

   1: public static void Main(string[] args)
   2: {
   3:     for(int i=0; i < 1000; i++)
   4:     {
   5:         ProcesaAlgoComplejo(i);
   6:         int j = ProcesaOtraCosa(i);
   7:         // ...
   8:     }
   9: }

Pero ojo, que se omiten tanto las llamadas al método como la evaluación de sus parámetros, y esto puede provocar errores difíciles de detectar. Por ejemplo, el siguiente código daría lugar a un bucle infinito de los de toda la vida 😉 si compilamos en modo “release”; sin embargo, compilando en “debug” funcionaría correctamente:

   1: int j = 0;
   2: while (j < 100)
   3: {
   4:     Console.WriteLine("Hey " + j);
   5:     Debug.WriteLine("Procesado " + (j++));  // <-- Esta línea desaparece cuando
   6:                                             //     compilamos en modo release!
   7: }

Aunque en el anterior ejemplo estamos jugando con la constante predefinida DEBUG, este atributo podemos utilizarlo con otras constantes, tanto existentes como personalizadas. Como muestra, podéis echar un vistazo a la definición de la clase System.Diagnostics.Trace, que vincula el uso de sus métodos a la existencia de la constante TRACE:

   1: public sealed class Trace

   2: {

   3:     // ...

   4:  

   5:     private Trace();

   6:     [Conditional("TRACE")]

   7:     public static void Assert(bool condition);

   8:     [Conditional("TRACE")]

   9:     public static void Assert(bool condition, string message);

  10:     [Conditional("TRACE")]

  11:     public static void Assert(bool condition, string message, string detailMessage);

  12:     [Conditional("TRACE")]

  13:     public static void Close();

  14:     [Conditional("TRACE")]

  15:     public static void Fail(string message);

  16:     [Conditional("TRACE")]

  17:     public static void Fail(string message, string detailMessage);

  18:     [Conditional("TRACE")]

  19:     public static void Flush();

  20:     [Conditional("TRACE")]

  21:  

  22:     //...

  23: }

Si vais a utilizar el atributo sobre vuestros métodos, condicionándolos a la existencia de constantes de compilación personalizadas, recordad que las constantes podéis definirlas:

  • desde las propiedades del proyecto en el IDE
  • en la línea de comandos del compilador (por ejemplo, /define:LOG)
  • variables de entorno del sistema operativo (set LOG=1)
  • en directivas sobre vuestro propio código (directiva #define LOG)

Eso sí, tened en cuenta que el método siempre será compilado e introducido en el ensamblado, son las invocaciones a éste las que son omitidas en caso de no existir la constante indicada.

Hay que tener en cuenta las siguientes observaciones para el uso del atributo Conditional:

  • Los métodos a los que se aplica no pueden tener tipo de retorno, es decir, serán void. Esto tiene bastante sentido, si pensamos en los efectos laterales que podría causar la desaparición de una invocación tras la cual se haga uso del valor retornado.
  • Sólo se pueden aplicar a métodos en clases o estructuras. Nada de interfaces (¡tampoco tendría mucho sentido!).
  • Si un método virtual está marcado como Conditional, las reescrituras de éste realizadas desde clases descendientes también lo estarán.  Es bastante lógico, puesto que así se mantienen las dependencias íntegras.
  • Si el atributo se aplica a un método, éste no puede ser un reemplazo del comportamiento de un antecesor (o sea, que no puede ser un override). También resulta muy lógico.

En resumen, se trata de un buen método para incluir código condicional en nuestros desarrollos, dependiente del contexto de compilación, evitando tener que usar directivas #if… #endif. Pero no lo olvidéis: cuidado con los efectos laterales citados.

Publicado en: Variable not found.

Si vas a diseñar un sistema de misiles…

… o algún arma química o biológica, que sepas que no puedes utilizar Google App Engine: estarías violando los términos de la licencia.

 image

“El uso del servicio debe cumplir con todas las leyes aplicables, reglamentos y ordenanzas, incluyendo cualesquiera leyes relativas a la exportación de datos o software. Usted acepta no usar el servicio en el diseño, desarrollo, producción, o uso de misiles o el diseño, desarrollo, producción, almacenamiento y uso de armas químicas o biológicas”

Así que, si es este tu caso, ya puedes ir buscando otro software. Y no lo vas a tener fácil, puesto que se trata de un párrafo que se incluye muy habitualmente en las licencias de aplicaciones.

Pues eso, mucho ojo. ;-D

Visto en: DevTopics: why-terrorists-hate-google-app-engine
Publicado en: Variable not found.

Generación de PDF desde .NET usando formularios

Un post en .NET Answers me ha recordado que hace tiempo tenía pendiente escribir una entrada para comentar la técnica que he utilizado en más de una ocasión para generar documentos PDF desde mis aplicaciones .NET de forma muy sencilla, y que puede aplicarse en escenarios donde se conozca de antemano el diseño del documento a imprimir y sólo sea necesario introducir información concreta en espacios muy definidos. Un caso muy habitual es el rellenado de formularios o impresos, aunque usando un poco la imaginación seguro que podéis encontrarle muchas más utilidades.

La técnica consiste en crear, utilizando alguna herramienta de diseño como Adobe Acrobat, un documento PDF que contenga todos los contenidos estáticos del documento que deseamos generar. En cada zona donde queremos inyectar contenido deberemos introducir un campo de formulario (por ejemplo, “nombre”, “apellidos”, etc.) adaptando el tipo de letra, límites y las propiedades del campo que sean necesarias.

imageYa desde código el procedimiento será bien sencillo: abrimos la plantilla, introducimos los valores en cada uno de los campos, y hacemos con el documento resultante lo que nos convenga según la ocasión: enviarlo por email, salvarlo a disco, ofrecerlo para la descarga, etc.

Para conseguir estos objetivos utilizaremos iTextSharp, una adaptación para .NET de la librería iText, muy conocida en el mundo Java. Por tanto, en primer lugar, es necesario descargarla desde Sourceforge, y referenciarla en el proyecto desde el cual vamos a utilizarla.

El siguiente código implementa un método realiza el procedimiento descrito:

   1: public void FillPDF(string templateFile, Stream stream)
   2: {
   3:     // Abrimos la plantilla y creamos una copia, sobre
   4:     // la cual trabajaremos...
   5:     PdfReader reader = new PdfReader(templateFile);
   6:     PdfStamper stamp = new PdfStamper(reader, stream);
   7:  
   8:     // Introducimos el valor en los campos del formulario...
   9:     stamp.AcroFields.SetField("Nombre", "Juan");
  10:     stamp.AcroFields.SetField("Apellidos", "Rodríguez Méndez");
  11:  
  12:     // Fijamos los valores y enviamos el resultado al stream...
  13:     stamp.FormFlattening = true;
  14:     stamp.Close(); 
  15: }

Así, para almacenar la plantilla con los datos en un nuevo PDF, bastaría con invocar al método anterior de la siguiente manera:

   1: Stream file = new FileStream("FormularioRelleno.pdf", FileMode.Create);
   2: FillPDF("plantilla.pdf", file);

O si queremos que desde una aplicación ASP.NET el usuario pudiera descargarlo directamente, podríamos utilizar un código como el siguiente:

   1: protected void btnGenerarPDF_Click(object sender, EventArgs e)
   2: {
   3:     Response.Clear();
   4:     Response.ContentType = "application/pdf";
   5:     Response.AddHeader("content-disposition", "attachment;filename=Formulario.pdf");
   6:     FillPDF(Server.MapPath("Plantilla.pdf"), Response.OutputStream);
   7: }

Por último, sólo comentar que iTextSharp no sólo es útil para rellenar formularios, ni mucho menos. Se trata de una librería muy potente que permite la creación y edición al vuelo de documentos PDF completos, y dispone de un complejo amplísimo API que nos permite hacer casi de todo con ellos. Además, se distribuye bajo licencias LGPL y MPL, muy permisivas ambas, por lo que pueden ser utilizadas en prácticamente cualquier tipo de sistemas.

Para el que no se le apetezca teclear mucho, ahí va una solución para Visual Studio 2005 con dos proyectos, uno web y otro de consola, demostrando el funcionamiento.

 

 

Publicado en: Variable not found.

De vuelta

Pues sí… todo lo que empieza acaba, y las vacaciones no iban a ser una alegre excepción.

Aquí estamos de nuevo listos para entrar en combate. Esta vez, además, el retorno al MundoReal™ coindice con un momento de emocionantes cambios a nivel profesional, lo cual hace especialmente motivador el regreso.

En cuanto a las vas vacaciones, simplemente geniales: mucho descanso en las playas de Huelva y Cádiz y, sobre todo, un grato recuerdo de la visita a Lanzarote, que sin duda es espectacular; si alguna vez tenéis oportunidad de visitar la isla, no dudéis en ir a disfrutar de ese lugar tan diferente. La única pega ha sido la insistente ola de calor que nos ha perseguido a todos nuestros destinos, pero bueno, son gajes del oficio.

Struts 2 in action, en Amazon.com De compañero de viaje esta vez he elegido Struts 2 in action, una muy recomendable lectura para conocer este veterano framework Java de desarrollo de aplicaciones web bajo la filosofía MVC. Me ha resultado interesantísimo conocer el enfoque del marco de trabajo, y contrastarlo con el muy reciente ASP.NET MVC; aunque con las obvias diferencias vinculadas a las tecnologías subyacentes en cada caso y al nombrado de componentes, hay muchísimas coincidencias y es sencillo encontrar correspondencias entre ambos frameworks que facilitan la comprensión y asimilación de los conceptos.

El libro está editado en español por Anaya Multimedia, bajo el nombre Struts 2; aunque, como suele ocurrir en este tipo de textos, de vez en cuando te encuentras errores de traducción y contenidos, cumple bastante bien su cometido.

Y sin más preámbulos, comenzamos la temporada 2009-10 en Variable not found, donde espero seguir contando, como hasta ahora, con vuestra participación y apoyo.

Publicado en: Variable not found.