WCF Guía Completa de Programación. CAP. II. Mi Primer servicio WCF

 

Introducción

Este en cualquier libro suele ser el típico ejemplo de “hola mundo”, sólo que en el caso de WCF creo que es bastante más divertido.

En el mejor de los casos para hacer una simple llamada vamos a tener que escribir un montón de código, esto que en un principio parece engorroso, a la larga cuando estemos construyendo aplicaciones complejas será una forma de poner orden a todo el mecanismo de desarrollo de aplicaciones distribuidas.

Componentes de una Aplicación WCF

Los que hayan trabajado con tecnologías antiguas basadas en COM o DCOM recordarán el duro camino de los CLSID para mantener las referencias entre clientes, servidores, servidores con servidores, etc.

la verdadera potencia de WCF es haber acumulado no sólo todas las tecnologías de aplicaciones distribuidas como Remoting, MSMQ, … Sino el haber utilizado el potencial de todo lo que se ha evolucionado en las arquitecturas internet B2B, SOAP…

Para estructurar una aplicación que exponga servicios y otra que los consuma, como veremos adelante es todo un mundo. De echo me atrevería a decir que el 70% de WCF es configuración o similar, mientras que el resto esta relacionado con el propio código.

En este capítulo no vamos a ver un ejemplo que sea el modelo a seguir para realizar una aplicación cliente o servidor WCF, pero si va a sentar las bases para entender todo lo que viene a continuación.

Por eso esta aplicación la escribiremos haciendo el menor número de líneas de código posibles y pasando por alto temas como poder extraer la configuración del código para llevarla a ficheros, ya que esto se verá más adelante.

WCF está totalmente relacionado con SOA, es más si no voy a a hacer una aplicación que necesite SOA debo plantearme si WCF es la solución. Estoy harto de ver proyectos donde la gente empieza a meter tecnologías a saco sin pensar si es lo correcto, sólo por estar a la última.

Debemos tener en cuenta que los principios de SOA son permitir el desarrollo de nuevos requerimientos de negocio sin tener que reconstruir toda la aplicación entera, así como poder tomar nuestros bloques de aplicación para construir bloques de procesos de negocio. Es decir que si alguien está pensando en utilizar WCF para cacharrear tecnológicamente lo debe pensar bien, puesto que el coste de horas de desarrollo es elevado y debe tener una contrapartida en el negocio que al final es quien contrata los sistemas.

Por otro lado el utilizar WCF en cierto modo nos abstraerá de tener que poseer determinados conocimientos como WSDL, etc. ya que WCF lo hará por nosotros.

Para definir WCF, hay que indicar que todo servicio está compuesto por al menos dos partes, el cliente y el servidor. El servidor expone los servicios y el cliente los consume, todo ello mediante el intercambio de mensajes.

Para que un cliente y un servidor se comuniquen es necesario establecer lo que se ha dado en llamar el ABC de WCF, que no es ni más ni menos que Address, Binding y Contract. O lo que es lo mismo.

  • Address: La dirección del servicio
  • Binding: El mecanismo de comunicación
  • Contract: Los servicios que se exponen.

Estas tres “cosas” juntas se denomina Endpoint que son los puntos de conexión entre cliente y servidor. Es decir un cliente envía y recibe la información a través de sus EndPoints, así como un servidor escucha y responde a través de sus EndPoints.

Unos ejemplos de estos tres elementos serían:

Address: http://servicios.acme.com:8001/serviciosuma

Binding:  BasicHTTPBinding

Contract: [OperationContract] int suma(int x,int y);

 

Construcción de un Sistema WCF Básico

Cómo he comentado anteriormente no se trata de hacer un servicio complejo con múltiples opciones de configuración, ficheros de configuración, distintos tipos de endpoints, etc. En este primer ejemplo se trata de probar unas mínimas piezas, ejecutar y decir “FUNCIONA!!” de tal forma que nos motive a seguir aprendiendo.

Otro tema a tener en cuenta es que los ejemplos que voy a poner en los distintos capítulos van a ser muy sencillos de entender, ya que lo importante no es averiguar que hace mi super ejemplo a nivel de negocio, sino entender la tecnología que se utiliza.

El Servidor

Pues para empezar lo primero que haremos será crear un Contrato, es decir construir algo que indique qué voy a exponer en mi servidor WCF.

Para ello crearemos un nuevo proyecto, lo haremos desde cero sin utilizar ninguna plantilla. Es el método que más me gusta, primero aprendemos por las bravas y luego wizards o similar, sino no hay quién entienda lo que se genera y como me enseño mi gran amigo Rido, cuando un wizard te genera algo que no entiendes, lo mejor es “quitarlo”. Qué Razón tienes Rido!!!

Un contrato de debe definir como una interface y en el proyecto debemos tener agregada la referencia a System.ServiceModel, que es el namespace que provee los objetos y atributos necesarios para construir servicios WCF.

image

Una vez agregada la referencia, podremos incluir la cláusula using Sytstem.ServiceModel en nuestro Proyecto.

En este primer proyecto, vamos a incluir una función muy sencilla en la que enviaremos  un par de enteros y la función nos devolverá la suma, resta, multiplicación o división, en función de lo que indiquemos. Es decir la típica calculadora.

Para ello definiremos primero el interface con los servicios que vamos a exponer.

[sourcecode language='csharp' ]
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
namespace IServicio
{
    [ServiceContract]
    public interface ICalculadora
    {
        [OperationContract]
        int sumar(int x, int y);

        [OperationContract]
        int restar(int x, int y);

        [OperationContract]
        int multiplicar(int x, int y);

        [OperationContract]
        decimal dividir(int x, int y);
    }
}
[/sourcecode]

En este código del interfaz, hemos de fijarnos en dos cosas.

El interfaz lleva el modificador [ServiceContract] que indica un nuevo grupo de operaciones o Contrato que estamos estableciendo.

También observamos como cada método lleva un modificador [OperationContract] que indica una Operación del Contrato que estamos estableciendo.

El Servicio

Una vez que hemos establecido nuestro Contrato hemos de implementar el servicio que desarrollará nuestro interfaz.

Lo haremos en un proyecto diferente que agregaremos a nuestra solución en el que implementaremos los cuatro OperationContract.

Este proyecto no presenta ninguna perculiaridad, salvo que agregamos como referencias el proyecto del interfaz y el espacio de nombres ServiceModel.

No se incluyen validaciones o similar por claridad del código, además de que el tratamiento de excepciones se verá más adelante.

El código completo del Servicio sería el siguiente:

[sourcecode language='csharp' ]
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
    
namespace Contratos
{
    public class Calculadora : ICalculadora
    {
      public  int sumar(int x, int y)
        {
            return x + y;
        }

      public  int restar(int x, int y)
        {
            return x - y;
        }


      public  int multiplicar(int x, int y)
        {
            return x * y;
        }


     public    decimal dividir(int x, int y)
        {
            return x / y;
        }
    }
}
[/sourcecode]

El Host

Para poder utilizar un servicio desarrollado mediante WCF será necesario alojarlo en un componente, existen varias posibilidades, tales como una aplicación de consola, un servidor IIS,…

Para nuestro primer ejemplo utilizaremos la aplicación consola y crearemos toda la configuración por código.

Para ello a nuestra solución agregaremos un nuevo proyecto de Consola.

Para poder  hostear el servicio WCF, hemos de indicar los siguientes elementos en nuestro código.

  1. ADDRESS. Definiremos la URL en la que expondremos el servicio y le asignaremos un nombre. En nuestro caso Calculadora
[sourcecode language='csharp' ]
Uri miurl = new Uri("http://localhost:8080/Calculadora");
[/sourcecode]
  1. BINDING. Especificaremos el protocolo de comunicación a nuestro servicio
[sourcecode language='csharp' ]
BasicHttpBinding elbinding = new BasicHttpBinding();
[/sourcecode]
  1. CONTRACT. Especificaremos el contrato de operaciones expuesto por nuestro servicio
[sourcecode language='csharp' ]
ServiceHost elhost = new ServiceHost(typeof(Calculadora), miurl);
[/sourcecode]

Después de estos tres pasos, del ya comentado ABC de WCF abriremos el Host mediante una instrucción Open e implementaremos un ReadLine sobre la consola para que no se nos cierre y se quede escuchando por la URL establecida.

 

[sourcecode language='csharp' ]
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using Contratos;



namespace HostServicio
{
    class Program
    {
        static void Main(string[] args)
        {
            Uri miurl = new Uri("http://localhost:8080/Calculadora");
            ServiceHost elhost = new ServiceHost(typeof(Calculadora), miurl);

            BasicHttpBinding elbinding = new BasicHttpBinding();
            elhost.AddServiceEndpoint(typeof(ICalculadora), elbinding, "");

            elhost.Open();

            try
            {
                Console.WriteLine("Servicio alojado en " + miurl.AbsoluteUri);
                Console.ReadLine();
            }
            finally
            {
                elhost.Close();
            }
        }
    }
}
[/sourcecode]

Tras haber creado el Host, el siguiente paso es arrancarlo, para ello haremos un Build de la solución y arrancaremos la aplicación de consola desde la carpeta BinDebug ejecutando como Administrador si estamos trabajando con Windows 7, Vista,….

image

También podemos abrir la consola “como administradores” y navegar hasta la carpeta para ejecutar el host a mano

image

En cualquiera de los casos nuestra aplicación quedará levantada indicandonos el mensaje que hemos introducido.

image

         Para verificar que nuestro servicio está expuesto desde el internet explorer introduciremos la URL que indicamos en el apartado Address del código de la aplicación HOST.

image

En esta imagen podemos observar quela aplicación servidor ha desplegado nuestro servicio pero que el Metadata esta deshabilitado actualmente, es decir, que las operaciones no están expuestas vía WSDL, esto se puede desactivar por configuración, pero en nuestro caso de momento lo vamos a hacer por código mediante la inclusión de las siguientes líneas:

[sourcecode language='csharp' ]
 ServiceMetadataBehavior metadatos = new ServiceMetadataBehavior();
            metadatos.HttpGetEnabled = true;
            elhost.Description.Behaviors.Add(metadatos); 
[/sourcecode]

Con las que indicamos que queremos mostrar el Metadata, es decir mostramos la información del interface Contrato mediante reflexión de los servicios que hayamos expuesto mediante el modificador [OperationContract]

Una vez incluidas estas líneas, si recompilamos y volvemos a introducir la url del servicio en el navegador, nos aparecerá una ventana que nos indica que mediante la herramienta svcutil podemos generar varios ficheros tales como el PROXY, necesario para nuestro cliente.

image

El código completo por lo tanto del Host sería el siguiente:

[sourcecode language='csharp' ]
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using Contratos;
using System.ServiceModel.Description;



namespace HostServicio
{
    class Program
    {
        static void Main(string[] args)
        {
            Uri miurl = new Uri("http://localhost:8080/Calculadora");
            ServiceHost elhost = new ServiceHost(typeof(Calculadora), miurl);

            BasicHttpBinding elbinding = new BasicHttpBinding();
            elhost.AddServiceEndpoint(typeof(ICalculadora), elbinding, "");

            ServiceMetadataBehavior metadatos = new ServiceMetadataBehavior();
            metadatos.HttpGetEnabled = true;
            elhost.Description.Behaviors.Add(metadatos); 

            elhost.Open();

            try
            {
                Console.WriteLine("Servicio alojado en " + miurl.AbsoluteUri);
                Console.ReadLine();
            }
            finally
            {
                elhost.Close();
            }
        }
    }
}
[/sourcecode]

El Cliente

El cliente que vamos a utilizar será una aplicación Winforms, muy sencilla en la incluiremos dos cajas de texto para los número x e y que está esperando nuestro servicio, además de unos botones para realizar las operaciones.

Para poder utilizar el cliente necesitamos el proxy, el cual generaremos mediante la utilidad svcutil como hemos indicado anteriormente. De momento añadiremos la clase proxy y más adelante en otros capítulos explicaremos en detalle el por qué del proxy.

Para ello arrancamos el símbolo del sistema que viene con el propio Visual Studio y ejecutamos el comando atacando a la URL en la que tenemos arrancado nuestro servicio mediante la consola.

image

Por su puesto la llamada la haremos desde la carpeta del cliente, así se nos generará en esta carpeta el proxy .cs que agregaremos al proyecto posteriormente.

image

image

Podemos ver que se ha generado el .cs con el proxy el cual incorporamos a nuestro proyecto cliente.

image

El proyecto Cliente es muy sencillo, se codificará sólo el método sumar y se dejará el resto en el código fuente para que quién se lo descargue pueda finalizar el ejemplo.

Para poder utilizar el servidor es necesario agregar las referencias a ServiceModel y utilizar la clase que nos ha generado la herramienta svcutil.

En el código del cliente cabe destacar:

La creación del Endpoint de Cliente

[sourcecode language='csharp' ]
 EndpointAddress ladireccion = 
                new EndpointAddress("http://localhost:8080/Calculadora");
            BasicHttpBinding elbinding = new BasicHttpBinding();
[/sourcecode]

La utilización del proxy

[sourcecode language='csharp' ]
 CalculadoraClient lacalculadora = 
                new CalculadoraClient(elbinding, ladireccion);
[/sourcecode]

La llamada al método sumar

[sourcecode language='csharp' ]
  MessageBox.Show("Resultado " +
                lacalculadora.sumar(int.Parse(txtX.Text), 
                int.Parse(txtY.Text)).ToString());
[/sourcecode]

El código completo del cliente sería:

[sourcecode language='csharp' ]
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.ServiceModel;

namespace Cliente
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void cmd_add_Click(object sender, EventArgs e)
        {
            EndpointAddress ladireccion = 
                new EndpointAddress("http://localhost:8080/Calculadora");
            BasicHttpBinding elbinding = new BasicHttpBinding();

            CalculadoraClient lacalculadora = 
                new CalculadoraClient(elbinding, ladireccion);

            MessageBox.Show("Resultado " +
                lacalculadora.sumar(int.Parse(txtX.Text), 
                int.Parse(txtY.Text)).ToString());

            
        }
    }
}
[/sourcecode]

Como podemos ver si ejecutamos nuestro servidor y nuestra consola, la llamada FUNCIONA!!!

 

image

Este es el primer paso, a partir de ahora en los siguientes capítulos se irá avanzando en configuración, contratos, seguridad, etc.

 

Código Completo.

El código completo de este primer capítulo lo podéis descargar desde aquí:

Capitulo1.zip

12 comentarios en “WCF Guía Completa de Programación. CAP. II. Mi Primer servicio WCF”

  1. Enhorabuena! estaba como loco buscando un ejemplo de WCF para entender ciertos conceptos como el endpoint y como exponer el servivio.
    Por favor, sigue escribiendo y danos más de tu sabiduría 😉
    Además te ha explicaco en un lenguaje llano que da gusto!
    Un saludo.

  2. Fantástico!

    Una explicación muy clara y sencilla, que arroja un poco de luz sobre cómo empezar a trabajar con WCF!

    Que gustito me ha dao completar el ejemplo!!

    quiero más!!

    🙂

    jejejejee

  3. Hola, muy bueno el ejemplo!!
    Solo una duda, cómo puedo poner que los parametros que solicito en el OperationContract son requeridos?
    Es que al usar la aplicacion de SoapUI y buscar mi servicio, me dice que los parametros son opcionales, ayudaaaa!!!

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *