Archive for the ‘ASP .NET’ Category

Desarrollo de Aplicaciones con el ORM .netTiers Parte I: Introducción

En un post anterior hace algún tiempo hablamos sobre los ORMs más conocidos entre los cuales mencionamos a .netTiers que es una plantilla para CodeSmith. En esta ocasión iniciaremos una serie de artículos para mostrar como utilizar este excelente ORM.

Introducción a netTiers
.netTiers es una plantilla de código abierto para CodeSmith escrito en C#. La intención de esta plantilla es asistir a los desarrolladores eliminando el código repetitivo, que tenemos que escribir cada vez que desarrollamos una aplicación con conexión a datos. Al mismo tiempo nos provee de un framework completo para comenzar a trabajar en las partes más importantes de nuestra aplicación, como son la capa de presentación, la lógica empresarial, el flujo de trabajo de nuestra aplicación, etc.

Conjunto de características actuales de netTiers
A continuación presentamos un listado de las características generales de .netTiers:

  • Genera una solución completa con proyectos separados y un framework basado en capas para su aplicación. Puede comenzar a trabajar con la aplicación inmediatamente terminado el proceso de generación.
  • Crea un conjunto completo de procedimientos almacenados que están especializados en el dominio de su aplicación. Este código se puede ejecutar como SQL en línea o como procedimiento almacenado, lo cual es configurable.
  • Genera automáticamente objetos de entidad y las relaciones entre estos objetos del dominio, basado en las tablas y relaciones de la base de datos.
  • Avanzado motor de validación de reglas de entidad, el cual puede utilizar las reglas creadas en el proceso de generación o utilizar delegados para cualquier regla de validación personalizada.
  • Las clases generadas incluyen dos partes, una parcial y una concreta, por lo tanto puede personalizar la lógica de cualquier clase sin que este código se sobrescriba cuando se ejecuta el proceso de generación nuevamente.
  • Utiliza una lista genérica personalizada para las colecciones (TList) que soporta toda la interfaz del modelo de componentes de .NET y más, y soporta enlace, ordenación y filtrado (Bindable, Sortable and Filterable).
  • Crea un sitio web completo, ya pre-configurado y listo para comenzar a escribir código conectable a datos inmediatamente.
  • Crea un conjunto completo de controles web de administración, que pueden servir como una consola de administración web completamente funcional para base de datos.
  • Crea un conjunto completo de controles DataSource con tipo para toda la API de acceso a datos, con soporte en tiempo de diseño, estos controles son similares a los ObjectDataSource, pero con más características propias del dominio.
  • Crea una API de servicios web completa para el dominio, perfecto para clientes .Net WinForms o dispositivos móviles, y su configuración es bastante simple.
  • Crea un conjunto completo de pruebas de unidad para los proveedores de datos y provee aproximadamente un 50% de cobertura. Estas pruebas pueden ser para nUnit o Visual Studio Team System.
  • El código que se genera está completamente comentado y listo para sus necesidades de documentación, además de seguir las directivas de Microsoft para la nomenclatura.
  • Cualquier código que se encuentre en una carpeta especial en cualquiera de los proyectos, que por defecto se llama App_Code, será automáticamente incluido en el proyecto generado.
  • Las consultas que se incluyen en la API de accedo a datos, se pueden realizar por: Clave primaria, clave foránea, índices, relaciones de muchos a muchos, todos, selección paginada con filtro y búsqueda; así también métodos de escritura en la base de datos como Inserción/Actualización/Eliminación.
  • Puede crear sus propios procedimientos almacenados personalizados, para las entidades y .netTiers generará los métodos que sirven como envoltorio de ese procedimiento almacenado y todo lo que se necesite, esto permite tener su propia lógica dentro de la API de .netTiers.
  • y mucho más.

Arquitectura de .netTiers
La arquitectura de .netTiers está basada en las guías de Microsoft patterns & practices, específicamente de: Designing Data Tier Components and Passing Data Through Tiers

Arquitectura Microsoft

Este concepto de capa de datos está compuesto por componentes de entidad del negocio personalizadas (que representan a los datos propiamente dichos), y componentes de lógica de acceso a datos (la lógica de persistencia).

Bases de datos y SQL
¿Cómo sabe .netTiers que generar? .netTiers utiliza el proveedor de metadata de CodeSmith que analiza una base de datos con el fin de crear un completo dominio de objetos, basado en las relaciones de la base de datos. El explorador de esquemas provee información sobre bases de datos, tablas, vistas, índices, procedimientos almacenados y más.

Buenas prácticas para diseñar bases de datos
En un mundo perfecto sería muy conveniente utilizar las siguientes recomendaciones para que la generación de código con .netTiers y CodeSmith sea óptima:

  • Los nombres de las tablas deben de estar en singular y en notación Pascal (primera letra de cada palabra compuesta en mayúsculas), ejemplo: Orden, DetalleOrden, Producto, etc.
  • Las descripciones para tablas, columnas y claves deben estar establecidas como atributos extendidos, para Microsoft SQL Server se utiliza la clave “MS_Description” para atributos extendidos.
  • .netTiers no asume relaciones, es necesario que se creen las relaciones de clave foránea a clave primaria específicamente en la base de datos.

Procedimientos almacenados personalizados
Existen muchos casos en los que se necesita extender la API de acceso a datos, sin perder las características de generación de la capa de datos. .netTiers ofrece la capacidad de escribir sus propios procedimientos almacenados, proporcionando la posibilidad de incrementar la funcionalidad que no ha sido generada automáticamente o las características que son especializadas de una aplicación en particular, un ejemplo sencillo sería el caso de necesitar la creación de un procedimiento almacenado personalizado para obtener un listado de productos con stock por debajo de un determinado límite. Cuando se inicia el proceso de generación, el explorador de esquemas de CodeSmith intenta descubrir toda la metadata para determinar el conjunto de resultados de un procedimiento almacenado así como también los parámetros que requiere tanto de entrada como de salida con sus respectivos tipos de datos, en base a esta información puede crear los métodos de las clases necesarias para realizar el mapeo.

Existen algunos casos en los que los procedimientos almacenados no retornan los resultados esperados, los procedimientos almacenados personalizados no funcionan cuando se utilizan tablas temporales dentro del procedimiento, esto se produce porque cuando el explorador de esquemas de CodeSmith está analizando la información no tiene los privilegios suficientes para crear las tablas temporales; una solución alternativa es utilizar variables de tabla en lugar de las tablas temporales.

Un detalle importante a tener en cuenta es que si queremos retornar entidades del dominio desde los procedimientos almacenados personalizados, necesitamos devolver en la consulta todos los datos de la tabla y en el orden correcto para que coincida con una entidad del dominio, cuando los resultados de un procedimiento almacenado personalizado no coincide con algún objeto entidad del dominio, se mapea como un DataSet genérico o como un objeto DataReader, lo cual es configurable.

Hasta aquí la parte introductoria de esta serie de artículos, en la que vimos una descripción un tanto más detallada de las bases de .netTiers, toda esta información fue obtenida de la documentación oficial de .netTiers que puede ser consultada en la siguiente dirección: .netTiers Documentation Wiki

Proyectos de Aplicación Web vs. Proyectos de Sitio Web (Web Application Projects vs. Web Site Projects)

Los proyectos de Aplicación Web hicieron su aparición como un add-in para Visual Studio 2005, luego debido a su gran difusión se incorporó como parte del Service Pack 1 para visual Studio 2005. Provee un modelo de proyecto Web similar al modelo de proyecto Web de Visual Studio 2003. Proporciona la posibilidad de definir una aplicación Web mediante un proyecto (.csproj o .vbproj), tal como era habitual en las versiones previas del .NET Framework, lo cual garantiza que todo el proyecto se compilará en un único ensamblado.

El objetivo de los proyectos de aplicación Web es dar respuesta a las peticiones de los usuarios. Algunos desarrolladores encontraron que la migración de aplicaciones de Visual Studio 2003 hacia el nuevo modelo de sitios web de Visual Studio 2005 presentaba muchos problemas haciéndolo en algunos casos impracticables, especialmente porque la compilación en el nuevo modelo de sitios Web de Visual Studio 2005 creaba múltiples ensamblados.

El nuevo modelo de proyectos de aplicación Web provee la misma semántica de los proyectos Webs de Visual Studio 2003. Esto incluye la estructura basadas en archivos de proyecto y el modelo de compilación donde todo el código del proyecto es compilado en un único ensamblado. Sin embargo, el nuevo tipo de proyecto pone a nuestra disposición todas las nuevas características de Visual Studio 2005 (Refactoring, diagramas de clase, desarrollo de pruebas, genéricos, etc.) y de ASP .NET 2.0 (páginas maestras, controles de datos, membresía e identidad, administración de roles, Web Parts, personalización, navegación de sitio, temas, etc.).

El modelo de proyectos de aplicación Web en visual Studio 2005 también hace innecesario dos requerimientos de Visual Studio 2003.

• Uso de extensiones de servidor de FrontPage. Ahora ya no es un requisito, aunque aún es soportado si el sitio Web aún utiliza estas extensiones.
• Uso de Internet Information Server (IIS). El nuevo tipo de proyectos soporta tanto IIS como el servidor ASP .NET de desarrollo incluido en Visual Studio 2005.

¿Cuál de los tipos de proyectos Web debemos utilizar?
Las siguientes tablas comparativas describen las diferencias entre los dos tipos de proyectos Web.

Opción o tarea

Proyectos de Aplicación Web

Proyectos de Sitio Web

Necesita migrar aplicaciones grandes de Visual Studio 2003.

X

 

Preferencia por el modelo de página simple sobre el modelo de código detrás.

 

X

Preferencia por la compilación dinámica y por trabajar sin generar todo el sitio por cada página modificada.

 

X

Necesita controlar los nombres de los ensamblados de salida.

X

 

Necesita generar un ensamblado por cada página

 

X

Necesita que clases independientes hagan referencia a páginas y controles de usuario Web.

X

 

Necesita generar una aplicación Web utilizando múltiples proyectos Web.

X

 

Necesita agregar pasos antes de generar (pre-build) y después de generar (post-build), durante el proceso de compilación.

X

 

Necesita abrir y editar cualquier directorio, como un proyecto Web, sin crear un archivo de proyecto.

 

X

Escenario

Proyectos de Aplicación Web

Proyectos de Sitio Web

Definición de proyecto

Similar a Visual Studio 2003. Solo archivos que son referenciados en el archivo de proyecto forman parte del proyecto, se muestran en el explorador de soluciones, y son compilados durante el proceso de generación. Debido a que existe un archivo de proyecto, algunos escenarios son más fáciles de implementar.

Se puede excluir archivos del proyecto y del programa de control de versiones con facilidad.

Los Proyectos de Sitio Web utilizan la estructura de directorios para definir los contenidos del proyecto. No existe archivo de proyecto y todos los archivos de la carpeta forman parte del proyecto.

Este tipo de proyecto es deseable si se tiene una estructura de carpetas que representa una aplicación ASP .NET, que se necesita editar en Visual Studio 2005 sin crear explícitamente un archivo de proyecto.

Compilación y resultado de generación.

El modelo de compilación para proyectos de aplicación Web es muy similar al modelo de Visual Studio 2003.

Todos los archivos de clases de código detrás y los archivos de clases independientes en el proyecto son compilados en un único ensamblado, el cual es colocado en la carpeta Bin. Puesto que se trata de un ensamblado único se puede especificar atributos como el nombre y versión del ensamblado, así como la localización del ensamblado de salida.

Otros tipos de escenarios son mejor implementados, como el patrón Modelo Vista Controlador (MVC), puesto que permite que las clases independientes en el proyecto hagan referencia a páginas y controles de usuario web.

El comando de Generación compila el proyecto de sitio Web únicamente para verificar errores de sintaxis. Para ejecutar el proyecto de sitio Web, se despliega los archivos de código fuente y se confía en la compilación dinámica de ASP .NET para compilar las páginas y clases de la aplicación.

Alternativamente, se puede precompilar el sitio para mejorar la performance, para lo cual se utiliza la misma semántica de la compilación dinámica.

Desarrollo iterativo

Para ejecutar y depurar páginas, se necesita generar todo el proyecto de aplicación Web. Generar todo el proyecto de aplicación Web usualmente es rápido, puesto que Visual Studio emplea un modelo de generación incremental, el cual compila solo los archivos que han sido modificados.

Se pueden configurar las opciones de generación de Visual Studio 2005 para cuando se ejecute un sitio web: Generar sitio web, una página individual, o ninguno en absoluto, en el último caso, cuando se ejecuta un sitio Web, Visual Studio simplemente lanza el explorador y le pasa la página actual o la página de inicio. La solicitud luego invoca la compilación dinámica de ASP .NET.

Por defecto, Visual Studio compila el proyecto de sitio Web completo en cualquier momento que se ejecute o depure una página. Esto se efectúa para identificar los errores de tiempo de compilación en cualquier lugar del sitio. Sin embargo una generación completa del sitio puede disminuir significativamente la velocidad del proceso iterativo de desarrollo, por tal motivo se recomienda cambiar las opciones de generación del proyecto para que compile sólo la página actual cuando se ejecute o depure.

Despliegue

Peusto que todos los archivos de clases son compilados en un ensamblado único, solo se necesita desplegar este ensamblado, junto con los archivos .aspx y .ascx, además de otros archivos estáticos de contenido.

En este modelo, los archivos .aspx no son compilados hasta que son ejecutados en el navegador. Sin embargo cuando se utiliza un proyecto de instalación Web, los archivos .aspx también pueden ser compilados e incluidos en el único ensamblado para su despliegue.

Cada vez que se despliegue el ensamblado único producido en este modelo, se reemplaza el código para todas las páginas del proyecto.

Tanto los archivos .aspx como los archivos de código detrás pueden ser compilados en ensamblados utilizando el comando “Publicar Sitio Web” de Visual Studio (El comando “Generar” no crea un conjunto de ensamblados que se puedan desplegar). Las opciones actualizables de publicación soportan únicamente compilación de archivos de código detrás, mientras que deja sin cambios a los archivos .aspx para el despliegue.

El modo de precompilado por defecto produce varios ensamblados en la carpeta Bin, típicamente uno por carpeta. La opción de nombres-fijos produce un ensamblado por página o control de usuario Web y pueden ser utilizadas para crear versiones desplegables de páginas individuales. Sin embargo, la opción de nombres-fijos incrementa el número de ensamblados y puede resultar en un incremento del uso de memoria.

Migración a partir de Visual Studio .NET 2003

Puesto que el modelo de proyecto de aplicación Web es el mismo que el de Visual Studio .NET 2003, la migración es generalmente simple y usualmente no requiere ninguna reestructuración de la aplicación.

La opción de compilación para Proyectos de Sitio Web es significativamente diferente a Visual Studio .NET 2003. Un asistente de conversión está disponible para migrar proyectos web existentes de Visual Studio 2003 a proyectos de sitios Web. Por razones obvias es usual la necesidad de arreglos manuales adicionales después de la conversión.

Para la mayoría de los escenarios, es preferible migrar a proyectos de aplicación Web.

Los cuadros comparativos muestran en detalle las diferencias entre los dos tipos de proyectos, para proyectos nuevos yo prefiero usar el nuevo modelo: Proyectos de Aplicación Web (Web Application Projects), en el caso de tener proyectos ya avanzados con el modelo de Proyectos de Sitio Web (Web Site Projects) no recomiendo la migración al nuevo modelo porque esta labor no es trivial y a menudo hay que realizar cambios manuales.

Puede consultar el artículo original en Ingles en el siguiente enlace: Introduction to Web Application Projects

Evento Load de Página ASPX Solo se Ejecuta la Primera Vez, Cuando se Abre la Página con JavaScript en Modo Modal.

Nuevamente uno de esos problemas que a uno lo ponen a pensar, y como ya es costumbre proviene de una amiga (que bueno que me hagan estas consultas, así tengo material para el Blog).

El Problema
Cuando abrimos una página ASP .Net en modo modal (diálogo), mediante la instrucción de JavaScript:

showModalDialog();

El código que ponemos en el controlador del evento load de la página que estamos abriendo, se ejecuta solo la primera vez que abrimos la página; en las siguientes veces, simplemente no ejecuta nada, es decir no se produce el evento load de la página.

La Solución
Como es costumbre lo primero que hice, fue reproducir el problema, y me pareció bastante extraño el comportamiento que tenía, luego pase a depurar el programa poniendo un punto de interrupción en la primera instrucción del controlador del evento Load de la página, ejecute el programa y como se esperaba se detuvo en el punto de interrupción, desde ahí comencé a ejecutarlo paso a paso presionando la tecla F10, hasta que se muestre la página por completo, luego cerré la página para abrirla de nuevo, y al abrir de nuevo la página, ¡o sorpresa!, ingresó nuevamente al controlador del evento Load donde estaba el punto de interrupción, y donde se suponía ya no debería de entrar. Así que detuve el proceso de depuración, ejecuté el programa y todo funcionó a la perfección.

Le comenté esto a mi amiga y le dije que después de depurar el programa, todo funcionaba a la perfección, pero ella no puedo reproducir lo que yo había logrado. Rato después cuando probé nuevamente el programa, surgió nuevamente el problema y como era de esperar, mi amiga se rió en mi cara.

Así que me puse a buscar la solución definitiva, luego de probar con muchas posibles soluciones y claro después de buscar en San Google, recordé que cuando una página es servida desde la caché de salida, no se ejecuta ningún código del lado del servidor. Así que procedí a desactivar la caché de salida de la página en cuestión, y que creen, eso solucionó el problema definitivamente, resulta que en las páginas que se muestran como diálogo (Modal), la caché de salida se activa de forma automática y claro no hay manera que se ejecute nuestro controlador de evento Load. Para desactivar la caché de salida de una página basta con colocar la siguiente declaración en el archivo apsx de la página:

<%@ OutputCache Location=”None” VaryByParam=”None” %>

Justo después de la directiva @Page.

Error de Codificación al Recuperar Datos con Caracteres Especiales Como la Letra Ñ de Gridview a un TextBox

Como es costumbre este post se origina con la consulta de una amiga, que me solicitó ayuda con un pequeño problema que se le presentó (el problema parecía tan pequeño que hasta se sonrojaba al hacer la consulta).

El Problema
Al recuperar los datos de un campo de la fila seleccionada en un GridView, a un control TextBox, manda caracteres extraños cuando se tratan de letras especiales como la “ñ” o las vocales con tilde, para recuperar los datos se utiliza el siguiente código en el evento RowCommand, del GridView.

protected void GridView1_RowCommand(object sender,
    GridViewCommandEventArgs e)
{
     if(e.CommandName == “Select”)
     {
        //Seleccionamos la Fila Actual
        GridView1.SelectedIndex =
            Convert.ToInt32(e.CommandArgument.ToString());

         //Recuperamos el valor de la segunda celda
        TextBox1.Text = GridView1.SelectedRow.Cells[1].Text;
     }
}

La Solución
Desde el inicio sospeché que el problema se trataba de la codificación de la página, recordé un post que había leído solo hace un momento donde se mostraba la forma de poner la codificación por defecto, seguí los pasos que se indicaban, pero no solucionó el problema.

Entonces hice la prueba cambiando el control TextBox por un control Label, grande fue mi sorpresa cuando todo funcionó a la perfección, entonces el problema estaba en el TextBox que por alguna razón no decodificaba los caracteres especiales.

Luego recordé que había una función para codificar texto que se utilizaba en seguridad, para evitar que el usuario ingrese caracteres especiales HttpUtility.HtmlEncode() y su correspondiente método para decodificarlo HttpUtility.HtmlDecode(). Como el problema es que los caracteres están codificados y por alguna razón extraña que no llego a entender no se decodifica al asignarlo a un TextBox, para solucionarlo tenemos que utilizar HttpUtility.HtmlDecode(), para decodificarlo manualmente.

protected void GridView1_RowCommand(object sender,
    GridViewCommandEventArgs e)
{
    if(e.CommandName == “Select”)
    {
        //Seleccionamos la Fila Actual
        GridView1.SelectedIndex =
            Convert.ToInt32(e.CommandArgument.ToString());

        //Recuperamos el valor de la segunda celda decodificándola
        TextBox1.Text =
            HttpUtility.HtmlDecode(GridView1.SelectedRow.Cells[1].Text);

    }
}

Temas y Skins con CSS para Mostrar una Interfaz de Usuario Consistente en ASP .NET 2.0

Una primera aproximación para lograr un interfaz de usuario consistente en ASP NET son las hojas de estilo CSS (Cascading Style Sheets), que nos ofrecen una gran mejora al centralizar la información sobre el estilo que nuestros Controles Web lucirán en archivos de hoja de estilos, en lugar de estar poniendo la información de estilo directamente en las propiedades de los controles, colocamos el nombre de estilo CSS. La ventaja de esta aproximación es que al cambiar el archivo de hojas de estilo, el cambio se verá reflejado en todos los controles que utilicen dicha hoja de estilos. La desventaja es que aún hay que colocar en cada propiedad de los controles el nombre del estilo CSS.

Para superar las limitaciones de las hojas de estilo CSS, utilizaremos Temas y Skins.

Tema.- Un tema es una colección de valores de propiedades que nos permiten definir la apariencia de páginas y controles, para luego aplicar esta apariencia a través de toda la aplicación Web asegurando la consistencia de la interfaz de usuario.

Los temas están compuestos por un conjunto de elementos como: Skins, hojas de estilo (CSS), imágenes y otros recursos; como mínimo un tema debe contener skins; los temas se crean en carpetas especiales del Sitio Web (App_Themes).

Skin.- Son archivos con extensión .skin y contiene valores para propiedades de controles individuales como GridView, DetailsView, etc. En la definición del skin se indica a qué control le corresponde.

Ejemplo.- El ejemplo que presentamos es bastante sencillo para ver como agregar temas a un Sitio Web.

1. Agregar un nuevo archivo de hoja de estilos, le podemos poner como nombre “Estilos.css”, en este archivo definimos los estilos que tendrá nuestro sitio web por ejemplo:

.SelectedDayStyle
{
    background-color: #41519A;
    font-weight: bold;
    color: White;
}

Así todos los estimos que vamos a necesitar para definir nuestros skins.

2. Luego agregamos un nuevo skin mediante, agregar nuevo elemento de Visual Studio, como nombre le podemos poner “GridView.skin”, visual estudio nos alertara que estamos intentando crear un skin dentro del sitio web, y nos sugiere crear una carpeta especial para los temas a lo cual respondemos que si; si todavía no existía ningún skin, visual Studio creará la carpeta “App_Themes” y dentro de esta carpeta creará un tema con el mismo nombre del skin, y el nuevo skin dentro del tema, el contenido del skin es similar al siguiente:

<asp:GridView runat="server" CssClass="DataWebControlStyle">
     <AlternatingRowStyle CssClass="AlternatingRowStyle" />
     <RowStyle CssClass="RowStyle" />
     <HeaderStyle CssClass="HeaderStyle" />
     <FooterStyle CssClass="FooterStyle" />
     <PagerStyle CssClass="PagerStyle" />  
</asp:GridView>

Todos los estilos a los que se hace referencia en el skin deben estar previamente definidos en el archivo de hojas de estilo.

Este skin se encargará de poner automáticamente los estilos a los GridView de nuestro sitio web.

3. Una vez creado el tema con sus respectivos skins, es hora de aplicar los temas a nuestro sitio web, podemos aplicar los temas página por página o aplicarlo a todo el sitio web, mediante el archivo de configuración, utilizaremos la segunda forma para lo cual tenemos que agregar en el archivo de configuración la siguiente línea, suponiendo que el tema se llama “Estandar”.

<pages styleSheetTheme="Estandar" />

4. Finalmente tenemos que hacer una referencia al archivo de hojas de estilo desde nuestra página:

<head runat="server">
     <title>Demos Skins</title>
     <link href="Estilos.css" rel="stylesheet" type="text/css" />
</head>

Ahora dependiendo de los skins que hayamos creado para los temas al agregar los controles a nuestra página tomarán automáticamente los estilos del tema.

Temas

Descargar Ejemplo: Ejemplo Temas y Skins
Favor de darle clic derecho y guardar destino como…, una vez descargado cambiar la extensión a .zip, y descomprimirlo (todo esto porque no me dejan subir archivos zip).

De la siguiente página se puede descargar un sitio web con algunos temas listos para utilizar: .Net Treats & Tricks