viernes, 28 de abril de 2017

Utilizando la clase NpgsqlError de la enumeración NpgsqlException.Errors

Una forma precisa de diagnosticar los errores PostgreSQL en una aplicación :NET es mediante el uso de la clase NpgsqlError de la cual se pueden obtener detalles adicionales a la excepción generada esta clase esta incluida en la enumeración Errors la cual al recorrerse y consultar las propiedades de la clase NpgsqlError podemos obtener información específica acerca de los errores y advertencias que se generan al ejecutar los comandos SQL o Store procedures en PostgreSQL por medio de una aplicación .NET que haga uso del driver Npgsql.

A continuación mostramos una aplicación de consola que se conecta a una base de datos PostgreSQL, ejecuta un comando SQL para crear un nuevo registro en una tabla y envia la excepción generada hacia un archivo de texto.


Aquí el código para crear la tabla Books


Aqui el código de la clase Book



Aquí el código de la clase BooksManager


using System;
using System.Data;
using Npgsql;
using NpgsqlTypes;
using TestNpgsqlError;

namespace TestNpgsqlError
{
    public class BooksManager
    {

        public static int Insert(Book b)
        {
            var resp = 0;
            var commandText = @"INSERT INTO Books(title,numpages,pubyear,created)
VALUES(:title, :numpages, :pubyear, :created)";
            try
            {
                string connStr = @"Server=127.0.0.1;Port=5432;Database=testBook;
         User ID=postgres;Password=Pa$$W0rd";
                using (NpgsqlConnection conn = new NpgsqlConnection(connStr))
                {
                    conn.Open();
                    using (NpgsqlCommand cmd = new NpgsqlCommand(commandText, conn))
                    {
                        cmd.CommandType = CommandType.Text;
                        cmd.Parameters.Add("title", NpgsqlDbType.Varchar).Value = b.Title;
                        cmd.Parameters.Add("numpages", NpgsqlDbType.Numeric).Value = b.NumPages;
                        cmd.Parameters.Add("pubyear", NpgsqlDbType.Numeric).Value = b.PubYear;
                        cmd.Parameters.Add("created", NpgsqlDbType.Timestamp).Value = DateTime.UtcNow;
                        resp = cmd.ExecuteNonQuery();
                    }
                }
                return resp;
            }
            catch (NpgsqlException ex)
            {
                LogErrors(ex);
                throw new ApplicationException(@"A DataBase error has occurred, 
please see the log file.");
            }
            catch (Exception ex)
            {
                Logger.Error(ex.Message);
                throw new Exception("A exception has occured, please see the log file.");
            }
        }

        static void LogErrors(NpgsqlException ex)
        {
            string msg = null;
            foreach (NpgsqlError item in ex.Errors)
            {
                msg = String.Format("Code: {0}\n", item.Code);
                msg += String.Format("Detail: {0}\n", item.Detail);
                msg += String.Format("Error: {0}\n", item.ErrorSql);
                msg += String.Format("File: {0}\n", item.File);
                msg += String.Format("Hint: {0}\n", item.Hint);
                msg += String.Format("Line: {0}\n", item.Line);
                msg += String.Format("Message: {0}\n", item.Message);
                msg += String.Format("Position: {0}\n", item.Position);
                msg += String.Format("Routine: {0}\n", item.Routine);
                msg += String.Format("Severity: {0}\n", item.Severity);
                msg += String.Format("Where: {0}\n", item.Where);
                msg += String.Format("======{0}======\n", DateTime.Now.ToString());
            }
            Logger.Error(msg);
        }
    }
}

Aquí el código de la clase Logger


Finalmente, el código la clase principal MainClass.


En la clase BooksManager se encuentra el método estático LogErrors en donde se realiza toda la funcionalidad, aquí es donde se itera por la enumeración Errors de la clase NpgsqlException y se escribe la información en el archivo de texto.


Antes de compilar y ejecutar la aplicación vamos a ocasionar un error en la sentencia de la consulta SQL. Por ejemplo no escribir correctamente el nombre de la tabla.



var commandText = "INSERT INTO Booksssss(title,numpages,pubyear,created)
VALUES(:title, :numpages, :pubyear, :created)";

Al compilar y ejecutar la aplicación veremos la excepción generada a propósito para poder consultar el archivo log y ver más detalles acerca de la excepción generada.
Compilamos la aplicación con los siguientes comandos:

$ dmcs -t:library -r:System.Data,Npgsql Book.cs BooksManager.cs Logger.cs 
/out:TestNpgsqlError.dll

$ dmcs -r:TestNpgsqlError.dll Main.cs

Ejecutamos la aplicación, como se muestra en la siguiente imagen:



Otra prueba es si escribimos erróneamente los parámetros de la cadena de conexión, por ejemplo cambiar el usuario de la base de datos o no teclear correctamente el nombre de la base de datos.



string connStr = "Server=127.0.0.1;Port=5432;Database=testBooks;User ID=postgressss;
Password=Pa$$W0rd";

Podemos consultar la bitácora y ver como por cada excepción se genera un código y los detalles de la excepción.


Descargar el código fuente del ejemplo (Download the source code)

jueves, 13 de abril de 2017

Publicación de archivos con ASP.NET en Linux y Apache con HtmlInputFile Server Control y en Windows con FileUpload Server Control

Una de las operaciones más frecuentes de las aplicaciones web (Web applications) es la carga de archivos (file upload), que es la acción donde el usuario puede seleccionar un archivo de su computadora y mediante el uso de un formulario en una página web puede transferir el archivo desde el sistema de archivos local hacia el sistema de archivos del servidor donde se encuentre la página web.

ASP .NET tiene dos formas de hacer esta funcionalidad, una mediante un control HtmlInputFile la cual se ha soportado desde el Framework 1.1 y la otra mediante un control FileUpload la cual se soporta a partir del Framework 2.0. Para este mini tutorial mostraré dos ejemplos de la implementación de la publicación de documentos con ASP .NET, el primero utilizando el control HtmlInputFile y el segundo utilizando el control FileUpload.

Fig 1. El código ASP.NET del ejemplo con un control HtmlInputFile.


Fig 2. El código C# del ejemplo con un control HtmlInputFile.



En este segundo ejemplo muestro la implementación del FileUpload server control ASP.NET (este control se encuentra disponible desde la versión 2.0 del Framework) con el siguiente código.

Fig 3. El código ASP.NET del ejemplo con server control FileUpload.


Fig 4. El código C# del ejemplo con server control FileUpload.


Para ambos casos el archivo de configuración web.config es el mismo, lo que cambia en ambos casos es el valor de la llave publishPath dentro de las etiquetas

<appSettings>
, ya que para el Ejemplo 1.0 que lo ejecutaremos en Linux utilizando Apache y Mono.
Por lo que el valor se establece en /home/martin/public_html/Downloads como se muestra en el web.config a continuación:

Fig 5. Archivo Web.config para la implementación en Apache bajo Linux


En el caso del ejemplo 2.0 lo ejecutaremos en IIS 7.0 y Windows. Por lo que el valor se establece como se muestra en el web.config a continuación:


Fig 6. Archivo web.config para la implementación en IIS


Para asignar el valor de la variable publishPath en el ejemplo 1.0 con la siguiente línea:

    string publishPath = ConfigurationSettings.AppSettings["publishPath"];
y para el ejemplo 2.0 se asigna con la siguiente línea:

    string publishPath = System.Configuration.ConfigurationManager.AppSettings["publishPath"];

Antes de ejecutar la página en Linux debemos habilitar con los permisos de escritura al directorio donde se guardaran los archivos, para hacerlo en Linux siga los siguientes pasos:

  1. El directorio donde se subiran los archivos debe tener los permisos de escritura para el grupo www.
  2. Si estamos como usuarios normales, cambiamos a una cuenta con privilegios de superusuario y establecemos y establecemos el grupo del directorio (en este ejemplo /home/martin/public_html/Downloads) como www con el siguiente comando:
                # chgrp www Downloads
            
  3. Ponemos permisos de escritura para el grupo con el siguiente comando:
                # chmod 775 Downloads
            

Estos comandos se muestran a continuación en la siguiente imagen.

Fig 7. Comandos para establecer los permisos del directorio


Ahora configuramos la Web Application dentro del archivo httpd.conf del servidor Apache como se muestra en la siguiente imagen:

Fig 8. Configuración de la Web Application en Apache


Para consultar como crear una aplicación Web en Apache revisar el siguiente documento: ASP.NET con Mono

Al ejecutar la página ASP.NET desde FireFox en Linux se mostrará como en las siguientes imágenes:

Fig 9. Seleccionando el archivo para publicar desde Firefox en Linux


Fig 10. Publicando el archivo desde Firefox en Linux


De la misma manera a como se hizo en el ejemplo anterior, antes de ejecutar la página en Windows debemos de habilitar con los permisos necesarios el directorio del servidor donde vamos a guardar los documentos, en este ejemplo la ruta configurada como directorio de publicación es C:\inetpub\wwwroot\dowloads, por lo que debemos seguir los siguientes pasos:

  1. Hacer click derecho sobre el directorio, en la ventana Properties seleccionar al usuario IIS_IUSRS (el cuál es el usuario anónimo de IIS), presionar el botón “Edit” para abrir la ventana Permissions.
    Fig 11. Seleccionando los permisos para el usuario de IIS

  2. En la ventana de Permissions en la lista inferior Permissions for IIS_IUSRS seleccionar la casilla con el permiso Write
    Fig 12. Estableciendo los permisos de escritura

Creamos la Web Application de forma que se muestre en IIS 7.0 como en la siguiente imagen:

Fig 13. Vista de la web application en IIS Manager


Al ejecutar la página ASP.NET desde Internet Explorer se verá como en las siguientes imágenes:
Fig 14. Seleccionando el archivo desde IE en Windows


Fig 15. Publicando el archivo desde IE en Windows


Un error frecuente tanto para la implementación con HtmlInputFile y FileUpload, es tratar de subir un archivo que tenga un tamaño mayor al máximo permitido por la petición al servidor Web (Request)

Fig 16. Excepción al exceder el límite máximo de la petición.



Para solucionar este error solo hay que agregar la siguiente línea al archivo de configuración, donde definimos el tamaño máximo en Kb del archivo que necesitamos publicar. Por ejemplo en el siguiente web.config se definió un tamaño máximo aproximado a 5 mbs (5120 kb).
Fig 17. El archivo web config estableciendo el tamaño máximo del archivo a publicar.



Para más información sobre este error consultar este enlace: HttpException Maximum Request Length.


Descarga el proyecto con HtmlInputFile (Framework 1.1)


Descarga el proyecto con FileUpload (Framework 2.0)

Descarga el código fuente inline del ejemplo con HtmlInputFile (Framework 1.1)


Descarga el código fuente inline del ejemplo con FileUpload (Framework 2.0)

domingo, 9 de abril de 2017

Threading: Programa que muestra la creación y ejecución de subprocesos.

Todos los sistemas operativos modernos permiten el uso de la concurrencia para hacer varias operaciones de manera simultánea o en paralelo, una manera actual de realizar la concurrencia es con el concepto de threads (hilos).

Un thread es un proceso ligero o un subproceso que tiene un simple flujo de control secuencial, el programa principal siempre tiene un simple flujo de control.

Un programa en C# empieza en un único Thread creado automáticamente por el CLR y el sistema operativo. Los métodos que son comúnmente utilizados por los Threads son:

  • Start: Inicia la ejecución y el hilo pasa al estado Running.
  • Suspend: Interrumpe la ejecución, puede reanudarse la ejecución si se invoca al método Resume del hilo que está en estado suspendido.
  • Sleep: Se invoca con un argumento que recibe la cantidad de milisegundos que el thread que se encuentra en estado Running debe dormir. Al terminarse este tiempo el thread vuelve al estado running
  • Resume: Reanuda la ejecución de un Thread en estado suspendido y lo pasa al estado running.

Una vez que un thread termina, no puede ser reiniciado.

Para mostrar estos conceptos escribí un programa para demostrar las técnicas básicas de creación de subprocesos llamado SimpleThreadSample, este programa crea un par de subprocesos (threads) que correrán simultáneamente dentro del thread principal del programa.

Cada subproceso corre con una prioridad normal, imprimiendo un mensaje en la consola dentro de un ciclo, invocando al método Sleep para permanecer inactivo.

El primer subproceso tendrá una inactividad de 300 milisegundos y el segundo subproceso tendrá una inactividad de 600 milisegundos.

Fig 1. El código fuente del programa


El programa crea cada subproceso con la clase ThreadStart pasando como argumento para el primer subproceso el método PrintLog10 que imprime el logaritmo del numero 10 y para el segundo subproceso el método Squared que imprime el cuadrado. Una vez creados ambos subprocesos se invoca el método Start() de cada uno de ellos, para pasarlos al estado Running.

Fig 2 la salida del programa en ejecución


Al terminar la ejecución de cada uno de los subprocesos, imprime los milisegundos que tardo en ejecutarse.


Download el código fuente

martes, 4 de abril de 2017

Números del 41 al 50 de la revista española DotNetMania

Los números del 41 al 50 de la revista española dotnetmania en PDF, revista dedicada a los profesionales de la plataforma .NET .

  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.

Trabajando con caracteres: Programa que suma el total de caracteres en un archivo de texto.

Una de las características fundamentales de cualquier lenguaje de programación es el trabajo con caracteres, todo programa fuente se compone de una secuencia de caracteres que el compilador interpreta. Como ejemplo un programa que muestra el total de coincidencias de un carácter en un archivo de texto, utilizando los métodos más usuales para convertir cadenas en arreglos de caracteres y viceversa.

Fig 1. El código del programa.


Fig 2. El programa requiere un archivo de texto.


Fig 3. El resultado de la ejecución del programa.


Download el código fuente.

lunes, 3 de abril de 2017

Números del 31 al 40 de la revista española DotNetMania

Los números del 31 al 40 de la revista española dotnetmania en PDF, revista dedicada a los profesionales de la plataforma .NET.

  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.