August 2009 - Artículos

NUNCA lo olvides, mensajes de usuario en lugar de mensajes de excepción

Hace poco menos de 1 mes me encontraba en una de esas famosas tiendas de Madrid y de otras partes de España donde se puede hacer casi de todo (hacer la compra mínima de urgencia, comer o cenar, comprar o leer libros y revistas, comprar música y películas...).

Próximo a la parte de la tienda dedicada a la música y las películas me encontré una curiosa caja de metal y de forma rectangular para recoger entradas para ir al cine y espectáculos.

Me quedé mirando el "cacharro", que no era otra cosa que una caja metálica con una pantalla y un pequeño interfaz para registrar los datos personales que nos solicitaba, y un flamante cable que salía descaradamente de la parte posterior para esconderse en el suelo en una más que posible regleta.

Como uno es curioso por naturaleza y puesto que nadie me lo impedía, me puse a toquetear en la aplicación para ver que tal se comportaba, como era de amigable, y bueno... pensando en que siempre es posible aprender algo nuevo (porqué no decirlo).

Empecé a usar la aplicación, y sin entrar en la discusión de si era más o menos bonita, intuituva, etc., y centránome en lo estrictamente funcional, efectivamente obtuve un listado de los espectáculos en cartelera, una breve sipnosis, y simulé que quería una entrada de una de los espectáculos para ver hasta donde podía llegar y "probar" más aún todo el proceso.

Todo fue correctamente hasta que llegó el momento de conectarme con el servidor para reservar asiento y formalizar la compra.

Ahí y transcurrido un rato, ocurrió un error con el sistema y me devolvió un pantallazo como el que se puede ver a continuación (no os fijéis mucho en la pobre calidad de la imagen):

El pantallazo es realmente nefasto. El error está claro que parece estar originado por un timeout en la respuesta del servidor de base de datos.

Ahora bien, todo esto para indicar una cosa que se repite una y otra vez, que no es nueva, pero que no siempre tenemos presente en los desarrollos Software que hacemos.

Repita conmigo: ¡NO es conveniente ni buena práctica volcar en pantalla la información que devuelve una excepción!.

Seamos un poco más estrictos y repita nuevamente conmigo: ¡NUNCA muestre mensajes de excepciones ni mensajes genéricos a un usuario!.

Se me revuelven las tripas de solo ver la imagen que capturé con el mensaje que apareció en pantalla. En mi caso porque entiendo un poquito lo que puede haber pasado, pero un usuario normal... ¿qué le importa todo eso que aparece en pantalla o para qué es?.

Al usuario lo que le interesaba es que apareciese no todo ese texto ahí desorganizado, sino un simple mensaje del tipo: "En estos instantes, la aplicación no es capaz de conectarse con el sevidor. Inténtelo pasados unos minutos o más tarde.".

Eso sin entrar en el detalle de que en la pantalla aparecen los dos posibles casos con diferente fuente de letra y enmarañado entre el mensaje devuelto por la excepción.

Está claro, que en el log interno se podría haber registrado el detalle del error, pero al usuario le importa realmente un rábano si es un Timeout expired, si tiene algo que ver o no EntaNetDAL.EntaNetSQLDB.Generic o lo que sea.

¿Porqué pasa esto?. Porque muchas veces pensamos como programadores y no como usuarios. Tan simple como eso.

No obstante y tratando otro tema mucho más sensible sobre lo mismo, el riesgo de mostrar mensajes de este tipo, es grandísimo, ya que en algunas ocasiones, podríamos comprometer incluso la seguridad de la aplicación y/o de los datos si mostramos información relevante. No sería la primera vez que aparece información sensible y que de repente, "alguien" nos ha hackeado nuestra aplicación.

Recordemos siempre que los usuarios solo entienden un lenguaje. El lenguaje breve, claro y conciso.

Los programadores y técnicos hablamos en una jerga mucho más compleja y técnica, pero el usuario solo quiere algo agradable a la vista, incluso cuando se produce un error de tipo Timeout como el caso del ejemplo.

Finalmente, agrego como referencias alguna documentación útil sobre el tema de las excepciones, por si queremos aprender más acerca de ellas.

Referencias:

Una interesante entrada en inglés sobre las mejores prácticas en el manejo de excepciones.

Krzysztof Cwalina con cuenta en inglés como elegir el tipo de excepción correcta a lanzar.

El equipo de CLR de Microsoft nos cuenta en inglés porqué es malo capturar Exception o una excepción en blanco.

Información del blog de Shiman's sobre las excepciones de aplicación.

Exception Management Architecture Guide. Guía de Microsoft sobre la gestión de excepciones.

Cross Posted from Jorge Serrano - MVP Visual Developer - VB

Documentación sobre Microsoft Silverlight 3.0

 

Microsoft ha publicado un fichero en formato CHM (ayuda de Windows) sobre Silverlight 3.0 en español.

El archivo representa la información de documentación que todo desarrollador de Silverlight 3.0 debe tener a mano, sobre todo cuando no disponemos de conexión a Internet.

El fichero ocupa poco más de 66 Mb.

Referencias:

Acceso directo a la página de descarga del fichero de ayuda de Silverlight 3.0 en español.

Cross Posted from Jorge Serrano - MVP Visual Developer - VB
Posted por Jorge Serrano con no comments
Archivado en:

Compilación bajo demanda en C#. Generación y compilación de código dinámicamente.

Introducción

Con el CLR 2.0, y en su caso desde la aparición de Microsoft .NET Framework 2.0, tenemos la posibilidad de hacer uso en C# de un namespace de nombre Microsoft.CSharp. Un nombre de espacio que en muchas ocasiones pasa por desapercibido para el programador y que podría resolvernos un sinfin de problemas en determinadas situaciones concretas.

Dentro de esta librería, encontraremos tres clases, dos de ellas obsoletas y de nombres Compiler y CompilerError, y una tercera clase que es sobre la que quiero hacer hincapié, de nombre CSharpCodeProvider.

Con la clase CSharpCodeProvider podemos acceder a instancias del generador y compilador de código C#. Dicho de otra forma, podríamos indicar un conjunto de instrucciones de código determinado para por ejemplo, evaluar expresiones compilando ese código en tiempo de ejecución para consumirlo por el ensamblado que lance esa porción o instrucciones de código.

Esto es muy útil de acuerdo a diferentes escenarios en los cuales, el código podría ser volatil o estar expuesto a cambios determinados en cálculos, o acciones determinadas, lo cual nos forzaría a lanzar el código bajo demanda.

Escenario de partida de ejemplo

Para situarnos, pensemos en una situación teórica concreta en la cual nuestro ensamblado debe ejecutar en tiempo de ejecución un conjunto de instrucciones u otro según el valor de una determinada variable.
Una forma de resolver esto podría ser introduciendo una claúsula if que de acuerdo a esa variable ejecutase una porción de código u otra, pero pensemos más allá e imaginemos que esa porción de código pudiera variar continuamente, ¿cómo podríamos resolver esto?.

Poner muchas claúsulas if recogiendo todas las posibilidades podría resolvernos el problema, pero además de no ser operativo, es que tampoco tenemos claro de que recojamos todas las posibilidades realmente, y además, solo se ejecutaría en nuestro caso o true o false de acuerdo al valor de esa variable.
Además de no parecer una solución muy limpia, engordaríamos el código con morralla y tendríamos que recompilar la aplicación cada vez que hubiera un cambio (pensemos en que el ejemplo que expongo es muy concreto y que son cambios frecuentes en el tiempo).

Se me ocurre no obstante otra solución.
La disposición de unas instrucciones persistidas en fichero, base de datos, etc., que carguen las líneas de código del conjunto de instrucciones que queremos lanzar en la aplicación, y que no nos obligue a recompilar nuestra aplicación cada vez que se produce un cambio de cálculo en algunos de los conjuntos de código.

¿Y cómo hacer esto?.

Poniendo en práctica un ejemplo teórico

Utilizando como ya he adelantado antes el nombre de espacio Microsoft.CSharp, y concretamente la clase CSharpCodeProvider.

Pero para utilizar toda la funcionalidad de la generación y compilación de código de forma dinámica, deberemos hacer uso de otro nombre de espacio de nombre System.CodeDom.Compiler.
Este nombre de espacio contiene tipos que nos permite administración la generación y compilación de código en aquellos lenguajes de programación que sean compatibles con .NET, como el ejemplo que nos ocupa con C#.
CodeDOM (Code Document Object Model) es por su parte, una estructura de modelos de código fuente.
Dentro de este nombre de espacio encontraremos diferentes clases e interfaces listas para generar y compilar nuestro las instrucciones de código que queramos.


Así que nos ponemos manos a la obra.

He creado una aplicación Windows donde he insertado tres controles TextBox, dos contoles radioButton, un control Label y un control Button.

El aspecto de nuestra aplicación es el siguiente:

Como podemos ver en la imagen, dentro de la primera y de la segunda caja de texto, tenemos dos instrucciones de código que son las siguientes:


Para la primera caja de texto:

using System;
public class ClaseCalculo
{
   public ClaseCalculo() {}
  
   public int MiMetodo()
   {
      int i = {0};
      return i * 2;
   }
}


Para la segunda caja de texto:

using System;
public class ClaseCalculo
{
   public ClaseCalculo() {}
  
   public int MiMetodo()
   {
      int i = {0};
      return i * 3;
   }
}


Además, dentro de la caja de texto del valor de la variable int i, le vamos a dar el valor de la expresión, que obtendremos de la tercera caja de texto.

Finalmente, el código de nuestro ensamblado asociado al control Button será el siguiente:

using Microsoft.CSharp;
using System.CodeDom.Compiler;

...

private void Button1_Click(object sender, EventArgs e)
{
    
// Declaramos la clase CSharpCodeProvider.
    CSharpCodeProvider csharpCodeProvider = new CSharpCodeProvider();
    
// Declaramos la clase CodeDomProvider.
    CodeDomProvider codeDomProvider = CodeDomProvider.CreateProvider("C#");
    CompilerParameters compilerParameters = 
new CompilerParameters();
    
// Generamos el codigo del ensamblado en memoria.
    compilerParameters.GenerateInMemory = true;
    
// No generamos un fichero ejecutable.
    compilerParameters.GenerateExecutable = false;
    
// Indicamos las referencias al ensamblado.
    compilerParameters.ReferencedAssemblies.Add("system.dll");
    
// Recuperamos el valor de la expresique queremos ejecutar internamente.
    int expression;
    
bool resultExpression = Int32.TryParse(this.textBox3.Text, out expression);
    
if (resultExpression)
    {
        
// Preparamos las instrucciones de codigo de forma dinamica
        // de acuerdo al valor de una variable o en este caso de un 
        // control de tipo radioButton.
        string source = "";
        
if (this.radioButton1.Checked)
        {
            source = 
this.textBox1.Text;
        }
        
else
        {
            source = 
this.textBox2.Text;
        }
        
// Despues de recuperar las instrucciones de codigo, 
        // preparamos el codigo junto al valor de la expresion.
        source = source.Replace("{0}", expression.ToString());
        
// Compilamos y obtenemos los resultados de la compilacion.
        CompilerResults compilerResults = csharpCodeProvider.CompileAssemblyFromSource(compilerParameters, source);
        
// Miramos si hay errores o no.
        if (compilerResults.Errors.Count > 0)
        {
            
foreach (CompilerError compilerError in compilerResults.Errors)
            {
                MessageBox.Show(
"Error compilando."
                                + Environment.NewLine
                                + Environment.NewLine
                                + String.Format(
"Error en linea {0} y columna {1}.", compilerError.Line, compilerError.Column)
                                + Environment.NewLine
                                + compilerError.ErrorText);
            }
        }
        
else
        {
            
// Obtenemos el valor 
            Type type = compilerResults.CompiledAssembly.GetType("ClaseCalculo");
            Object objectEvaluator = Activator.CreateInstance(type);
            MethodInfo methodInfo = type.GetMethod(
"MiMetodo");
            var result = methodInfo.Invoke(objectEvaluator, 
new object[0]);
            MessageBox.Show(String.Format(
"Resultado: {0}", result));
        }
    }
     
else
    {
         MessageBox.Show(String.Format(
"El valor de la expresion {0} no es valido."this.textBox3.Text));
    }
}

