C Sharp

-June 2013+
SMTWTFS
2627282930311
2345678
9101112131415
16171819202122
23242526272829
30123456
  • RSS
  • Add To My MSN
  • Add To Windows Live
  • Add To My Yahoo
  • Add To Google

Statistics

  • Entries (29)
  • Comments (55)

Programación paralela a través de tareas(Paralell Task) en .NET 

Posted by Gustavo Alzate Sandoval Monday, June 10, 2013 11:02:00 PM

En muchas ocasiones se nos presentan escenarios en los cuales debemos ejecutar procesos de forma paralela, debido a que de forma secuencial se vuelven muy lentos y bloquean al usuario por un tiempo considerable, uno de estos escenarios puede ser si en una aplicación de reservas de vuelos online, debemos buscar disponibilidad mediante web services tanto para la aerolínea A como para la aerolínea B, si lo ejecutamos de forma secuencial iniciamos el llamado a A, y cuando este termine iniciamos el llamado a B, esto tardaría un tiempo considerable, la mejor forma sería ejecutando los llamados al mismo tiempo, usando Multithreading o usando paralelismo, en nuestro ejemplo vamos a usar paralelismo ya que vamos a usar todos los núcleos de nuestro procesador.

Para tener conceptos claros acerca de la programación paralela, recomiendo leer mi artículo anterior "Introducción a la programación paralela"

http://eltavodev.blogspot.com/2013/05/introduccion-la-programacion-paralela.html

Ahora vamos a ver ejemplos de cómo usar paralelismo a través de tareas en .NET, crearemos la siguiente aplicación:

 
A lo largo del ejemplo vamos a usar tres métodos: TareaA(), TareaB, TareaC(), tarea A, tiene un tiempo de retardo para efectos del ejercicio:
 
private void TareaA()
{
      Thread.Sleep(2000);
      MessageBox.Show("Se ejecutó la tárea A");
}


En nuestro primer botón "Task", vamos a crear una tarea indicándole que debe ejecutar nuestro método TareaA, e iniciamos la tarea:

Task t = new Task(this.TareaA);
t.Start();


También podemos crear tareas que ejecuten múltiples instrucciones:

Task t = Task.Factory.StartNew(() =>
{
      this.TareaA();
      int resultado = 1 + 2;
});
this.TareaB();


También podemos tipar nuestras tareas:

Task<int> t = Task.Factory.StartNew(() =>
{
      return 1 + 2;
});
MessageBox.Show((t.Result + 1).ToString());


Si queremos especificar una secuencia de ejecución para nuestras tareas, lo podemos hacer mediante la instrucción ContinueWith:

Task.Factory.StartNew(() =>
{
      this.TareaA();
}).ContinueWith((t) => TareaB());


Y por último vamos ver como sincronizar el fin de ejecución de todas nuestras tareas, muy útil en caso de que necesitemos ejecutar algún proceso cuando terminen todas las tareas que tenemos ejecutándose en paralelo:

Task t = new Task(this.TareaA);
t.Start();
 
Task t2 = new Task(this.TareaB);
t2.Start();
 
Task t3 = new Task(this.TareaC);
t3.Start();
 
Task.WaitAll(new Task[] { t, t2, t3 });
 
MessageBox.Show("Se terminó la ejecución de todas las táreas");


Con esto damos por terminado nuestro artículo sobre programación paralela a través de tareas, espero les sea de gran utilidad, a continuación el link de descarga del código de ejemplo:

https://www.dropbox.com/s/gsjhi12w68r1wuq/EjemploPTask.rar

También puedes encontrar este artículo en mi blog:

http://eltavodev.blogspot.com/2013/06/programacion-paralela-traves-de-tareas.html


Saludos.

View User Profile for tavo

Usando todos los núcleos del procesador en tus consultas Linq to Objects mediante Plinq 

Posted by Gustavo Alzate Sandoval Sunday, May 26, 2013 10:15:00 PM
En este artículo vamos a ver como optimizar nuestras consultas linq to objects usando todos los núcleos de nuestro procesador a través de Plinq.
 
Para tener conceptos claros acerca de la programación paralela, recomiendo leer mi artículo anterior “Introducción a la programación paralela”
 
 

¿Qué es Plinq?

Parallel LINQ (PLINQ) es una implementación paralela de LINQ to Objects. PLINQ implementa el conjunto completo de operadores de consulta estándar de LINQ como métodos de extensión para el espacio de nombres T:System.Linq y tiene operadores adicionales para las operaciones paralelas.
 
Para entrar en materia vamos a ver ejemplos de consultas linq to objects y consultas Plinq y vamos a comparar el tiempo que tarda cada una, para eso implementaremos el siguiente formulario:

 
Para nuestras consultas vamos a declarar una enumeración de 1 a 10’000.000, un Stopwatch para medir el tiempo que tardan las consultas y vamos a crear un método que busque los números primos en el rango anterior con el fin de darle complejidad a las consultas para que tarden más tiempo para efectos de nuestro ejemplo.

        private bool esPRimo(int n)
        {
            if (n <= 1) return false;
            if ((n & 1) == 0)
            {
                if (n == 2) return true;
                else return false;
            }
            for (int i = 3; (i * i) <= n; i += 2)
            {
                if ((n % i) == 0) return false;
            }
            return n != 1;
        }
        IEnumerable<int> numeros = Enumerable.Range(1, 10000000);
        Stopwatch tiempo = new Stopwatch();
 
En el evento click de nuestro primer botón “Linq” vamos a copiar el siguiente fragmento de código para realizar la consulta a través de linq to objects y mostrar el tiempo transcurrido:

            tiempo.Restart();
            var con = numeros.Where(c => esPRimo(c));
            con.ToList();
            tiempo.Stop();
            this.lblTiempo.Text = string.Format("Tiempo transcurrido: {0}",  tiempo.ElapsedMilliseconds.ToString("n2"));

Esta consulta tarda 5.715 milisegundos, una diferencia considerable con la siguiente implementación en paralelo que tarda 2.909 milisegundos

            tiempo.Restart();
            var con = numeros.AsParallel().Where(c => esPRimo(c));
            con.ToList();
            tiempo.Stop();
            this.lblTiempo.Text = string.Format("Tiempo transcurrido: {0}", tiempo.ElapsedMilliseconds.ToString("n2"));

Nótese que solo tuvimos que usar la extensión AsParallel para usar los demás cores del procesador, observemos el comportamiento de nuestro procesador con el administrador de tareas:

Imagen de consulta linq to objects:


 
Imagen de consulta Plinq:
 
 
Podemos observar como en la consulta de linq to objects se dispara el uso de un solo núcleo del procesador, mientras que en la consulta Plinq se dispara el uso de todos los núcleos, he ahí la gran diferencia en tiempo.
 
Algo a tener en cuenta es que nuestra consulta Plinq no devolverá los resultados en orden, ya que no procesa de forma secuencial, en caso de que necesitemos obtener en orden los números como es el caso de nuestro ejemplo solo basta con hacer uso de la extensión AsOrdered, como se muestra a continuación:

var con = numeros.AsParallel().AsOrdered().Where(c => esPRimo(c));

Obviamente eso hace que tarde un poco más nuestra consulta pero no es mucho, solo aproximadamente un milisegundo.

Para terminar nuestro ejemplo hay un aspecto que es importante resaltar y es la especificación del grado de paralelismo que deseamos utilizar en nuestras consultas y lo logramos con la extensión WithDegreeOfParallelism(Environment.ProcessorCount / 2) y especificamos el número de núcleos que queremos usar.

            tiempo.Restart();
            var con = numeros.AsParallel().WithDegreeOfParallelism(Environment.ProcessorCount / 2).Where(c => esPRimo(c));
            con.ToList();
            tiempo.Stop();
            this.lblTiempo.Text = string.Format("Tiempo transcurrido: {0}", tiempo.ElapsedMilliseconds.ToString("n2"));

En el ejemplo anterior usamos la mitad de los núcleos que tiene el procesador.

Con esto damos por terminado nuestro artículo sobre Plinq, espero les sea de gran utilidad, en un próximo artículo veremos otra forma de paralelismo en .NET como lo es el paralelismo mediante Tareas.

A continuación el link de descarga del ejemplo.

https://www.dropbox.com/s/ogk7skbwfmt5qcf/EjemploPlinq.rar
 
También puedes ver este artículo en mi blog:
View User Profile for tavo

Crud básico con Wcf Data Services, ajax y Jquery 

Posted by Gustavo Alzate Sandoval Tuesday, May 14, 2013 9:20:00 PM

En este artículo vamos a ver cómo implementar un CRUD básico a través de WCF Data Services, pero en esta ocasión lo vamos a hacer totalmente desde el lado del cliente, usando AJAX para invocar nuestros servicios de datos usando los verbos básicos de http GET, POST, PUT y DELETE, y usando el plugin jqxGrid de Jquery  en una versión no comercial, para mostrar los datos en una grilla, para esto vamos a seguir los siguientes pasos:

  1. Crear aplicación Asp.net
  2. Crear modelo de datos con Entity Framework
  3. Crear WCF Data Service
  4. Configurar WCF Data Service para acceso a nuestras entidades.
  5. Referenciar librerías para usar el jqxGrid.
  6. Crear llamados AJAX para interactuar con WCF Data Services.

Para los primeros cuatro pasos remitirse a mi anterior artículo:

http://eltavodev.blogspot.com/2013/04/crud-basico-con-wcf-data-services.html

5. Referenciar librerías para usar el jqxGrid.

Para usar el plugin jqxGrid, debemos referenciar las siguientes librerías y estilos:

<link rel="stylesheet" href="http://www.jqwidgets.com/jquery-widgets-demo/jqwidgets/styles/jqx.base.css"type="text/css" />
<script src="http://www.jqwidgets.com/jquery-widgets-demo/scripts/jquery-1.8.2.min.js" type="text/javascript"></script>
<script src="http://www.jqwidgets.com/jquery-widgets-demo/jqwidgets/jqx-all.js" type="text/javascript"></script>

6.   Crear llamados AJAX para interactuar con WCF Data Services.

En nuestro ejemplo vamos a crear un CRUD básico para la tabla Customers, visualmente es de la siguiente forma:

CrudAjax

Para cargar nuestro grid, vamos a incluir los siguientes scripts en el encabezado del HTML:

$(document).ready(function () {
 
            ConsultarClientes();
 
            $("#gridClientes").bind('rowselect'function (event) {
 
                $("#txtID").val(event.args.row.CustomerID);
                $("#txtNombre").val(event.args.row.ContactName);
                $("#txtCompania").val(event.args.row.CompanyName);
                $("#hfAccion").val("Modificar");
            });
 
            $('#gridClientes').on('rowdoubleclick'function (event) {
                if (confirm("Está seguro de eliminar el cliente: " + event.args.owner.rows.records[event.args.rowindex].bounddata.ContactName)) {
                    EliminarCliente(event.args.owner.rows.records[event.args.rowindex].bounddata.CustomerID);
                }
            });
 
        });


// Cargar grid con los clientes existentes
        function ConsultarClientes() {
            var source = {
                type: "GET",
                datatype: "json",
                datafields: [
                    { name: 'CustomerID' },
                    { name: 'ContactName' },
                    { name: 'CompanyName' }
                ],
                url: 'NorttwindAccess.svc/Customers',
                cache: false,
                root: 'data'
            };
 
            var dataAdapter = new $.jqx.dataAdapter(source, { contentType: 'application/json; charset=utf-8',
                downloadComplete: function (data, textStatus, jqXHR) {
                    return data.d;
                }
            }
            );
 
            $("#gridClientes").jqxGrid({
                source: dataAdapter,
                columns: [
                    { text: 'ID', dataField: 'CustomerID', width: 200 },
                    { text: 'Nombre', dataField: 'ContactName', width: 200 },
                    { text: 'Compañia', dataField: 'CompanyName', width: 180 }
                ]
            });
        }

Con el código anterior cuando carga la página invocamos la función ConsultarClientes(), la cual permite invocar el servicio de datos con la url 'NorttwindAccess.svc/Customers, y luego lo carga en el grid, además de esto adjuntamos dos eventos al grid, rowselect que usamos para cargar el cliente seleccionado en los campos de texto, y el evento rowdobleclick en el cual vamos a realizar la eliminación del cliente cuando se haga doble click sobre él.

Ahora para eliminar un cliente, agregamos la siguiente función:

// Eliminar un cliente
        function EliminarCliente(id) {
            $.ajax({
                type: "DELETE",
                url: "NorttwindAccess.svc/Customers('" + id + "')",
                data: "{}",
                contentType: "application/json; charset=utf-8",
                dataType: "json",
                success: function (data) {
                    alert("El cliente se eliminó correctamente.");
                },
                error: function (msg) {
                    alert(msg.responseText);
                }
            });
        }

Y para terminar agregamos la siguiente función para guardar y modificar un cliente: 

// guardar o modificar un cliente.
        function GuardarCliente() {
            var cliente = {
                CustomerID: $("#txtID").val(),
                ContactName: $("#txtNombre").val(),
                CompanyName: $("#txtCompania").val()
            };
            var verbo = "POST";
            var mensaje = "Cliente ingresado correctamente.";
            var URL = "NorttwindAccess.svc/Customers";
            if ($("#hfAccion").val() == "Modificar") {
                verbo = "PUT";
                mensaje = "Cliente modificado correctamente.";
                URL = "NorttwindAccess.svc/Customers('"+ $("#txtID").val() +"')";
            }
 
            $.ajax({
                type: verbo,
                url: URL,
                data: JSON.stringify(cliente),
                contentType: "application/json; charset=utf-8",
                dataType: "json",
                success: function (data) {
                    $("#hfAccion").val("Nuevo");
                    LimpiarCajas();
                    alert(mensaje);
                },
                error: function (msg) {
                    alert(msg.responseText);
                }
            });
        }

Con esto damos por terminado nuestro ejemplo de cómo implementar un CRUD básico usando WCF Data Services mediante llamados AJAX, es una forma sencilla de realizar una implementación sin usar código del lado del servidor, espero les sea de gran utilidad, a continuación el link de descarga del código fuente, para mayor detalle, la implementación está en el archivo PruebaClientes.aspx.

https://www.dropbox.com/s/v3wcbg7kh65ktrn/WCFDataServicesExample%20-%20copia.rar

También puedes encontrar este artículo en mi blog: http://eltavodev.blogspot.com/2013/04/crud-basico-con-wcf-data-services-ajax.html

Saludos. 

View User Profile for tavo

Crud básico con wcf data services 

Posted by Gustavo Alzate Sandoval Monday, May 06, 2013 10:37:00 PM

 

En este artículo vamos a ver cómo usar WCF Data Services para interactuar con nuestra base de datos mediante REST, para esto vamos a realizar un formulario de CRUD básico y seguiremos los siguientes pasos:

  1. Crear aplicación Asp.net
  2. Crear modelo de datos con Entity Framework
  3. Crear WCF Data Service
  4. Configurar WCF Data Service para acceso a nuestras entidades.
  5. Interactuar  con nuestro servicio desde una aplicación asp.net

 ¿Qué es WCF Data Services?

También conocido como ADO.NET data services, es un componente del .net Framework que permite crear servicios web usando ODATA (Open Data Protocol), para exponer y consumir datos en la web mediante REST, ODATA expone los datos como recursos que son accesibles y modificados a través de URIs, usando los verbos HTTP GET(Consultar), PUT(Modificar), POST(Ingresar) y DELETE(Eliminar).


Creando nuestro modelo de datos con la DB ejemplo Northwind.

Antes que nada para crear el modelo debemos tener la base de datos Northwind en nuestra instancia de SQl Server, dichas base de datos se adjunta en este artículo para que se sea descargada y restaurada. Una vez tengamos esta DB, en nuestro proyecto web hacemos click derecho, agregar un nuevo elemento y seleccionamos, ADO:NET Entity Data Model.

 Crear Acceso a datos

 Luego configuramos la conexión con la base de datos:

 Crear Acceso a datosII

 Y seleccionamos las tablas que necesitemos de nuestra base de datos.

 AccesoDatosIII

 Creando nuestro WCF Data Service.

Ahora que tenemos creado nuestro modelo de datos, procedemos a crear nuestro servicio de datos, para esto hacemos clic derecho, agregar nuevo elemento, y elegimos Servicio de datos WCF.

 CreateWCFDataService

 Enseguida nos crea nuestro Data service, y nos indica que debemos especificar el origen de datos y configurar los permisos para las entidades que vamos a exponer en el servicio.

public class WcfDataService1 : DataService/* TODO: escriba aquí el nombre de clase del origen de datos */ >

{

    // Se llama a este método una única vez para inicializar directivas aplicables a todo el ámbito del servicio.

    public static void InitializeService(DataServiceConfiguration config)

    {

         // TODO: establezca reglas para indicar qué operaciones de servicio y conjuntos de entidades son visibles, actualizables, etc.

         // Ejemplos:

         // config.SetEntitySetAccessRule("MiConjuntoDeEntidades", EntitySetRights.AllRead);

         // config.SetServiceOperationAccessRule("MiOperaciónDeServicio", ServiceOperationRights.All);

         config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;

    }

}

 

En nuestro caso el origen de datos es NorthwindEntities que hace referencia al modelo que creamos con entity Framework, y vamos a especificar permisos de crear, leer, actualizar y eliminar datos en la tabla Customers de nuestra DB, la configuración del servicio nos queda así:

public class NorttwindAccess : DataService<NorthwindEntities>{

        // Se llama a este método una única vez para inicializar directivas aplicables a todo el ámbito del servicio.

        public static void InitializeService(DataServiceConfiguration config){

          // TODO: establezca reglas para indicar qué operaciones de servicio y conjuntos de entidades son visibles, actualizables, etc.

           // Ejemplos:

           // config.SetEntitySetAccessRule("MiConjuntoDeEntidades", EntitySetRights.AllRead);

          // config.SetServiceOperationAccessRule("MiOperaciónDeServicio", ServiceOperationRights.All);

          config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;

           config.SetEntitySetAccessRule("Customers"EntitySetRights.All);

           config.UseVerboseErrors = true;

        }

}

 Cabe resaltar la configuración de UseVerboseErrors en True, esto para lograr obtener el detalle completo de la excepción desde el web services, en caso de que ocurra algún error.

Ahora tenemos configurado nuestro servicio de datos, lo podemos probar ingresando a la URL  http://localhost:1995/NorttwindAccess.svc donde NorttwindAccess es el nombre de nuestro servicio.

 

 testService

Nos muestra las tablas a la cuales otorgamos permisos, en este caso solo la tabla Customers.

También podemos hacer cualquier query a través de la URI de nuestro servicio, algunos ejemplos a continuación:

 

  • Seleccionar todos los registros de la tabla Customers:
  •  Seleccionar los registros donde el Campo CustomerID sea igual a “ALFKI”:
  • Seleccionar todos los registros de la tabla Customers ordenados por el campo ContactNAme:
  •  Seleccionar todos los registros de la tabla Customers donde el campo ContactName termine en “no”:

          http://localhost:1995/NorttwindAccess.svc/Customers?$filter=endswith(ContactName, 'no')

  • Seleccionar los campos CustomerID y ContactName de la tabla Customers:

 Estos son algunos ejemplos de los tantos que se pueden hacer.

 

Ahora procedemos a referenciar nuestro nuevo servicio de datos a nuestra aplicación web asp.net, para poder interactuar con él.

serviceReference 

Una vez tenemos nuestro servicio de datos referenciado podemos interactuar con el desde nuestra aplicación.

En nuestro ejemplo vamos a crear un CRUD básico para la tabla Customers, visualmente es de la siguiente forma:

CRUD

 
Para poblar el GridView con todos los Clientes, creamos el siguiente método el cual será invocado en el evento Load de nuestra página.

private void LlenarGrid(){

       var serv = new NorthwindService.NorthwindEntities(new Uri("http://localhost:1995/NorttwindAccess.svc"));

       var clientes = (from c in serv.Customers

                            orderby c.ContactName

                            select c).ToList();

       this.gvCustomers.DataSource = clientes;

       this.gvCustomers.DataBind();

}

 

Observemos que inicializamos nuestro modelo de datos a partir de nuestro servicios de datos, y sobre el podemos ejecutar cualquier consulta linq to entities, en este caso obtenemos  todos los registros de la tabla Customers y cargamos el GridView con los resultados.

 

Ahora para eliminar un registro de la tabla Customers, en el vento gvCustomers_RowDeleting de nuestro gridView asignamos el siguiente fragmento de código:

try{

       string strID = this.gvCustomers.Rows[e.RowIndex].Cells[0].Text;

       var serv = new NorthwindService.NorthwindEntities(new Uri("http://localhost:1995/NorttwindAccess.svc"));

       NorthwindService.Customers eliminarCliente = (from c in serv.Customers

                                                                            where c.CustomerID.Equals(strID)

                                                                            select c).Single();

       serv.DeleteObject(eliminarCliente);

    serv.SaveChanges();

    this.lblError.Text = "El cliente se elimino correctamente.";

    this.LlenarGrid();

}catch (Exception ex){

    this.lblError.Text = string.Format("Ocurrió un error al eliminar el cliete: {0}", ex.Message);

}

 

Para terminar con nuestro ejemplo, vamos a observar el código alojado en el evento click del botón guardar, en el cual se ejecutan las inserciones y actualizaciones a nuestra DB:

 try{

       var serv = new NorthwindService.NorthwindEntities(new Uri("http://localhost:1995/NorttwindAccess.svc"));

       if (this.hfAccion.Value.Equals("Nuevo")){

           NorthwindService.Customers customer = new NorthwindService.Customers{

                    CustomerID = this.txtID.Text,

                    ContactName = this.txtNombre.Text,

                    CompanyName = this.txtCompania.Text

           };

           serv.AddToCustomers(customer);

       }else{

            NorthwindService.Customers modificarCustomer =

            (from c in serv.Customers

             where c.CustomerID.Equals(this.txtID.Text)

             select c).Single();

             modificarCustomer.ContactName = this.txtNombre.Text;

             modificarCustomer.CompanyName = this.txtCompania.Text;

             serv.UpdateObject(modificarCustomer);

       }

       serv.SaveChanges();

    this.lblError.Text = "El cliente se actualizó correctamente.";

       this.hfAccion.Value = "Nuevo";

       this.txtID.Enabled = true;

       this.LlenarGrid();

}catch (Exception ex){

    this.lblError.Text = string.Format("Ocurrió un error al ingresar el cliete: {0}", ex.Message);

}

 

Con esto doy por terminado el artículo, espero que sea de gran utilidad para muchos, adicional el link de los fuentes de la solución y el .bak de la base de datos a continuación. En un próximo artículo estaré mostrando como consumir estos Data Services  mediante Jquery a través de una petición AJAX.

View User Profile for tavo

Enviar correo electrónico a una carpeta del sistema en C# 

Posted by Hernan Guzmán Monday, April 15, 2013 10:56:00 PM

Hay ocasiones en las que necesitamos probar partes de nuestro código que incluyen la funcionalidad de envío de correos electrónicos y no siempre se puede contar en los ambientes de desarrollo o pruebas con un servidor de correo SMTP. Una alternativa para probar nuestras funcionalidades en ese contexto, es almacenando los mensajes de correo en una carpeta específica del servidor.

Para hacer esto, es tan sencillo como agregar la siguiente sección en el archivo de configuración de la aplicación:

<system.net>
    <mailSettings>
        <smtp deliveryMethod="SpecifiedPickupDirectory">
            <specifiedPickupDirectory pickupDirectoryLocation="C:\TempMail" />
        </smtp>
    </mailSettings>
  </system.net>

Y podemos hacer la prueba agregando un código básico para generar un correo electrónico:

            using (SmtpClient client = new SmtpClient())
            {
                string from = "me@localhost.com";
                string to = "you@remote.com";
                string subject = "Sending to local directory";
                string body = "It works!";
 
                MailMessage message = new MailMessage(from, to, subject, body);
 
                client.Send(message);
            }

Luego de esto, podemos ir a buscar el mensaje en la carpeta específicada, y encontraremos el archivo del correo electrónico generado:

 

Para tener en cuenta:

  • La carpeta especificada en el web.config debe existir, ya que no es creada automáticamente.
  • Desde ASP.NET, el servidor IIS debe estar configurado para tener permisos de escritura en la carpeta especificada.

Espero que sea de utilidad!

@hernandgr

View User Profile for Hernan Guzmán

Creando un servicio WCF básico con JSON 

Posted by Hernan Guzmán Sunday, April 14, 2013 8:40:00 PM

En este tutorial, veremos cómo crear de forma sencilla un servicio WCF que haga uso de JSON.

El primer paso es crear una solución de código web en blanco en Visual Studio

 

Luego de esto, adicionamos un nuevo ítem, y seleccionamos en el tipo un Servicio WCF

 

Para comenzar a desarrollar el ejemplo, adicionaremos una clase Persona con unos datos básicos, de la siguiente forma:

using System.Runtime.Serialization;
 
namespace EjemploWcfJSon.Entidades
{
    [DataContract]
    public class Persona
    {
        [DataMember]
        public int IdPersona { getset; }
 
        [DataMember]
        public string Nombre { getset; }
 
        [DataMember]
        public string Direccion { getset; }
 
        [DataMember]
        public string Edad { getset; }
    }
}

Es importante anotar que para un correcto funcionamiento en WCF, la clase debe llevar obligatoriamente el atributo DataContract y las propiedades el atributo DataMember.

Luego de esto, adicionamos en la interface del servicio la firma del método a implementar para el ejemplo, de la siguiente forma:

    [ServiceContract]
    public interface IPersona
    {
        [OperationContract]
        [WebGet(UriTemplate = "ConsultarPersonas", 
                RequestFormat = WebMessageFormat.Json, 
                ResponseFormat = WebMessageFormat.Json)]
        List<Entidades.Persona> ConsultarPersonas();
    }

En esta clase, resaltamos el uso del atributo WebGet, en el cual especificamos el formato que queremos utilizar en nuestro servicio, el cual es JSON en este caso.

Luego, lo que haremos es escribir el código del servicio que implementará la interface. En este, adicionamos un código para que retorne una colección de datos de ejemplo de la siguiente forma:

        public List<Entidades.Persona> ConsultarPersonas()
        {
            List<Entidades.Persona> personas = new List<Entidades.Persona>();
 
            personas.Add(new Entidades.Persona() { IdPersona = 1, Nombre = "Hernan", Direccion = "Carrera 50", Edad = "26" });
            personas.Add(new Entidades.Persona() { IdPersona = 1, Nombre = "Jose", Direccion = "Calle 70", Edad = "54" });
            personas.Add(new Entidades.Persona() { IdPersona = 1, Nombre = "Jaime", Direccion = "Carrera 7", Edad = "13" });
            personas.Add(new Entidades.Persona() { IdPersona = 1, Nombre = "Alejandro", Direccion = "Calle 30", Edad = "29" });
            personas.Add(new Entidades.Persona() { IdPersona = 1, Nombre = "Cesar", Direccion = "Carrera 10", Edad = "35" });
 
            return personas;
        }   

Finalmente, debemos adicionar una configuración al web.config para que nuestro servicio WCF tenga un endpoint configurado para funcionar con JSON. La modificación se hace agregando alguna configuración en los elementos <endpointBehaviors />, <bindings /> y <services />

El archivo web.config resultante se verá así:

<?xml version="1.0"?>
<configuration>
  <system.web>
    <compilation debug="true" targetFramework="4.5" />
    <httpRuntime targetFramework="4.5" />
  </system.web>
  <system.serviceModel>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true"
        multipleSiteBindingsEnabled="true" />    
    <behaviors>
      <serviceBehaviors>
        <behavior name="">
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="false" />
        </behavior>
      </serviceBehaviors>
      <endpointBehaviors>
        <behavior name="web">
          <webHttp/>
        </behavior>
      </endpointBehaviors>
    </behaviors>
    <bindings>
      <webHttpBinding>
        <binding name="webHttpBindingJson" crossDomainScriptAccessEnabled="true"/>
      </webHttpBinding>
    </bindings>    
    <services>
      <service name="EjemploWcfJson.Servicio.Persona" >
        <endpoint address="" binding="webHttpBinding" bindingConfiguration="webHttpBindingJson" contract="EjemploWcfJson.Servicio.IPersona" behaviorConfiguration="web"/>
      </service>
    </services>
  </system.serviceModel>
</configuration>

Una vez hecho esto, ya podemos ejecutar el servicio desde un navegador, y veremos la respuesta con los datos en formato JSON.

Si la prueba la hacemos en Internet Explorer, obtendremos un archivo para descarga, que podemos abrir con un editor de texto y veremos que contiene los mismos datos.

Espero que este ejemplo sea de utilidad. El código del mismo lo pueden encontrar en mi cuenta de GitHub.

@hernandgr

View User Profile for Hernan Guzmán

Manipular hojas de Excel usando la librería EPPlus 

Posted by Hernan Guzmán Saturday, April 06, 2013 4:51:00 PM

A continuación quiero hacer una breve introducción a una librería para realizar operaciones con hojas de Excel muy interesante que encontré, motivado por una necesidad específica que tenía en mi trabajo:

En internet se encuentra una gran variedad de componentes libres que permiten realizar fácilmente operaciones con hojas de Excel. Entre las ventajas que brindan estos componentes, la mayor es la de no depender de tener que instalar software adicional ni de hacer implementaciones complejas, ya que el objetivo de estos componentes es encapsular esa complejidad en métodos mas sencillos que permiten a los desarrolladores concentrarse realmente en lo que necesitan hacer y brindando mayor productividad.

Es así como llegué a encontrar la librería EPPlus en Codeplex. Dicha librería tiene buena reputación en diferentes fuentes que encontré en internet realizando mi investigación, y en Codeplex se puede corroborar que es un proyecto que ya lleva un buen tiempo, con varias versiones de por medio, buenas calificaciones y con más de 30.000 descargas hoy en día.

Entre las caracterí­sticas que permite manejar EPPlus, según su documentación, están:

  • Manejo de rangos
  • Aplicar estilos
  • Gráficos
  • Imágenes
  • Tablas
  • Protección
  • Encripctación
  • Tablas Pivot
  • Validación de datos
  • VBA

A continuación, un ejemplo de un "Hola mundo" con EPPlus:

        private void CreateExcel()
        {
            string rutaArchivo = @"D:\Documento.xlsx";
 
            using (ExcelPackage package = new ExcelPackage(new FileInfo(rutaArchivo)))
            {
                var worksheet = package.Workbook.Worksheets.Add("Contenido");
                worksheet.Cells["B1"].Value = "Hello world!";
                package.Save();
            }
        }

Este es sólo un mínimo ejemplo de lo que permite hacer esta librería. Los invito a visitar su página, donde pueden encontrar más documentación y ejemplos: http://epplus.codeplex.com/

View User Profile for Hernan Guzmán

Aplicaciones en .NET con SignalR 

Posted by Pavel Espitia Friday, December 14, 2012 7:56:00 AM

En la actualidad con la llegada de nuevas tecnologías como los WebSockets y los entornos de programación como Node.JS las aplicaciones en tiempo real, asíncronas, multi usuario y altamente escalables son una gran necesidad, sin embargo en cuanto a aplicaciones desarrolladas en tecnologías anteriores esto solo era posible en una pequeña parte y el proceso era largo y tedioso, hoy en día existen librerias como SignalR que permiten que nuestras aplicaciones en .NET cumplan estos requisitos mencionados anteriormente, sin mas veremos como crear una aplicación web para chatear usando SignalR y algo de magia !.

1. Iniciamos creando un nuevo proyecto ASP.NET Empty Web Application y Framework 4.5

 

 
 


 2. En el proyecto añadimos un nuevo item, en este caso será una página HTML la cual llamaremos Index

 

 

 

 

 

 

 

 

 

3. Hacemos click derecho en el proyecto, buscamos el administrador de paquetes de NuGet y hacemos click en el

 

 

 

 

 

 

 

 

 

 

4. En este punto buscamos el paquete Microsoft.AspNet.SignalR algo importante a tener en cuenta es cambiar la opción donde dice Stable Only a Include Prerelease, seleccionamos el paquete y damos click en Install

 

 

 

 

 

 

 

 

 

 

Aceptamos la licencia en este punto

 

 

 

 

 

 

 

 

 

 

 

 

5. Cuando se completa la instalación del paquete ya vemos los archivos necesarios en la carpeta Scripts y mas referencias agregadas

 

 

 

 

 

 

 

 

 

 

 

 

 

 

6. En este punto vamos a crear una clase que herede de la clase Hub de SignalR, esta clase va a ser la encargada de la comunicación entre clientes y servidor.
Agregamos una clase llamada Chat, le añadimos un using a Microsoft.AspNet.SignalR.Hubs y hacemos que la clase herede de Hub.
Creamos un método con un parámetro, en nuestro caso el método se llama sendMessage y tiene un parámetro de tipo string llamado message, este método va a ser el encargado de distribuir el mensaje a todos los clientes.
En el método que creamos para distribuir el mensaje se va a usar la clase Clients de SignalR, de esta manera podemos distribuir el mensaje a todos los clientes, a un grupo en especifico o a varias opciones que trae por defecto, en nuestro caso el mensaje va a ser para todos los clientes entonces usamos Clients.All y al ser este un objeto de tipo dynamic de .NET podemos añadirle propiedades o métodos en tiempo de ejecución en vez de tiempo de ejecución (Mas información de dynamic http://bit.ly/Xh19z5 ), nuestro método se va a llamar AddMessage y recibe el parámetro message, cuando finalicemos nuestra clase debe verse de la siguiente forma:

 

 

 

 

 

 

 

 

 

Nota: el nombre del método por alguna razón que desconozco tiene que iniciar con minúscula, intenté varias veces llamándolo SendMessage y no funcionaba. (se agradece si alguien sabe porqué :P )


7. Ya teniendo la manera como el servidor va a transmitir la información o en nuestro caso un mensaje vamos a ver como trabajar con la parte del cliente para recibir y enviar mensajes.
En la página Index.html que creamos anteriormente añadimos un control input de tipo texto, otro input de tipo botón y una lista no ordenada (UL)

<input type="text" id="msg" value=" " />
<input type="button" id="send" value="send" />
<ul id="message"></ul>

después de esto añadimos añadimos una referencia a jQuery y a la libreria de javascript de SignalR, adicional agregamos una referencia a signalR/hubs que es donde nuestra aplicación crea un script según los hubs creados

<script src="Scripts/jquery-1.6.4.min.js"></script>
<script src="Scripts/jquery.signalR-1.0.0-alpha2.min.js"></script>
<script src="signalR/hubs"></script>

despues de esto añadimos el siguiente texto donde le decimos a SignalR como trabajar con el cliente

<script>
$(function () {
//Conexion con el ID de nuestr Hub (clase)
var chat = $.connection.chat;
/*Como va a manejar la ejecución del método AddMessage que creamos en nuestra clase Chat
se usa client para saber que se va a usar del lado del cliente (en la clase Chat
usamos Clients)*/
chat.client.AddMessage = function (message) {
$('#message').append('<li>' + message + '</li>');
};
/*Cuando se inicia la conexión y está lista para usarse (done) le decimos que en el click
del botón send ejecute el método SendMessage y su parámetro va a ser el valor
del campo de texto msg*/
$.connection.hub.start().done(function () {
$('#send').click(function () {
chat.server.sendMessage($('#msg').val());
});
});
});
</script>

Nuestra página html en estos momentos debe estar de la siguiente manera:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
</head>
<body>
<input type="text" id="msg" value=" " />
<input type="button" id="send" value="send" />
<ul id="message">
</ul>
<script src="Scripts/jquery-1.6.4.min.js"></script>
<script src="Scripts/jquery.signalR-1.0.0-alpha2.min.js"></script>
<script src="signalR/hubs"></script>
<script>
$(function () {
//Conexion con el ID de nuestr Hub (clase)
var chat = $.connection.chat;
/*Como va a manejar la ejecución del método AddMessage que creamos en nuestra clase Chat
se usa client para saber que se va a usar del lado del cliente (en la clase Chat
usamos Clients)*/
chat.client.AddMessage = function (message) {
$('#message').append('<li>' + message + '</li>');
};
/*Cuando se inicia la conexión y está lista para usarse (done) le decimos que en el click
del botón send ejecute el método SendMessage y su parámetro va a ser el valor
del campo de texto msg*/
$.connection.hub.start().done(function () {
$('#send').click(function () {
chat.server.sendMessage($('#msg').val());
});
});
});
</script>
</body>
</html>

En este punto ejecutamos la aplicación y podemos probar el envío de mensajes, para ver mejor la funcionalidad podemos abrir dos navegadores distintos y empezar a usar la aplicación.


Siguiendo el concepto de tiempo real del chat podemos empezar a pensar en muchas más aplicaciones que aprovechen al máximo esta característica.

Notas del post:
1. Al inicio se pueden enredar con algunas cosas como por ejemplo el nombre del método que debe iniciar en minúscula, pero es bastante fácil siguiendo este post.
2. La versión actual de SignalR es PreRelease por lo tanto puede que cambien muchas cosas que se muestran acá, este post se hizo con la versión 1.0.0-alpha2


Saludos !.

 

Post original en http://bit.ly/XhnOLI

View User Profile for Pavel Espitia

[Csharp] LINQ to Excel… Introducción. 

Posted by samuelarellanonet Wednesday, April 04, 2012 1:10:17 AM

 

Hola que tal, antes de profundizar en el tema de LINQ to Excel, considero necesario que veamos los términos respecto a LINQ. Languaje Integrated Query (LINQ) básicamente es un lenguaje de consultas nativas semejantes a SQL soportada por los lenguajes de la plataforma .NET.

LINQ nos proporciona los operadores de consulta estándar que nos va a permiri filtar, enumerar, etc. Su objetivo principal de LINQ es permitir que todo el código hecho en Visual Studio como pueden ser los datasets, XML u objetos de bases de datos que sean también orientados a objetos.

 

Para poder desarrollar nuestra aplicación de LINQ to Excel, primeramente debemos de descargar el SDK de la siguiente dirección: http://code.google.com/p/linqtoexcel/

 

Con el fin de ejemplificar el uso de LINQ to SQL, realizaremos un proyecto de consola dentro del entorno de desarrollo de Visual Studio (ya sea 2010 o 11 beta).

 

En este caso vamos a crear un documento de Microsoft Excel 2010 con la siguiente estructura.

 

image

Posteriormente será necesario crear una clase denominada Personas, la cual contendrá las propiedades (o bien el nombre de las columnas) de nuestro documento de Excel, tal como se mira en la siguiente codificación:

   1: namespace ConsoleApplication1
   2: {
   3:     public class Persona
   4:     {
   5:         public string Nombre { get; set; }
   6:         public string Apellidos { get; set; }
   7:     }
   8: }

 

Es necesario copiar el documento de Excel y darle la propiedad que deseamos una copia a la hora de compilar nuestro proyecto.

 

image

Las referencias de las Dlls que vamos a requerir son las siguientes:

  • LinqtoExcel.dll
  • Remotion.Data.Linq.dll

Posteriormente escribimos la siguiente sintaxis:

   1: using System;
   2: using System.Linq;
   3:  
   4: namespace ConsoleApplication1
   5: {
   6:     class Program
   7:     {
   8:         static void Main(string[] args)
   9:         {
  10:             //Nos permite obtener el directorio donde se encuentra nuestra aplicación, seguida del nombre del documento de Excel
  11:             var directorio = System.IO.Path.Combine(System.IO.Directory.GetCurrentDirectory(), "Ejemplo.xls");
  12:             //Utilizamos Linq to Excel y asignamos al QueryFactorio el directorio donde se encuentra nuestro documento de Excel
  13:             //para comenzar a utilizarlo.
  14:             var book = new LinqToExcel.ExcelQueryFactory(directorio);
  15:             //Realizamos un query para obtener todos los registros que se encuentran en la hoja de Excel
  16:             //Recuerde que la clase Persona contiene las propiedades (columnas) que se encuentran dentro del archivo de Excel
  17:             var qry = from x in book.Worksheet<Persona>()
  18:                       select x;
  19:             foreach(Persona p in qry)
  20:             {
  21:                 //Mandamos imprimir a consola el nombre y el apellido
  22:                 Console.WriteLine(p.Nombre + " " + p.Apellidos);
  23:             }
  24:             Console.ReadKey();
  25:         }
  26:     }
  27: }

 

Al ejecutar la aplicación verá lo siguiente:

image

Espero que haya quedado clara la explicación/

Cualquier duda o comentario es bien recibido.

Saludos.

 

Samuel Arellano

[C#-VS2010] Creando y consumiendo Snippets en VS2010 C# 

Posted by samuelarellanonet Friday, March 30, 2012 2:05:31 AM

Hola que tal, el objetivo de este post es dar a conocer el uso de los Snippets, así como incluirlos dentro del manejador o administrador de Snippets y posteriormente utilizarlos en nuestros proyectos de C#.

El uso de los Snippets toma su importancia debido a que son fragmentos de código reutilizables, ya que mediante ellos se encapsulan tareas que resultan ser reptitivas dentro del proceso de desarrollo de software. Si bien Visual Studio ya incluye sus propios Snippets con tareas definidas, también nos brinda la posibilidad a nosotros los desarrolladores de crear los propios.

cabe mencionar que en Visual Studio 2010 contamos con dos características principales para los Snippets:
• Expansión (el código se inserta en el cursor)
SurroundsWith (se coloca dentro del código existente)

En el siguiente videotutorial, te explico como hacer un Snippet sencillito y como poderlo consumir en un proyecto de consola.

Saludos

Samuel Arellano

Page 1 of 3 1 2 3 > >>
© 2009 - 2013 Avanet