Índice de la sección dedicada a .NET (en el Guille) ASP.NET

Crear una clase para acceder a un Servicio Web

Sin usar una Referencia Web en Visual Studio .NET


Autor: Guillermo 'guille' Som
Fecha: 29/Mar/2004
Actualizado el 01/Abr/2004

Parnorama Box

En este artículo encontrarás los siguientes temas:
-Crear una clase utilizable en un proyecto a partir de un servicio Web.
-Usar la utilidad WSDL desde la línea de comandos para crear esa clase.
-Compilar la clase en una DLL para usarla en un proyecto.
-Crear una aplicación cliente que utiliza un servicio Web de dos formas:
--Usando la clase creada con WSDL.
--Usando la DLL generada a partir de dicha clase.

Tanto para Visual Basic .NET como para C#.


 

Introducción:

Para poder usar un Servicio Web XML desde una aplicación de .NET tenemos que indicarle a la aplicación dónde localizar dicho servicio Web.
Si estamos usando Visual Studio .NET para crear la aplicación cliente (la que se conectará con el servicio Web) lo que nos recomiendan es crear una referencia Web, (en este ejemplo te explico cómo crear una referencia Web).
Y esto está bien, vamos que es lo que habitualmente haremos; pero es posible que también te pueda interesar saber cómo poder acceder a ese servicio Web sin necesidad de crear dicha referencia Web, bien porque no quieras o bien porque no estés usando Visual Studio .NET. En esos casos podemos hacerlo manualmente, o casi; ya que utilizaremos una de las herramientas que se incluyen con el SDK de .NET Framework: WSDL.exe
Con la utilidad WSDL podemos crear una clase "proxy" que nos sirva de intermediario entre nuestra aplicación y el servicio Web.
Para usar esta herramienta simplemente escribiremos la dirección del servicio Web y, por defecto, se creará un fichero con el mismo nombre que el servicio Web y con la extensión .cs, ya que el código que contendrá será en C#. Por supuesto, si estamos usando Visual Basic .NET podemos indicarle a WSDL que el código lo genere en ese lenguaje.
Por ejemplo, si el servicio Web está en este link:
http://www.elguille.info/Net/WebServices/CelsiusFahrenheit.asmx

La línea de comandos que tendríamos que usar es:
WSDL http://www.elguille.info/Net/WebServices/CelsiusFahrenheit.asmx

El fichero generado (realmente es una clase) tiene toda la información necesaria para conectarse con el servicio Web, pero lo más importante es que esa clase la podemos agregar a un proyecto que quiera usar dicho servicio Web y tendremos todos las funciones expuestas por dicho servicio Web, de forma que podamos usarlas como si de cualquier clase se tratara, es decir, nos da igual que sea un servicio Web o una clase normal y corriente, a la hora de escribir el código no vamos a notar ningún cambio. Ese cambio lo podremos notar en tiempo de ejecución, particularmente si no tenemos conexión con Internet, ya que la clase generada por WSDL sólo nos permite "saber" qué funciones (métodos) tiene el servicio Web y cómo "llegar hasta él", pero no incluye ninguna funcionalidad, ya que esa funcionalidad reside en el servicio Web alojado en la dirección indicada de Internet.
Pero esto es un mal menor, por la sencilla razón de que si queremos usar un servicio Web siempre tendremos que tener una conexión al servidor que lo tiene alojado.

 

Un ejemplo práctico:

A continuación te voy a explicar lo que tendrás que hacer para crear una aplicación que utilice dicho servicio Web.

La aplicación cliente usará un formulario como el de esta figura:


Fig. 1. El formulario cliente del servicio Web


A continuación te mostraré todo el código necesario para crear tanto la aplicación en Visual Basic .NET como en C#, así como la forma de generar la clase que nos permitirá acceder al servicio Web.

 

Crear la clase y usarla en un cliente Windows Forms (paso a paso):

En estos pasos que te voy a indicar ahora habrá algunos que son genéricos tanto para Visual Basic .NET como para C# y otros en los que te indicaré el que corresponda a VB o a C#. Más adelante podrás ver el código completo tanto para un lenguaje como para el otro.

1.- Abre el Visual Studio .NET y crea una nueva aplicación de Windows (en VB o C#)
2.- Diseña el formulario para que tenga el aspecto mostrado en la figura anterior (Fig. 1).
Al botón con el texto "a º F" dale el nombre btnC2F, al otro botón lo llamas btnF2C.
A la caja de texto de arriba (la que muestra TextBox1) le cambias el nombre por: txtCelsius, a la otra caja de textos le das el nombre txtFahrenheit. Las dos etiquetas superiores las dejas con los nombres que tienen, ya que no la vamos a usar desde código, a la etiqueta grande, le cambias el nombre por lblInfo.
3.- En el explorador de soluciones pulsa con el botón derecho en Referencias y pulsa en "Agregar", tal como se muestra en la figura 2.


Fig. 2. Agregar referencia
 

4.- Del cuadro de diálogo selecciona esta referencia:
System.Web.Services
El aspecto de la lista de referencias debería ser como se muestra en la figura 3.


Fig. 3. Las referencias del proyecto
 

 

5.- Crea el fichero "proxy" usando la utilidad WSDL.
5.a.- Si el código es para C#, usa esta línea de comandos:
  WSDL http://www.elguille.info/Net/WebServices/CelsiusFahrenheit.asmx
5.b.- Si el código es para Visual Basic .NET, usa este otro:
  WSDL /l:VB http://www.elguille.info/Net/WebServices/CelsiusFahrenheit.asmx
Esta línea de comandos creará un fichero llamado Conversor.cs o Conversor.vb dependiendo de que hayas usado la línea de comandos 5.a ó 5.b respectivamente.
6.- Pulsa en el proyecto que se ha creado en Visual Studio .NET y pulsa con el botón derecho del ratón.
En el menú despegable selecciona Agregar y del submenú que se muestra, selecciona: Agregar elemento existente, tal como se muestra en la figura 4.


Fig. 4. Agregar un elemento existente

Examina en el sitio que has creado el fichero con WSDL para añadirlo al proyecto. Eso hará que tengas en el proyecto el fichero generado con WSDL, lo cual hará que la clase esté disponible para usarla en nuestro proyecto.
A partir de este momento, ya podemos usar la clase Conversor en nuestra aplicación.

7.- Vamos a añadir el código para cada uno de los dos botones, pulsando en btnC2F se convertirá de Centígrados a Fahrenheit, por tanto, haremos doble-click en el control para que se muestre el procedimiento de evento que interceptará la pulsación en dicho botón. Lo que haremos será convertir el contenido de la caja de textos (txtCelsius) en un valor doble, crearemos una nueva instancia de la clase Conversor, llamaremos al método CaF al que le pasaremos el valor que queremos convertir de Centígrados a Fahrenheit y el resultado lo asignaremos a la otra caja de textos (txtFahrenheit), debido a que el valor que devuelve la función es de tipo double, dicho valor tendremos que convertirlo a cadena, para poder asignarlo a la propiedad Text de la caja de textos.
Dependiendo de que estemos usando Visual Basic o C# escribiremos el siguiente código:

Para Visual Basic .NET:

Private Sub btnC2F_Click( _
                ByVal sender As System.Object, _
                ByVal e As System.EventArgs) Handles btnC2F.Click
    Dim conv As New Conversor
    Dim c As Double = Double.Parse(txtCelsius.Text)
    txtFahrenheit.Text = conv.CaF(c).ToString()
End Sub

 

Para C#:

private void btnC2F_Click(object sender, System.EventArgs e)
{
    Conversor conv = new Conversor();
    double c = double.Parse(txtCelsius.Text);
    txtFahrenheit.Text = conv.CaF(c).ToString();
}

 

8.- Ahora haremos lo mismo con el botón de convertir de grados Fahrenheit a Centígrados.
Pero el código a usar será algo diferente, un poco más enredoso, pero igualmente operativo. En esta ocasión vamos a poner todo el código en una sola línea, sin crear ninguna variable intermedia y dando un formato al valor devuelto, de forma que si el valor devuelto por la función tiene más de dos decimales, sólo se muestren dos.

El código para Visual Basic .NET es:

Private Sub btnF2C_Click( _
                ByVal sender As System.Object, _
                ByVal e As System.EventArgs) Handles btnF2C.Click

    txtCelsius.Text = New Conversor().FaC(Double.Parse(txtFahrenheit.Text)).ToString("0.##")
End Sub

 

El código para C# es:

private void btnF2C_Click(object sender, System.EventArgs e)
{
    txtCelsius.Text = new Conversor().FaC(double.Parse(txtFahrenheit.Text).ToString("0.##");
}

9.- Pero debemos tener presente que se puede producir un error al intentar convertir la temperatura.
Los posibles errores son:
a.- Que el usuario no introduzca un número, lo cual producirá una excepción al llamar al método Parse de la clase Double.
b.- Que se pierda la conexión o que el servidor tarde en responder, con lo cual también se producirá un error.
Por tanto, el código mostrado deberíamos incluirlo dentro de un bloque Try/Catch para que el programa no se detenga a causa del error.

Nota:
Este cambio lo puedes ir intentando por tu cuenta y comprobarlo después con el que te muestro un poco más abajo.

 

Resumiendo:

Creando una clase con la utilidad WSDL y añadiendo dicha clase a un proyecto, podemos acceder a un servicio Web de forma fácil y sin tantos quebraderos de cabeza.

 


Otra forma de hacer lo mismo (o casi):

También podemos conseguir el mismo resultado "aislando" la clase del proyecto, es decir, no añadiendo la clase al proyecto.
Para conseguirlo, puedes compilar en una DLL la clase generada con WSDL y la librería resultante añadirla como referencia al proyecto.

Esto nos permitiría recompilar la librería sin necesidad de tener que hacer lo mismo con la aplicación cliente. Después se distribuiría la nueva DLL (siempre que no tenga un nombre seguro y si es así, no deberíamos cambiar la versión de la librería para que siguiese siendo compatible) y todo seguiría funcionando al ciento por ciento.

Para crear la librería:

1.- Generamos la clase usando WSDL.
2.- Compilamos la librería usando el compilador de VB.NET o C# de la siguiente forma:

Para Visual Basic .NET:
vbc /t:library /out:Conversor.dll Conversor.vb /r:System.dll /r:System.Web.Services.dll /r:System.Xml.dll

Para C#:
csc /t:library /out:Conversor.dll Conversor.cs /r:System.Web.Services.dll /r:System.Xml.dll

Fíjate que al usar el compilador de C# no hace falta referenciar System.dll, sin embargo en VB sí es necesario.

3.- Añadimos una referencia de la DLL generada y ya tenemos la clase disponible para usar.

Otra de las ventajas de usar una DLL es que podemos crearla en VB o C# y usarla en un proyecto independientemente del lenguaje usado. Aunque esto no es ninguna novedad, ya que es así como funciona todo punto NET.
 

 

Y esto es todo.

Si quieres ver el código completo de la aplicación cliente, pulsa en estos enlaces:
Para Visual Basic .NET
Para Visual C#

 

Espero que haya quedado claro y que a partir de ahora sepas algo más sobre cómo usar un servicio Web desde una aplicación de .NET

Nos vemos.
Guillermo
Iniciado el 29 de marzo en Las Palmas de Gran Canaria y terminado el 1 de abril en Zamora.


Código para Visual Basic.NET (VB.NET)El código del cliente del servicio Web Conversor, para VB .NET:


Private Sub btnC2F_Click( _
                ByVal sender As System.Object, _
                ByVal e As System.EventArgs) Handles btnC2F.Click
    'Dim c As Double = Double.Parse(txtCelsius.Text)
    'Dim conv As New Conversor
    'txtFahrenheit.Text = conv.CaF(c).ToString()
    '
    lblInfo.Text = "Convirtiendo..."
    Try
        Dim c As Double = Double.Parse(txtCelsius.Text)
        Dim conv As New Conversor
        txtFahrenheit.Text = conv.CaF(c).ToString()
        lblInfo.Text = ""
    Catch ex As Exception
        lblInfo.Text = ex.Message
    End Try
End Sub

Private Sub btnF2C_Click( _
                ByVal sender As System.Object, _
                ByVal e As System.EventArgs) Handles btnF2C.Click
    'txtCelsius.Text = New Conversor().FaC(Double.Parse(txtFahrenheit.Text)).ToString("0.##")
    '
    lblInfo.Text = "Convirtiendo..."
    Try
        txtCelsius.Text = New Conversor().FaC(Double.Parse(txtFahrenheit.Text)).ToString("0.##")
        lblInfo.Text = ""
    Catch ex As Exception
        lblInfo.Text = ex.Message
    End Try
End Sub

 


Código para C Sharp (C#)El código del cliente del servicio Web Conversor, para VB .NET:


private void btnC2F_Click(object sender, System.EventArgs e)
{
    //Conversor conv = new Conversor();
    //double c = double.Parse(txtCelsius.Text);
    //txtFahrenheit.Text = conv.CaF(c).ToString();
    //
    lblInfo.Text = "Convirtiendo...";
    try
    {
        double c = double.Parse(txtCelsius.Text);
        Conversor conv = new Conversor();
        txtFahrenheit.Text = conv.CaF(c).ToString();
        lblInfo.Text = "";
    }
    catch(Exception ex)
    {
        lblInfo.Text = ex.Message;
    }
}

private void btnF2C_Click(object sender, System.EventArgs e)
{
    //txtCelsius.Text = new Conversor().FaC(double.Parse(txtFahrenheit.Text)).ToString("0.##");
    //
    lblInfo.Text = "Convirtiendo...";
    try
    {
        txtCelsius.Text = new Conversor().FaC(double.Parse(txtFahrenheit.Text)).ToString("0.##");
        lblInfo.Text = "";
    }
    catch(Exception ex)
    {
        lblInfo.Text = ex.Message;
    }
}

 


la Luna del Guille o... el Guille que está en la Luna... tanto monta...