Una vez que hemos preparado nuestra aplicación, pasaremos a ejecutarla.

Para comprobar que nuestra aplicación ejecuta dinámicamente el código de las cajas de texto que contiene las instrucciones de código, vamos a alternar la ejecución de uno u otro conjunto de instrucciones haciendo clic sobre cada uno de los controles radioButton.

Observaremos que la aplicación devuelve dinámicamente un resultado u otro de acuerdo a nuestra selección.

Ahora bien, cambiemos un valor o una parte del conjunto de instrucciones de código de una u otra caja de texto y ejecutemos nuevamente el procedimiento.
Si lo hemos hecho bien, obtendremos un resultado positivo.
Si hemos cometido algún error, obtendremos un mensaje de error como se indica a continuación.

Como podemos ver, el compilador nos devuelve un mensaje de error que es el que en nuestro caso, he mostrado por pantalla.

Conclusión

Aún y así, debemos tener en cuenta la posibilidad de buscar una respuesta rápida por parte la aplicación.
La compilación bajo demanda o dinámica nos ofrece una salida según determinadas situaciones, pero tampoco debemos usarla como norma, ya que penaliza en rendimiento más que si no tuviésemos que generar y compilar código dinámicamente.
Dentro de la generación y compilación, por regla general CompileAssemblyFromSource es más lento que CompileAssemblyFromDom, pero en algunas situaciones, podemos encontrarnos con el caso inverso.

Cross Posted from Jorge Serrano - MVP Visual Developer - VB

StyleCop v4.3.2.1 publicada

 

Microsoft ha publicado el pasado 10 de Agosto una actualización de la herramienta StyleCop.

StyleCop como sabrás, es una herramienta que se utiliza para analizar el código de C# de acuerdo a unos estilos y reglas de consistencia.
Lo mejor de esta herramienta es que se puede ejecutar desde Visual Studio.

Esta nueva versión resuelve algunos bugs encontrados en la última revisión y que se pueden ver en el apartado de referencias (más abajo).

Referencias:

Información oficial del blog de StyleCop sobre la nueva versión del producto.

Acceso directo a la página web de descarga de StyleCop.

Cross Posted from Jorge Serrano - MVP Visual Developer - VB

Actualizados los HOLs de WF para C# y VB.NET

Microsoft publicó hace unos días la última actualización de sus HOL (Hands On Labs) sobre Microsoft Windows Workflow Foundation (WF) para C# y VB.NET.

Los laboratorios están preparados tanto para Microsoft .NET Framework 3.0 como para Microsoft .NET Framework 3.5.

En el caso de Microsoft .NET Framework 3.0, necesitaremos las extensiones de Windows Workflow Foundation para Visual Studio, mientras que en el caso de Visual Studio 2008 (.NET Framework 3.5), no serán necesarias estas extensiones.

Las descargas oscilan entre 16.4 Mb y 11.5 Mb según queramos los HOL para Microsoft .NET Framework 3.0 o para Microsoft .NET Framework 3.5.

Referencias:

Acceso a la página de descarga de Microsoft de los HOL.

Cross Posted from Jorge Serrano - MVP Visual Developer - VB

Movie Maker se renueva... en forma de Windows Live Movie Maker

A los que nos gusta todo lo relacionado con la multimedia, la noticia no nos viene del todo mal, y es que Microsoft ha actualizado su famoso Movie Maker a su versión Windows Live.

Lo malo, es que solo podremos utilizarla en Windows Vista y Windows 7. Así que si tenemos Windows XP o anterior, nos podemos olvidar de usarlo.

Con el programa, podremos entre otras cosas, generar videos con nuestras imágenes, con transiciones incluidas, para grabarlas posteriormente en un CD o DVD.

Una recomendación lógica de Microsoft es el uso de Microsoft Photo Gallery, que queda incluida dentro de la sección de Windows Live también.

La descarga apenas ocupa poco más de 1 Mb que se inicia después de aceptar el acuerdo y licencia. En este punto y cuando finalice la descarga, se inica el programa de instalación de manera autónoma, fácil y rápido.

Desde el programa de instalación, podremos instalar no solo Windows Live Movie Maker, sino también otros programas Live como el comentado Photo Gallery.

Referencias:

Enlace directo a la página de descarga e información de Windows Live Movie Maker.

Cross Posted from Jorge Serrano - MVP Visual Developer - VB
Posted por Jorge Serrano con no comments
Archivado en:

Windows Azure Platform Training Kit (actualización de Agosto 2009)

 

Microsoft ha publicado la actualización del paquete de Windows Azure Platform Training Kit que contiene información técnica, laboratorios, etc., para adentrarse en todo lo relativo a Windows Azure.

Los requerimientos mínimos son Microsoft .NET Framework 3.5 SP1, Microsoft Visual Studio 2008 SP1 y Microsoft Powershell.

Referencias:

Acceso directo al enlace de descarga (entre 111 Mb y 228 Mb).

Cross Posted from Jorge Serrano - MVP Visual Developer - VB

Carga dinámica de CSS en ASP.NET

 

Me encuentro en el blog de Walter Novoa una interesante entrada sobre ASP.NET y en concreto como cargar dinámicamente CSS u hojas de estilo.

Reconozco que hay varias formas de realizar cargas dinámicas de hojas de estilo, pero esta me ha parecido muy interesante y por eso la indico aquí.

Espero que os resulte útil.

Referencias:

Enlace web al blog de Walter Novoa con la información de la carga dinámica de CSS en ASP.NET.

Cross Posted from Jorge Serrano - MVP Visual Developer - VB
Posted por Jorge Serrano con no comments
Archivado en:

Borrador sobre la estructura de los tipos de datos espaciales o Spatial Data Type de SQL Server 2008

No sé si mucha gente lo sabe o no, pero Microsoft creó para SQL Server 2008 un nuevo tipo de datos destinado al almacenamiento de datos espaciales, el Spacial Data Type.

Sin embargo, existe un pequeño problema, y es que para muchos este tipo de datos es un gran desconocido, y aunque lo conozcamos,... utilizarlo en la práctica se nos hace costoso.

Microsoft ha publicado un borrador de la documentación de la estructura de los tipos de datos espaciales. El documento, en formato pdf en inglés, tiene una extensión de casi 30 páginas, donde se nos cuentan los entresijos de este nuevo tipo de datos de SQL Server.

Adicionalmente, comparto también con todos unas excelentes entradas de Enrique Catalá (de Solid Quality) sobre este tipo de datos, por si hay alguien que no sabe de lo que hablo.

Espero que la información sea interesante.

Referencias:

Nuevos tipos de datos Espaciales en SQL Server 2008 (I) - Enrique Catalá.

Nuevos tipos de datos Espaciales en SQL Server 2008 (II) - Enrique Catalá.

Nuevos tipos de datos Espaciales en SQL Server 2008 (III) - Enrique Catalá.

Nuevos tipos de datos Espaciales en SQL Server 2008 (IV) - Enrique Catalá.

Acceso a la información.

Descarga directa del borrador del pdf (en inglés).

Cross Posted from Jorge Serrano - MVP Visual Developer - VB
Posted por Jorge Serrano con no comments
Archivado en:

No actualices a Windows 7 si tienes Visual Studio 2010 Beta 1 o .NET Framework 4.0 Beta 1 instalados

Me encuentro en los blogs de Heath Stewart's y Scott Hanselman's una recomendación que quiero compartir sobre la instalación de Windows 7 ahora que han aparecido diferentes comentarios y entradas al respecto.

Se trata del conflicto existente a la hora de actualizar a Windows 7.

Según el blog de Heath, Microsoft .NET Framework 4.0 Beta 1 debería ser desintalado, al igual que Microsoft Visual Studio 2010 Beta 1 (en orden inverso al que he comentado si tenemos los dos).

Referencias:

Blog de Heath Stewart's comentando la información.

Blog de Scott Hanselman's con esta infomación.

Cross Posted from Jorge Serrano - MVP Visual Developer - VB

Code Contracts en MSDN Magazine

Melitta Andersen, Program Manager del equipo BCL del CLR ha escrito un interesante artículo sobre Code Contracts en MSDN Magazine que merece la pena leer.

El artículo, en inglés, trata sobre las partes principales de Code Contracts, en concreto, sobre sus partes, la librería, las precondiciones y las postcondiciones, etc.

Cabe destacar que el artículo está basado en la versión beta de Microsoft .NET Framework 4.0, por lo que el artículo puede quedar inválido cuando salga la versión definitiva de .NET Framework 4.0.

Referencias:

Acceso al artículo de Melitta Andersen (en inglés) - versión normal.

Acceso al artículo de Melitta Andersen (en inglés) - versión imprimible.

Artículo sobre precondiciones y Microsoft Code Contracts V1.0.

Acceso al proyecto en Microsoft Research (versión actual, v1.2.20518.12).

Cross Posted from Jorge Serrano - MVP Visual Developer - VB

Windows 7x7

Ahora que estamos en la aproximación de Windows 7, os traigo una iniciativa de Microsoft en español en la que recoge en 7 semanas 7 videos, contando todas las bondades del nuevo sistema operativo de Microsoft.

Estos videos son una buena forma de conocer las novedades, mejoras y bondades del nuevo sistema operativo de Microsoft.

La información se recoge en tres grupos diferentes: Funciones Generales, Características para Programación, y Características Técnicas.

Espero que la información le sea útil a más de uno.

Referencias:

Enlace a Windows 7x7

Cross Posted from Jorge Serrano - MVP Visual Developer - VB
Posted por Jorge Serrano con no comments
Archivado en:

Windows 7 disponible mañana para los subscriptores de MSDN y TechNet


Microsoft ha hecho público que la versión de Windows 7 estará disponible a partir de mañana para los subscriptores de MSDN y TechNet.
Lo más destacable es que estará disponible en 893 imágenes iso. No está mal...

Lo que no encajo a comprender del todo es que según Microsoft, la versión RTM de MSDN y TechNet (que es la misma), estará disponible casi 2 meses antes de la fecha de lanzamiento y antes de que esté disponible en los canales de distribución y en los equipos preinstalados con versión OEM, cuya fecha de disponibilidad es para el 22 de Octubre.
¿Y porqué no termino de encajar todo esto?. Pues porque como casi todos sabreis, por la web se ha filtrado una iso (que no es difícil de encontrar) de la supuesta versión OEM de Windows 7 que habría sido filtrada por Lenovo.

Existe la posibilidad de que la versión filtrada por Lenovo sea la misma que la versión que aparecerá en MSDN y TechNet, pero si eres de los que se bajaron e instalaron esa versión, simplemente... ten precaución amigo conductor.

Referencias:

Blog de Chris Green (Microsoft)

Información de GenBeta sobre la filtración de Windows 7 OEM

Cross Posted from Jorge Serrano - MVP Visual Developer - VB
Posted por Jorge Serrano con no comments
Archivado en: