martes, diciembre 02, 2008

Integración con SkypeWeb API desde ASP.net y Mono

Todos los códigos de este artículo os los podéis descargar desde:
  • Proyecto de Visual Web Developer Express 2005, aquí
  • Solución de Monodevelop, aquí

En este artículo vamos a ver una pequeña integración con el API de Skype para plataformas web. Lo que vamos a hacer es implementar un pequeño control de presencia que podremos utilizar en nuestra web. La idea es que, a través del API Web de Skype, interrogar sobre nuestro estado en Skype y, en base a la respuesta, mostrar un icono de estado.

¿Para qué nos puede servir esto, os preguntareis? Pues, por ejemplo, Skype es una muy buena opción para dar soporte a usuario y siempre queda bien poner un icono de que estamos online o no en nuestra página web. También sirve como base para cuando Skype ofrezca más servicios vía web, en fin, y como curiosidad.

Vamos al lío entonces...
Lo primero que tenemos que hacer es configurar Skype para permitirle que notifique nuestro estado. En Herramientas -> Opciones, en la pestaña Privacidad, marcaremos la opción "Mostrar mi estado de conexión en la web":




















Una vez marcada esta opción, el servidor de Skype permitirá que le interroguen sobre el estado de nuestro usuario a través de su API. Skype provee de dos métodos por los que obtener el estado de un usuario: vía consulta DNS, vía petición HTTP. Nosotros vamos a ver la segunda opción. La sintaxis para interrogar es la siguiente:

http://mystatus.skype.com/[nombre_usuario].extension

En [nombre_usuario] pondremos el usuario sobre el que queremos obtener el estado, en este caso, será el nuestro, y en extensión le indicaremos a Skype cómo queremos que nos devuelva la información. Disponemos de cuatro opciones:
  • Sin extensión: Skype devuelve una imagen con el estado del usuario (en la documentación se muestra las diferentes imágenes de que dispone)
  • xml: devuelve un XML con el estado del usuario en diferentes idiomas
  • txt: devuelve el estado del usuario en formato texto en el idioma del explorador
  • num: devuelve un código equivalente al estado del usuario (ésta es la opción que vamos a utilizar).
Lo que vamos a hacer, por lo tanto, es lanzar una petición http al servidor de Skype, obtener la respuesta y en base al código que nos devuelva, poner una imagen u otra en pantalla. Los posibles códigos de retorno son:
  • 0: desconocido
  • 1: offline
  • 2: online
  • 3: fuera
  • 4: no disponible
  • 5: no molestar
  • 6: invisible
  • 7: skype me


Vamos a codificar el asunto
La página de demo la podéis encontrar pinchando aquí

El proyecto está realizado tanto para Monodevelop (para los de Linux) como para Web Developer Express Edition 2005 (para los de Windows). La única diferencia es que Mono no dispone de soporte para el AJAX de ASP.net y en la versión de Mono está quitado el tema de AJAX.

La pantalla del proyecto es la siguiente:
















Introduciremos el nombre del usuario a interrogar y pulsaremos sobre el botón "Buscar desde Servidor". El código que se ejecuta en este botón es:
















Lo primero que se hace es realizar un HttpWebRequest hacia el servidor de Skype pasándole el usuario que se ha introducido en el textbox. Obtenemos la respuesta y creamos un Stream para ir leyendo el resultado que nos devuelve Skype.

Al leer el código de la respuesta, ponemos en pantalla una imagen correspondiente al estado del usuario. En la carpeta img disponemos de 8 imágenes llamadas 0.png, 1.png, 2.png,... en función del código devuelto, pondremos una u otra.

El resultado es el siguiente:
















En el proyecto de Web Developer, le he puesto un UpdatePanel para que no haya refrescos de pantalla, mientras que en Mono no está puesto.

Control de Presencia
Con esta pequeña integración podemos poner un icono en nuestra página web indicando nuestro estado en Skype. Tenemos dos alternativas:
  • Poner un timer para que vaya refrescando el estado cada x tiempo.
  • Realizar esta operación en el Page_Load y actualizar el estado solamente cuando se acceda a la página.
También existe la posibilidad de implementar las llamadas desde Javascript a través de un Proxy y manejar la respuesta directamente desde la página (en Javascript).

En fin, espero que os haya gustado este pequeño post, y que os sirva para investigar más allá y para poner vuestro icono de presencia en vuestras webs.

lunes, noviembre 03, 2008

Gráficos dinámicos con Open Flash Chart en ASP.NET y UpdatePanels

Todos los códigos de este post os los podéis descargar desde aquí. Todo el proyecto ha sido realizado con Visual Web Developer 2005 Express Edition.

Buenas, hace tiempo que tenía ganas de escribir este artículo sobre la creación de gráficos sobre ASP.NET utilizando la librería flash OpenFlashChart. Este componente flash nos permite crear gráficos muy versátiles, de muy diversos tipos y totalmente customizables en estilo. Además, es código abierto y libre tanto para uso personal como comercial. Aunque ya ha sido liberada la versión 2 (con cambios sustanciales en la forma de pasar los datos), este artículo está basado en la versión 1.9.7 que fue la que inicialmente me descargué en su momento y con la que trabajé.

Introducción del por qué y el cómo
En la página de OFC podéis encontrar multitud de ejemplos, tutoriales, foros, etc. por lo que no voy a explicar aquí los diferentes tipos de gráficos y las funcionalidades de las que dispone OFC.

Después de leer la documentación y de probar con la librería, me surgió un problema, la necesidad de pasarle datos dinámicamente desde código al gráfico y que se refrescará utilizando UpdatePanels de ASP.net. Es decir, poder generar, actualizar, cambiar el tipo de gráfico, todo ello desde código (entiéndase base de datos) y utilizando el AJAX de ASP.NET. Para conseguir tal propósito, me he apoyado en la librería .NET que viene con la descarga de OFC llamada "OpenFlashChartLibrary.dll". Esta librería trae un control de servidor para renderizar el gráfico, pero en este proyecto no se utiliza, sólo utilizaremos las clases que nos permiten generar el código de los gráficos que entiende el componente flash.

¿Qué es lo que queremos conseguir?
Puedes acceder a las páginas de demo pulsando aquí

Si véis en las páginas de demo, lo que queremos conseguir es un entorno basado en AJAX (UpdatePanels) para la generación y actualización de gráficos. En el ejemplo hay dos páginas:
  • La primera (Ejemplo de gráfico dinámico): permite generar un gráfico dinámicamente y anexarle dos series más. Además podemos elegir si cada serie la queremos en forma de barras o líneas. Si elegimos el gráfico como tarta sólo se renderiza la primera serie. Además el gráfico recalcula automáticamente los márgenes de valores máximos a mostrar en base a los datos introducidos (hay un error en la demo, sólo recalcula para la primera serie, lo siente).















  • La segunda (Ejemplo de varios gráficos): nos permite generar dos gráficos simultáneamente y actualizarlos de forma independiente, cada uno con sus controles de tipo de gráfico y la serie a mostrar.

















¿Cómo lo hacemos?
Todo el tema se basa en la clase RenderizadorGrafico.cs que se encuentra en la carpeta App_Code del proyecto. Dicha clase se apoya en la libreria OpenFlasChartLibrary para la generación del código del gráfico. El funcionamiento general es el siguiente:
  1. Le pasamos a la clase la primera serie a pintar junto con varios valores generales (título del gráfico, posiciones decimales, etc)
  2. Si tenemos más series le vamos pasando cada una de las series restantes (debe coincidir el número de valores de la serie con los del eje X), con su nombre.
  3. Llamamos al método RenderizarGrafico pasándole el código del gráfico (devuelto por los métodos anteriores), la ubicación del componente flash OFC, el div donde queremos que se coloque el gráfico y la página en la que estamos. Este método se encargará de generar el código javascript necesario para mostrar el gráfico y lo inyectará en la página.
La clase RenderizadorGrafico.cs en detalle
La clase RenderizadorGrafico.cs es la encargada de generar el código que entiende el componente OFC para la generación de los gráficos. Esta clase se apoya en la librería OpenFlashChartLibrary.dll que viene con OFC y que simplifica la generación del código. Los métodos de los que dispone la clase son:
  • RenderizarGrafico: se le pasa el código del gráfico (obtenido con los otros métodos), la ruta del componente OFC, el div donde colocar el gráfico (uno por cada gráfico) y la página que llama al método. Este método tiene una sobrecarga para cuando tenemos varios gráficos en pantalla en la que le pasamos arrays con los diferentes códigos y los divs donde colocar cada gráfico.
  • GenerarCodigoGrafico: este método se encarga de generar el código del gráfico que le pasaremos al método RenderizarGrafico. A este método le pasaremos la serie tanto para el eje X como para el eje Y y diferentes parámetros de visualización. Este método dispone de una sobrecarga para la representación de gráficos en forma de tarta que se manejan de forma diferente. En esta sobrecarga se le pasan los valores en formato Object[,], pasando en la primera dimensión el valor y en la segunda la etiqueta.
  • AnexarGrafico: este método permite anexarle más series a un gráfico.
La clase define al inicio el estilo que se va a aplicar para los gráficos, teniendo varios struct y constantes que se van utilizando a lo largo de los métodos. En cualquier momento se puede modificar dichos valores para cambiar el aspecto de nuestros gráficos.













La clase dispone, al final de un par de métodos que se utilizan para corregir ciertos fallos que me encontré en la librería .net en la generación de gráficos del tipo tarta.

¿Cómo genera la clase el gráfico?
La clase, en el método RenderizarGráfico, genera el código javascript necesario para renderizar el gráfico en pantalla. Utiliza el fichero swfobject.js para la incrustación de elementos flash en páginas web y lo inyecta en la página. Para inyectar el código hace uso del elemento ScriptManager del AJAX de ASP.net.














¿Cómo le pasamos los datos?
Tenemos dos formas de pasarle los datos a la clase dependiendo del tipo de gráfico que vamos a realizar. Si vamos a crear un gráfico que no sea del tipo tarta tendremos que crearnos lo siguiente:
  • Array de strings con los valores del eje X
  • Array de doubles con los valores del eje Y
  • Float con el valor máximo de la gráfica
  • Float con el valor mínimo
Si vamos a generar un gráfico del tipo tarta tendremos que crearnos lo siguiente:
  • Array de objects de dos dimensiones (object[2,numero elementos]) que tenga en la dimensión 0 el valor y en la dimensión 1 la etiqueta para ese valor. El componente se encargará de pintarlos en el orden correcto.
Lo último, ¿qué código ponemos en el aspx?
Finalmente, para que nuestro gráfico se vea correctamente tendremos que crearnos en la página un div donde vaya a ser colocado. Para utilizar AJAX en los refrescos del gráfico, pondremos dicho div dentro de una estructura UpdatePanel y le pondremos los triggers pertinentes.


















Final
Espero que os haya gustado este artículo y que os pueda servir. Personalmente, esta solución se encuentra en entornos de producción y funciona perfectamente. Como siempre, agradeceré cualquier comentario.

lunes, octubre 06, 2008

Inscripción al concurso de blogs del 20 minutos

He inscrito este blog en el concurso de la revista 20 minutos, en la categoría de mejor blog de tecnología. Si os gusta el contenido que publicamos aquí, os agradeceríamos que nos votaseis en cuanto empiecen las votaciones (15 de Octubre).

La dirección del concurso es http://www.20minutos.es/premios_20_blogs y el nombre con el que se ha inscrito éste es "N-Idea de muchos temas".

miércoles, agosto 27, 2008

Uso de Transacciones en C# con TableAdapters

Actualización (10-10-2008): el enlace correcto al artículo de Mike Pagel es http://www.codeproject.com/KB/dotnet/transactionta.aspx. Gracias Diego.
Actualización: ha habido un error con el enlace el artículo de Mike Pagel, podéis descargaros su clase desde la dirección http://www.nidea-soluciones.com/PruebasAJAX/TransactionSupport.zip

En este nuevo artículo voy a abordar el tema de la gestión de transacciones cuando trabajamos con TableAdapters generados por Visual Studio. El trabajo con TableAdapters generados por Visual Studio es muy cómodo, en el sentido que genera toda la lógica de acceso a datos y la representación de los mismos con Datatables, pero en el momento en que queremos utilizar transacciones en nuestros accesos a base de datos, el tema se complica. En determinados entornos, sobre todo a la hora de programar sistemas grandes, el uso de transacciones se vuelve inevitable. En este artículo vamos a ver una forma muy cómoda de usar transacciones con TableAdapters generados por Visual Studio.

Un poquito de teoría
Antes de nada, vamos a ver un poco cómo va el tema de las transacciones. ¿Para qué sirven las transacciones? Una transacción lo que nos permite es controlar un grupo de sentencias a base de datos de forma que podamos o bien dar marcha atrás a todas las sentencias o bien confirmar el bloque completo. El control del grupo de sentencias lo lleva la base de datos, de forma que el programador sólo debe indicar si se confirma (Commit Transaction) o no (Rollback Transaction) el grupo de sentencias. En el siguiente dibujo os pongo un ejemplo:





Como podéis ver, desde el momento en el que iniciamos la transacción, todas las operaciones quedan registradas y si realizamos un rollback deshacemos las hechas y si hacemos un commit, la transacción se termina y los cambios quedan confirmados.
Pero, ¿qué pasa si hacemos un select sobre un campo actualizado en una transacción no confirmada? Buena pregunta, porque se plantea un problema, si la sentencia no está confirmada, el gestor de base de datos no puede asegurar que ese dato sea correcto. En ese caso entran en juego los niveles de aislamiento de transacciones (Isolation Levels) que, básicamente, lo que deciden es cómo se debe comportar el gestor de base de datos en estas situaciones.

Bueno, al lío
Vamos a ir paso a paso, lo primero que vamos a hacer es crearnos una aplicación de Windows Forms en C# (me supongo que sabéis hacerlo). Para todo vamos a utilizar la versión gratuita (Express) de visual studio, en concreto Visual C# 2005 Express Edition.

1. Crearse un proyecto "Aplicación para Windows"
2. En la pantalla principal nos creamos los siguientes controles











3. Nos creamos una nueva base de datos en SQL Server 2005 Express Edition que se llame "PruebaTransacciones" con una tabla llamada "Tabla1" que contenga 2 campos "Id" y "Nombre" y otra llamada "Tabla2" con los mismos campos. La definición es la siguiente:
























4. Nos creamos en nuestro proyecto dos TableAdapters, uno para cada una de las tablas que hemos creado en base de datos.















Por ahora, nuestro proyecto y los TableAdapters nos tienen que quedar de la siguiente manera:









Ahora mismo no disponemos de soporte para transacciones porque los tableadapters generados no lo incluyen. Es en este momento cuando le vamos a introducir esa nueva funcionalidad. Vamos a utilizar una clase creada por Mike Pagel y que podéis encontrar en su artículo del CodeProject http://www.codeproject.com/useritems/typed_dataset_transaction.asp. Lo que vamos a hacer es sobreescribir la clase base de los tableadapters con esta que incorpora las funcionalidades de las transacciones. Para ello, incluiremos la clase en nuestro proyecto y en las propiedades de los TableAdapters, pondremos el nombre de la clase en la propiedad BaseClass:










En mi caso le he puesto Transaccion.TransactionSupport porque el namespace de la clase es Transaccion.

Utilizar las transacciones
Ahora que tenemos soporte para transacciones vamos a utilizarlas en nuestra pantalla. Teníamos creados un botón y dos radiobuttons, vamos a programar el evento Click del botón de la siguiente manera:






















Lo que hacemos es insertar un registro en la tabla1 y confirmamos o deshacemos la operación en base a los radiobuttons que se pusieron. Ahora vamos a modificar un poco el código para realizar una operación sobre las dos tablas compartiendo la transacción:
























En este caso, hemos igualado la transacción secundaria con la principal para poder interactuar con varias tablas a la vez. El último paso es: ¿cómo pasar una transacción por diferentes clases y métodos para actuar sobre múltiples tablas sin tenerlo todo en el mismo método? La pregunta es larga pero la respuesta es corta, veamos la siguiente modificación al método del botón:






















En este caso, estamos instanciando la clase ManejadorTabla2 y llamando al método ActualizarTabla para guardar los cambios en la tabla2. A este método, aparte de los registros le estamos pasando la transacción. El código interno del método es el siguiente:






















Lo que hacemos en este método es controlar si se pasa como argumento una transacción o no. Si el método falla, lo que hacemos es devolver un false para el método que controla la transacción decida qué hay que hacer. En caso que no se pase transacción, el método se comporta de forma normal.

Conclusión
Ciertamente, el uso de transacciones en entornos grandes es obligatorio. No nos podemos plantear un sistema sin control de transacciones porque antes o después se haría inviable su programación. Creo que esta solución al problema es muy simple, elegante y efectiva y os animo a probarla. Como siguiente paso para el que guste de estos temas queda la modificación de la clase para adaptarlas a entornos no SQLServer como puede ser MySql. El código es muy sencillo y creo que se podría modificar rápidamente.

En fin espero que os haya gustado este articulillo sobre transacciones.

jueves, julio 03, 2008

Motor de Informes Dinámicos con itextsharp (II)

Hola de nuevo a todos, ha pasado un tiempo desde la primera parte del tutorial, pero ya he encontrado tiempo para escribir esta segunda parte (más interesante que la primera). En la primera parte vimos cómo funcionaba la librería itext# para generar informes PDF al vuelo. En esta segunda parte lo que veremos será cómo crear plantillas XML para juntarlas posteriormente con datos y generar el PDF.

El inicio de todo
Lo que vamos a hacer es por un lado, crearnos una plantilla XML con parámetros, por otro lado, generar nuestros datos en formato XML (para poder guardarlos en base de datos) y finalmente, juntar las dos cosas y obtener, al vuelo, la plantilla con los datos en formato PDF.

El flujo de datos

El funcionamiento del sistema de plantillas es el siguiente.

















Desde la página obtenemos los datos en XML y la plantilla, lo cual va en sesión a la página ImpresionPDF.aspx. Esa página se encarga de llamar a la clase ParseadorPDF.cs que es la que contiene la lógica de negocio para generar el PDF al vuelo. Esa clase devuelve un MemoryStream con el PDF a la página, la cual lo renderizará en pantalla.

La plantilla XML
El primer paso es generarnos la plantilla XML con los tags adecuados que entienda la librería. Para un ejemplo de los tags que se pueden utilizar, en la ayuda nos ofrecen algunos ejemplos. Nosotros vamos a trabajar con el siguiente XML que es muy sencillo:






















En este informe utilizamos diferentes tags, como: table, row, cell, newline, itext(obligatorio al inicio y al fin) y en medio hemos introducido tags propios:nomAE, numAE, nomAl y dniAl. Estos serán los parámetros que se sustituirán posteriormente por los valores que le digamos. La librería itextsharp tiene un problema a la hora de parsear los XML en PDFs y es que NO PUEDE TENER ESPACIOS EN BLANCO DENTRO DE LOS TAGS TABLES. Es decir, para generar una plantilla XML, no podemos indentarla, sino que tiene que ir como se muestra en la imagen o dará un error de ejecución.

Los datos a parsear
En este paso, lo que vamos a ver es cómo pasarle los datos que queremos que aparezcan en el informe a la librería para que los junte correctamente. Le vamos a pasar un vector con dos dimensiones, en una dimensión irá un esquema XML con los datos a imprimir y en la otra irá la plantilla a utilizar. El esquema XML es como el siguiente:













A la hora de crear el documento veremos cómo crear este esquema XML para guardarlo en base de datos. Una vez recuperado el documento XML, la creación del vector es la siguiente:








En el vector de objetos “datos” guardamos el XML y la plantilla correspondiente. Seguidamente llamamos a la pantalla ImpresionPDF.aspx que se encargará de generar la plantilla XML.


La página ImpresionPDF.aspx

Esta página es la encargada de recibir los datos desde la sesión y llamar a la clase encargada de generar el PDF. Además de esto, obtiene de base de datos los márgenes a aplicar, las dimensiones del PDF y varios datos de formato propios de la plantilla. Una vez recuperados estos datos llama al método GenerarPDF de la clase ParseadorPDF:








El método devuelve un MemoryStream con el fichero PDF para ser renderizado. Veamos ahora cómo se produce el parseo real de los datos.


La clase ParseadorPDF.cs

Esta es la clase que se encarga de juntar las plantillas con sus respectivos datos. El flujo es el siguiente:

1. Crear el PDF global que va a ser devuelto y ponerle las dimensiones precisas:






2. Recorrer los datos y plantillas pasadas para ir tratando a cada una de ellas. Este método permite que se pasen a la vez varios XML de datos con varias plantillas en el mismo vector de objetos, por lo que lo primero es ir recorriendo las diferentes plantillas. Para cada XML de datos realizamos una conversión a un vector de objects con los datos que es lo que entiende el método:






3. Para cada plantilla con sus datos los juntamos en un PDF temporal que es guardado en una ruta temporal y posteriormente anexado al PDF global que se creó al inicio. En esta parte es donde se realiza la unión real de los datos, creando un hashtable que enlaza cada parámetro con su valor y llamando al método Parse de la librería PDF:












4. Una vez realizado el parseo, lo que tenemos que hacer es eliminar los ficheros temporales que hemos ido creando en el proceso. Estos ficheros se encuentran guardados en la variable subFicheros.

El método ParsearDatos

Este método es el encargado de crear un hashtable que enlace cada parámetro con su valor. Lo primero es crear el hashtable y asignarle los primeros valores fijos:














Seguidamente, para cada parámetro, tendremos que unirlo con su parámetro y asignarle un XMLPeer correcto:











Dependiendo del tipo de parámetro que sea será tratado de una forma o de otra, lo que rellenamos en el método es la propiedad peer.Content con el valor del parámetro y si le queremos incluir más atributos rellenamos la propiedad peer.AddValue.


El método ConcatenarPaginas

Este método se encarga de unir las páginas de los PDF temporales que creamos con la del PDF global que será devuelto a la capa de presentación. El código de este método es el siguiente:












El final

Bueno, con esto termino el artículo. Espero haberos dado una idea inicial de cómo realizar un motor de plantillas basado en XML para la librería itextsharp. No he podido explicar el funcionamiento completo porque eso exigiría muchísimo tiempo pero creo haber ahondado bastante para que podáis seguir vosotros.


Como siempre, para cualquier duda que os surja aquí estoy.