lunes, 5 de mayo de 2008

WSE Parte I


Web Service Enhancements.

Antes de iniciarnos con WSE, debemos entender que es un web service, ya que WSE, como su nombre lo indica, trabaja sobre WebServices y realza o amplia los protocolos de transferencia y transmisión de datos, así como la seguridad entre un websrvice y una aplicación.

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í



WebService.


Un webservice en un servicio que una organización entrega a sus clientes a través de la web, ya sea en canales de Internet o de Intranet, para ser consumidos en aplicaciones web y/o aplicaciones Windows. Cuando hablo de aplicaciones Windows, me refiero a cualquier tipo de aplicación que se puede crear en plataforma Windows y que puede consumir web services.


Los web services contienen métodos que se llaman desde las aplicaciones que consumen estos web services, estos métodos son conocidos como métodos web y son definidos como cualquier otro método de una aplicación, con la salvedad de que estos llevan la etiqueta de firma que los define como métodos web (Web Method).


Bueno ahora debemos saber que un Web Method de un Web Service se pude consumir de dos forma: Sincrona o Asíncrona.

  • Cuando solicitamos directamente un método y la aplicación queda esperando respuesta (no permite seguir operando en la interfaz) estamos hablando de que estamos realizando una llamada sincrona.
  • Cuando solicitamos un método de forma asincrona, la aplicación permite que se realicen otras acciones en la interfaz hasta que el Web Method del Web Service responde a la aplicación.


Dependiendo del canal de transferencia y de la velocidad de respuesta del metodo web, es que utilizaremos uno u otro.

En esta primara parte veremos como ejecutar un Web Method de un Web Service de forma sincrona y asíncrona, luego cuando veamos el comportamiento del Web Services, veremos WSE, que permite otros tipos de forma de transferencia de datos.

Los casos de WSE que veremos en la segunda parte estarán orientados a SOAP y a Enrutamiento (esto es bueno cuando deseas enmascarar el web services original).


Ahora al web services simple con WSE.

El ejercicio que presento a continuación tiene incluída la librería de WSE, así que recomiendo que se descargen WSE 3.0 y lo instalen antes de seguir con el ejercicio:


Los ejercicios que vamos a hacer están rescatados de los ejemplos que vienen en WSE 3.0 que se instalan con la librería, pero como siempre, en esta ocación vienen explicados paso a paso:


1 - Antes de realizar cualquier acción para la creación del WebServices, crearemos el proyecto de cliente que consumirá el WS, esto nos permitirá agregar el proyecto WS a la carpeta de solución, el proyecto de Windows se llamará WseWinBasico. Luego crearemos una aplicación de web services que llamaremos WseWsvBasico, dentro de este proyecto, eliminaremos el servio web por defecto y agregaremos un Servicio llamado WseEjercicioUNO.


2 - Como siguiente paso realizaremos la instanciación a las dll que nos permitirán utilizar los Servicios de WSE:

Nos posicionaremos en el nodo raíz del proyecto y seleccionaremos con el botón derecho la opción Agregar Referencias, como se muestra a continuación.




Al abrirse la ventana que nos permitirá agregar las referencias, buscaremos las referencias a la librería Microsoft.Web.Service3, como se muestra en la siguiente imagen:



Presionar el botón aceptar, con esto se observará que se ha agregado la referencia a esta librería, viendo en las propiedades del proyecto de WebService.

3 - El siguiente paso será agregar la instanciación de la librería en el proyecto, para esto agregaremos la siguiente línea de código en la cabecera de directivas:

using Microsoft.Web.Services3;

4 - Adicionalmente, agregaremos una llamada de instanciación a la librería:

using System.Xml.Serialization;
using System.Collections.Generic;


Estas librería nos permitirán utilizar las opciones de generación de listas y la generación de archivos XML, tanto de llamadas a métodos como de respuestas de los mismos.

5 - Como siguiente paso, definiremos una estructura que nos permitirá retornar información al cliente que consuma el servicio. Esta estructura retornará valores de tio xml y se definirá de la siguiente forma:

[XmlRoot(Namespace = "http://wse/Ejemplo001")]
public class Usuario
{
public String Valor;
public String Apellido;
public String Nombre;
public double Sueldo;
public DateTime fecha;
}

Esta estructura será definida fuera del espacio de nombre de la definición del Web Service. Si no tenemos habilitada la instanciación a System.Xml.Serializacion y System.Collections.Generic no se podrá definir la estructura de retorno.

6 - El siguiente paso será construir el método que capturará la información que se envía desde el cliente, para ello definiremos las siguientes directrices que estarán asociadas al método:

[WebMethod]

Asociado a todos los métodos que se presentarán como disponibles dentro de un servicio web.

[SoapDocumentMethod(ResponseElementName = "Usuario")]

Al aplicar SoapDocumentMethod, a un método se especifica que los mensajes SOAP hacia y desde el método utilizan el formato Document.ResponseElementName obtiene o establece el elemento asociado a la respuesta SOAP de un método de servicios Web XML.

[return: XmlElement("Usuario")]

Define que el parámetro de retorno será enviado a través de SOAP.

7 - Definiremos el método de la siguiente forma:

public List UsuarioDatoSolicitud([XmlArray(IsNullable = true), XmlArrayItem("Valor", IsNullable = false)] string[] Valores)
{
}

Si se observa el método tiene una estructura de lista, como la que se ha definido.

8 - Dentro del método definiremos las siguientes líneas de código:

List<Usuario> usuarioDato = new List<Usuario>();

foreach (String valor in Valores)
{
Usuario usu = new Usuario();
usu.Valor = valor;
if (valor == "m.roa")
{
usu.Nombre = "Mario Antonio";
usu.Apellido = "Roa Vidal";
usu.Sueldo = 5.5;
}
else
{
usu.Nombre = "Walter Borney";
usu.Apellido = "Roa Cleary";
usu.Sueldo = 1.15;
}
usuarioDato.Add(usu);
}
return usuarioDato;



Con esto ya tenemos listo el Método Web del Web Service para ejecutarlo. Si ejecutamos el Web Service observaremos que nos solicitará definir el modo de depuración dl WebService, a lo cual diremos que si.



Se podrá observar que la aplicación Web, no solicita parámetros, aunque tenga definido parámetros de entrada, lo que permite ver son las solicitudes de llamada y las estructura de retorno del Metodo Web.



I - CONSUMO DEL SERVICIO WEB DESDE UNA APLICACIÓN WINDOWS SINCRONICAMENTE


Ya creado el servicio web, debemos realizar el consumo del mismo para ello crearemos una referencia web al webservices que llamaremos WseWsv, y luego crearemos en la aplicación windows una interfaz de tipo winforms, luego agregaremos tres botones, un list box, tres controles label y tres textbox, a la interfaz que hemos definido en nuestra aplicación Windows, quedando la internas de la siguiente forma:



Con esto definido, podremos seguir con los siguientes pasos:

1 - En el proyecto Windows , agregaremos la referencia a la librería Microsoft.Web.Service3

2 - Agregaremos una definición de uso de la referencia Web dentro del archivo de código del formulario, de la siguiente forma:

using WseWinBasico.WseWsv;

3 - Dentro del espacio de nombre de la solución de la aplicación agregaremos una referencia al servicio web que utilizaremos, como se muestra a continuación:

// definimos la variable de instancia
WseEjercicioUno wsvProxi;


4 - Adicionalmente definiremos una variable de tipo GUID que utilizaremos en la llamada asincrona que realizaremos en previos pasos de la siguiente forma:

Guid guid;

También debemos agregar una referencia al WebService que vamos a consumir.

5 - En el método que atiende el evento load del formulario definiremos las siguientes líneas de código:

//cargamos el listbox
this.lbxUsuario.Items.Add("m.roa");
this.lbxUsuario.Items.Add("w.roa");

// creamos la instancia
wsvProxi = new WseEjercicioUno();

// usar una guía para el objeto
// UserState en vez de cancelar la solicitud
guid = new Guid();

this.btnCerrar.Enabled = false;

6 - Por ultimo, en el método que atiende el evento clic del botón de llamada sincrónica, definiremos las siguientes líneas de código:

this.btnSincrono.Enabled = false;

String[] symbols = new String[1];
symbols.SetValue((string)this.lbxUsuario.SelectedItem, 0);

try
{
Usuario[] usuario = wsvProxi.UsuarioDatoSolicitud(symbols);
foreach (Usuario usu in usuario)
{
this.txtNombre.Text = usu.Nombre;
this.txtApellido.Text = usu.Apellido;
this.txtSueldo.Text = usu.Sueldo;
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
finally
{
this.btnSincrono.Enabled = true;
}


7 - Ejecutamos la solución y observaremos el comportamiento del Web Service Sincrónico



II - CONSUMO DEL SERVICIO WEB DESDE UNA APLICACIÓN WINDOWS ASINCRONICAMENTE


Los llamados asincrónicos de WebServices tienen un comportamiento similar los de Hilos, en donde se realiza la llamada a un web services y este responde en cuanto se termine la solicitud. Para definir una llamada a un Web Service de forma asincrónica se deben seguir los siguientes pasos:

1 - Antes de realizar cualquier acción sobre el método que atiende el evento clic del bot´n de llamada asincrónica, se debe crear el siguiente método:

// llamada asincrónica al evento
private void WsvProxyUsuario(object sender, UsuarioDatoSolicitudCompletedEventArgs e) {

}

2 - Dentro del método recién creado agregaremos las siguientes líneas de código:

//inicializamos los estados de los botones
this.btnAsincrono.Enabled = true;
this.btnSincrono.Enabled = true;
this.btnCerrar.Enabled = false;

if (e.Error != null)
{
// llamada fallida
MessageBox.Show("La llamada al Web Service a Fallado");
}
if (e.Cancelled)
{
// llamada cancelada
MessageBox.Show("La llamada al Web Service a sido Cancelada");
}
else
{
// conexión exitosa
Usuario[] usuario = e.Result;
foreach (Usuario usu in usuario)
{
this.txtNombre.Text = usu.Nombre;
this.txtApellido.Text = usu.Apellido;
this.txtSueldo.Text = usu.Sueldo.ToString();
}
}


3 - En el método que atiende el evento clic del botón de llamada asincrónica, agregaremos las siguientes líneas de código.

this.btnAsincrono.Enabled = false;
this.btnSincrono.Enabled = false;
this.btnCerrar.Enabled = true;
this.txtNombre.Text = "";
this.txtApellido.Text = "";
this.txtSueldo.Text = "";

// asignación de llamada al método asincrónico
wsvProxi.UsuarioDatoSolicitudCompleted
+= new UsuarioDatoSolicitudCompletedEventHandler(WsvProxyUsuario);

// asignación de variable de llamada al método asincrónico
String[] symbols = new String[1];
symbols.SetValue((string)this.lbxUsuario.SelectedItem, 0);

// llamada asincrona del método
wsvProxi.UsuarioDatoSolicitudAsync(symbols, guid);

4 - Por ultimo, si se observa, hemos definido una variable de tipo Guid, la cual nos permitirá controlar la llamada y cancelación de la consulta asincrónica, por lo cual, podremos definir en el método que atiende el botón cerrar llamada asincrónica la siguiente línea de código.

// se cancela la llamada asincrona
wsvProxi.CancelAsync(guid);



III - CONSUMO DE SERVICIOS WEB DE FORMA ASINCRONA EN APLICACIONES WEB



Para desarrollar una interfaz que consuma el método del servicio web definido, se deben seguir los siguientes pasos:

1 - Crearemos una interfaz que tenga la siguiente apariencia:






2 - En el proyecto, agregaremos la referencia a la librería Microsoft.Web.Service3

3 - Agregaremos una definición de uso de la referencia Web dentro del proyecto al servicio web de la siguiente forma:

using WseWinBasico.WseWsv;

4 - Dentro del espacio de nombre de la solución de la aplicación agregaremos una referencia al servicio web que utilizaremos, como se muestra a continuación:

// definimos la variable de instancia
WseEjercicioUno wsvProxi;


Adicionalmente definiremos una variable de tipo GUID que utilizaremos en la llamada asincrona que realizaremos en previos pasos de la siguiente forma:

Guid guid;

También debemos agregar una referencia al WebService que vamos a consumir.

5 - En el método que atiende el evento load del formulario definiremos las siguientes líneas de código:

//cargamos el listbox
this.lbxUsuario.Items.Add("m.roa");
this.lbxUsuario.Items.Add("w.roa");

// creamos la instancia
wsvProxi = new WseEjercicioUno();

// usar una guía para el objeto
// UserState en vez de cancelar la solicitud
guid = new Guid();

this.btnCerrar.Enabled = false;


6 - Antes de realizar cualquier acción sobre el método que atiende el evento clic del botón de llamada asincrónica, se debe crear el siguiente método:

// llamada asincrónica al evento
private void WsvProxyUsuario(object sender, UsuarioDatoSolicitudCompletedEventArgs e)
{


}


7 - Dentro del método recién creado agregaremos las siguientes líneas de código:

//inicializamos los estados de los botones
this.btnAsincrono.Enabled = true;
this.btnSincrono.Enabled = true;
this.btnCerrar.Enabled = false;

if (e.Error != null)
{
// llamada fallida
MessageBox.Show("La llamada al Web Service a Fallado");
}
if (e.Cancelled)
{
// llamada cancelada
MessageBox.Show("La llamada al Web Service a sido Cancelada");
}
else
{
// conexión exitosa
Usuario[] usuario = e.Result;
foreach (Usuario usu in usuario)
{
this.txtNombre.Text = usu.Nombre;
this.txtApellido.Text = usu.Apellido;
this.txtSueldo.Text = usu.Sueldo.ToString();
}
}



8 - En el método que atiende el evento clic del botón de llamada asincrónica, agregaremos las siguientes líneas de código.

this.btnAsincrono.Enabled = false;
this.btnSincrono.Enabled = false;
this.btnCerrar.Enabled = true;
this.txtNombre.Text = "";
this.txtApellido.Text = "";
this.txtSueldo.Text = "";

// asignación de llamada al método asincrónico
wsvProxi.UsuarioDatoSolicitudCompleted
+= new UsuarioDatoSolicitudCompletedEventHandler(WsvProxyUsuario);

// asignación de variable de llamada al método asincrónico
String[] symbols = new String[1];
symbols.SetValue(this.lbxUsuario.SelectedItem.ToString(), 0);

// llamada asincrona del método
wsvProxi.UsuarioDatoSolicitudAsync(symbols, guid);


9 - Por ultimo, si se observa, hemos definido una variable de tipo Guid, la cual nos permitirá controlar la llamada y cancelación del la consulta asincrónica, por lo cual, podremos definir en el método que atiende el botón cerrar llamada asincrónica la siguiente línea de código.

// se cancela la llamada asincrona
wsvProxi.CancelAsync(guid);


En la cabecera de definición del código HTML se debe agregar la autorización de ejecución de las llamadas asincronas, para ello se debe definir la siguiente línea de código:

Async="true"

Quedando la cabecera HTML de llamada al ensamblado de la siguiente forma:

<%@ Page Language="C#" AutoEventWireup="true"
Async="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>

No hay comentarios: