lunes, 5 de mayo de 2008

WSE Parte II


No voy a perder tiempo en definirles que es WSE ya que nuestros amigos de microsoft ya tienen un sitio en donde explican este tema, por lo cual solo les pondré la url para que consulten que es WSE Ir a Explicación de WSE

Para poder utilizar WSE, lo primero que debemos hacer es descargarnos esta librería e instalarla en el servidor en el cual se ejecutarán los WebServices y en el PC en donde se desarrollará la aplicación, esta librería se la pueden descargar desde aquí

A continuación despliego la información del ejemplo:

MENSAJERÍA SOAP UTILIZANDO WSE

El presente ejercicio estará orientado a consumir desde un portal de Web Service una clase que contendrá un método que nos permitirá retornar la información que utilizaremos, para ello debemos crear tres proyectos de distinto índole, los cuales presentarán las siguientes características:

  • BILBIOTECA DE CLASE. El cual estará encargado de administrar las estructuras que se utilizarán, tanto en la aplicación de cliente como en la clase que residirá en el servicio Web. Adicionalmente se controlará el tipo de versión de cabecera SOAP que se utilizará en el enlace entre el cliente y el servidor Web.
  • WEB SERVICES. En esta aplicación residirá la clase que contendrá el método que se consumirá desde el cliente. Este portal de servicios Web no tendrá ningún servicio Web definido, solo contendrá la clase descrita.
  • CLIENTE DE CONSOLA. La cual utilizando la biblioteca de clase y la clase del Web Service, obtendrá los resultados deseados.

I - BILBIOTECA DE CLASE.

Para la creación del proyecto de solución con los proyectos antes descritos, se deben seguir los siguientes pasos:

1 - Crearemos un nuevo proyecto de bibliotecas de clases al cual llamaremos WseBase.

2 - Agregaremos las siguientes referencias a la solución.

  • Microsoft.Web.Service3
  • System.Configuration
  • System.Drawing
  • System.Security
  • System.Web
  • System.Web.Services
  • System.Windows.Forms.


3 - La clase que se crea por defecto la renombraremos de la siguiente forma Documents.cs

4 - Antes de realizar cualquier acción sobre esta clase, definiremos el uso de algunos espacios de nombres que se han referenciado o que se encuentran definidos por defecto en la aplicación, estos espacios de nombre deben ser:

using System;
using System.Xml.Serialization;


5 - Cambiaremos el nombre del espacio de nombre de la clase al siguiente Microsoft.Web.Services3.Usuario, quedando la definición del espacio de nombre de la siguiente forma:

namespace Microsoft.Web.Services3.Usuario
{
}


IMPORTANTE. Solo debe quedar definido el espacio de nombre y las definiciones de uso antes descritas en la clase creada.

6 - A continuación agregaremos las estructuras que se utilizarán dentro de la clase, estas serán:

USUARIO. Encargada de contener la estructura de definición de variables que se utilizarán en la ejecución del programa, tanto de asignación, como de despliegue de la misma.

[XmlRoot(Namespace="http://localhost/Wse")]
public class Usuario
{
public String usuario;
public String Nombre;
public String Apellido;
public double Sueldo;
}


USUARIOS. Estructura que contendrá una variable del tipo de la Clase Usuario variable.

public class Usuarios
{
[XmlElement("Usuario")]
public Usuario[] usuarios;
}

USUARIOREQUEST. Variable de tipo Usuarios, que será representada, cuando sea devuelta, en formato XML.

[XmlRoot(Namespace = "http://localhost/Wse")]
public class UsuarioRequest
{
[XmlArray("usuarios")]
[XmlArrayItem("Usuario")]
public String[] Usuarios;
}



7 - Como siguiente paso, agregaremos una nueva clase al proyecto de biblioteca de clase, la cual llamaremos AppBase. Dentro de esta clase definiremos el uso de algunos espacios de nombres que se han referenciado o que se encuentran definidos por defecto en la aplicación, estos espacios de nombre son:

using System;
using System.Collections;
using System.Configuration;
using System.Text;
using System.Net;
using System.IO;
using System.Web.Services.Protocols;
using System.Security.Cryptography.X509Certificates;
using Microsoft.Web.Services3;
using Microsoft.Web.Services3.Configuration;
using Microsoft.Web.Services3.Security;
using Microsoft.Web.Services3.Security.Tokens;
using Microsoft.Web.Services3.Security.X509;



8 - Cambiaremos el nombre del espacio de nombre de la clase al siguiente Microsoft.Web.Services3.Usuario, quedando la definición del espacio de nombre de la siguiente forma:

namespace Microsoft.Web.Services3.Usuario
{

}


IMPORTANTE. Solo debe quedar definido el espacio de nombre y las definiciones de uso antes descritas en la clase creada.

9 - Dentro del estacio de nombre agregaremos la definición de la clase AppBase de la siguiente forma:

public class AppBase
{
}

10 - Dentro del espacio de nombre de la clase recién creada, agregaremos la siguiente definición de variable de ambiente de clase:

SoapProtocolVersion _soapVersion = SoapProtocolVersion.Default;

11 - Agregaremos, a continuación (dentro del espacio de la clase), la siguiente propiedad.

protected SoapProtocolVersion SoapVersion
{
get
{
return _soapVersion;
}
}

12 - Por último agregaremos el siguiente constructor de la clase:

// define el tipo de versión de soap que se utilizará en la llamada
public AppBase() {
string soapVersion = System.Configuration.ConfigurationManager.AppSettings["soapversion"];
switch (soapVersion)
{
case "soap11":
_soapVersion = SoapProtocolVersion.Soap11;
break;
case "soap12":
_soapVersion = SoapProtocolVersion.Soap12;
break;
default:
case "default":
_soapVersion = SoapProtocolVersion.Default;
break;
}
}

II - CREACION DE WEBSERVICE



El siguiente paso será crear el proyecto de Web Service, para ello seguiremos los siguientes pasos.

1 - Agregaremos un proyecto de Web de tipo Servicio Web a la solución, al cual llamaremos Wse. Como característica especial, definiremos que este proyecto de Web será creado en el directorio virtual de IIS, con la siguiente definición http://localhost/Wse

2 - El siguiente paso será eliminar, tanto el servicios web como su clase de componente de código asociado.

3 - A continuación agregaremos una clase a la solución que llamaremos UsuarioServicio.cs, debemos aceptar la opción que permite crear la clase para que quede disponible en el proyecto.

4 - Agregaremos las siguientes referencias al proyecto:

  • Microsoft.Web.Service3
  • WseBase
  • System.Configuration.Install
  • System.Design
  • System.Security
  • System.Windows.Form


5 - Abriremos la clase en el editor de código fuente y agregaremos las siguientes instancias de uso de espacios de nombre:

using System;
using System.Collections;

using Microsoft.Web.Services3;
using Microsoft.Web.Services3.Messaging;

using Microsoft.Web.Services3.Usuario;


NOTA: Debemos recordar que la instancia a Microsoft.Web.Service3.Usuario, está asociada a la biblioteca de clase WinBase

6 - El siguiente paso es asegurarnos que el nombre del espacio de nombre es el siguiente

namespace UsuarioServicio
{

}

7 - Dentro del espacio de nombre definido crearemos la siguiente clase:

[SoapService("http://localhost/Ejercicio002")]
public class UsuarioConsulta : SoapService
{

}

IMPORTANTE. Se debe considerar que los mismos espacios de nombre de cabecera SOAP deben ser definidos en los métodos que invocarán a la clase desde el cliente

8 - Dentro de la clase definida agregaremos la siguiente función, la cual estará encargada de retornar el XML con la lista de usuarios consultados.

[SoapMethod("http://localhost/Ejercicio002/UsuarioRequest")]
public Usuarios funUsuarioConsultar(UsuarioRequest message)
{
ArrayList list = new ArrayList();
foreach (String valor in message.Usuarios)
{
Usuario usu = new Usuario();
usu.usuario = valor;

if (valor == "m.roa")
{
usu.Nombre = "Mario Antonio";
usu.Apellido = "Roa Vidal";
usu.Sueldo = 5000;
}
else
{
usu.Nombre = "Walter Borney";
usu.Apellido = "Roa Cleary";
usu.Sueldo = 6000;
}
list.Add(usu);
}

Usuarios usuarios = new Usuarios();
usuarios.usuarios = (Usuario[])list.ToArray(typeof(Usuario));
return usuarios;
}

IMPORTANTE. Se debe considerar que los mismos espacios de nombre de cabecera SOAP deben ser definidos en los métodos que invocarán a la clase desde el cliente

9 - A continuación, reemplazaremos las líneas de código del we.config, con las siguientes:

<?xml version="1.0"?>
<configuration>
<configSections>
<section name="microsoft.web.services3" type="Microsoft.Web.Services3.Configuration.WebServicesConfiguration, Microsoft.Web.Services3, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
</configSections>
<system.web>
<httpHandlers>
<add verb="*" path="StockService.ashx" type="UsuarioServicio.UsuarioConsulta"/>
</httpHandlers>
<webServices>
<soapExtensionImporterTypes>
<add type="Microsoft.Web.Services3.Description.WseExtensionImporter, Microsoft.Web.Services3, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
</soapExtensionImporterTypes>
<webServices>
<compilation debug="true">
<assemblies>
<add assembly="Microsoft.Web.Services3, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add assembly="System.Security, Version=2.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/>
<add assembly="System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
<add assembly="System.Configuration.Install, Version=2.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/>
<add assembly="System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/>
</assemblies>
<compilation>
</system.web>
<configuration>



Generamos el proyecto WebService de solución

III - CREACION DE CLIENTE DE CONSOLA



Como último paso debemos crear el cliente que consumirá la aplicación, este cliente será de tipo de consola y lo agregaremos a la solución, para ello se deben seguir los siguientes pasos:

1 - Agregar un proyecto Windows de consola a la aplicación, el cual llamaremos WseConsola.

El archivo por defecto que se crea lo renombraremos con el nombre MAIN.

2 - Agregaremos las siguientes referencias a la aplicación:

  • Microsoft.Web.Service3
  • WseBase
  • System
  • System.Data
  • System.Web
  • System.Web.Services
  • System.Xml


3 - Abriremos el Archivo Main.cs con el editor de código y agregaremos las siguientes referencias de uso a los espacios de nombre que se detallan a continuación:

using System;
using Microsoft.Web.Services3;
using Microsoft.Web.Services3.Addressing;
using Microsoft.Web.Services3.Messaging;
using Microsoft.Web.Services3.Usuario;


4 - Como siguiente paso, eliminaremos el espacio de nombre actual con todo lo creado y agregaremos el siguiente espacio de nombre:

namespace UsuarioClienteLlamada
{

}

5 - Dentro del espacio de nombre creado agregaremos la siguiente clase:

class UsuarioClienteLlamada : AppBase
{

}

6 - Dentro del espacio de clase, agregaremos el siguiente método de lectura

[MTAThread]
static void Main(string[] args) {
UsuarioClienteLlamada ucl = null;

try
{
ucl = new UsuarioClienteLlamada();

}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}

Console.WriteLine("");
Console.WriteLine("Presione [Enter] para continuar...");
Console.WriteLine("");
Console.ReadLine();
}

7 - Antes de continuar con la definición de código de esta clase, agregaremos a la solución una nueva clase con el siguiente nombre:

UsuarioCliente.cs

8 - Abriremos el Archivo UsuarioCliente.cs con el editor de código y agregaremos las siguientes referencias de uso a los espacios de nombre que se detallan a continuación:

using System;
using Microsoft.Web.Services3;
using Microsoft.Web.Services3.Messaging;
using Microsoft.Web.Services3.Usuario;

9 - A continuación definiremos el siguiente espacio de nombre:

namespace UsuarioClienteLlamada
{

}

10 - Dentro del espacio de nombre creado, definiremos la siguiente clase:

[SoapService("http://localhost/Ejercicio002")]
public class UsuarioCliente : SoapClient
{
public UsuarioCliente(Uri to) : base(to) { }

}


NOTA. Se debe observar que en la clase existe un constructor de clase que captura la URL que se entrega, esta URL estará asociada al WebService que se desea consumir.

IMPORTANTE. Se debe considerar que los mismos espacios de nombre de cabecera SOAP deben ser definidos en los métodos que invocarán a la clase desde el cliente

11 - El siguiente paso, será crear el método que llamará al método de la clase creada en el Web Service, esto se hará a continuación del constructor definido, definiendo las siguientes líneas de código:

[SoapMethod("http://localhost/Ejercicio002/UsuarioRequest")]
public Usuarios funUsuarioConsultar(UsuarioRequest message)
{
// se invoca el servicio utilizando mensajería de punto a punto
// (SoapServiceAttribute.TargetNamespace)
// y se define la función que se consumirá y que retorna las
// listas con los valores rescatados
return (Usuarios)base.SendRequestResponse("funUsuarioConsultar",
message).GetBodyObject(typeof(Usuarios),
SoapServiceAttribute.TargetNamespace);
}



IMPORTANTE. Se debe considerar que los mismos espacios de nombre de cabecera SOAP deben ser definidos en los métodos que invocarán a la clase desde el cliente

Guardamos el código creado y regresamos al archivo Main.cs

12 - Dentro del espacio de la clase UsuarioClienteLlamada, agregaremos el siguiente procedimiento que se encargará de realizar el consumo de la clase antes creada y de retornar la información:

public void prcConsumoEjecutar()
{

String[] symbols = { "m.roa", "w.roa" };
UsuarioRequest request = new UsuarioRequest();
request.Usuarios = symbols;

UsuarioCliente proxy = new UsuarioCliente(new Uri("http://" + System.Net.Dns.GetHostName() + "/Wse/StockService.ashx"));

Console.WriteLine("Llamando {0}", proxy.Destination.Address.Value);

Usuarios quotes = proxy.funUsuarioConsultar(request);

Console.WriteLine("La llamada al Web Service ha sido exitosa:");

foreach (Usuario quote in quotes.usuarios)
{
Console.WriteLine("");
Console.WriteLine("Usuario:\t\t" + quote.usuario);
Console.WriteLine("Nombre:\t\t\t" + quote.Nombre);
Console.WriteLine("Apellido:\t\t" + quote.Apellido);
Console.WriteLine("Sueldo:\t\t\t" + quote.Sueldo.ToString());
}
}

13 - Por ultimo dentro del bloque try definido en el Método Main de la aplicación agregaremos las siguientes líneas de código:

ucl = new UsuarioClienteLlamada();

ucl.prcConsumoEjecutar();



Quedando el bloque try de la siguiente forma:


try
{
ucl = new UsuarioClienteLlamada();
ucl.prcConsumoEjecutar();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}

Bueno amigos tienen todo, ahora si no les funciona es porque han picado algo mal.

No hay comentarios: