v1.1
Fase previa:
Objetivo: Se decidió realizar este Servicio Web puesto que ofrecía un claro ejemplo de las posibilidades del .NET Framework y resultaba rápido de desarrollar, puesto que el tiempo y los recursos disponibles eran limitados.
Análisis de Requisitos del Sistema: Construir un Servicio Web y una pequeña aplicación que lo utilice, que consistirá en un Conversor de Monedas (a partir de una moneda origen, una moneda destino y una cantidad, dará el valor de la cantidad en la moneda origen cambiada a la moneda destino).
Especificación Funcional del Sistema:
Servicio Web (funciones):
Se trata de la aplicación web que consume el servicio. Hay múltiples maneras de presentar los datos devueltos por dicho servicio, pero creemos que la más intuitiva para el usuario (aunque no la más sencilla de desarrollar) sería la compuesta por un formulario con los siguientes controles.
El código del servicio web está separado en dos archivos. Cuando se llama al servicio web, estamos llamando al archivo euroconversor.asmx, donde hemos declarado en la directiva de página que usaremos la separación de código mediante code-behind. Así la lógica de la aplicación la tendremos en el archivo euroconversor.asmx.vb.
Aunque las prestaciones de SQL Server son mucho mayores, se eligió como motor de datos Access, ya que el primero lo ofrecen pocos servidores de hosting gratuito. Como se puede observar en el listado2, las dos funciones del servicio web son bastante sencillas.
En MostrarMonedas abrimos una conexión a la base de datos y volcamos la única tabla de la que está formada en la tabla "Monedas" de un dataset, la cual devolvemos a la aplicación que consume el servicio web.
En CambioMoneda leemos los parámetros que nos envían de la aplicación consumidora (moneda1, moneda2 y cantidad). Conectamos a la base de datos y ejecutamos dos consultas para obtener el valor de 1€ en cada una de las dos monedas. Entonces realizamos una sencilla operación matemática para obtener el cambio redondeado (lo más pequeño que podemos tener son céntimos de €) y devolvemos dicho cambio. Nótese que se ha declarado la función como String. Eso quiere decir que el resultado lo devolveremos como una cadena de texto.
listado1 euroconversor.asmx
<%@ WebService Language="vb" Codebehind="euroconversor.asmx.vb" Class="euroconversor.euroconversor" %>
listado2 euroconversor.asmx.vb
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' euroconversor.net v1.1 '
' por '
' Ignacio Martín ([email protected]) '
' Jon Calafel ([email protected]) '
' Copyright 2001. Todos los derechos reservados '
' '
' '
' NOTA: Este servicio ha sido diseñado bajo la beta2 de .NET Framework '
' No se garantiza que funcione correctamente en la versión final de '
' Microsoft .NET Framework '
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Imports System.Web.Services
Imports System.Data
Imports System.Data.OleDb
<WebService(Namespace:="http://localhost", Description:="Este servicio web ofrece conversion entre monedas de la UE. Para obtener un lista de las monedas de nuestra base de datos consulte la función <i>MostarMonedas</i><br><br>Para cualquier comentario o duda <a href=""mailto:[email protected]"">envíenos un e-amil<a><br><br>© Copyright Ignacio Martin/Jon Calafel 2001. Todos los derechos reservados.")> Public Class euroconversor
Inherits System.Web.Services.WebService
#Region " Web Services Designer Generated Code "
Public Sub New()
MyBase.New()
'This call is required by the Web Services Designer.
InitializeComponent()
'Add your own initialization code after the InitializeComponent() call
End Sub
'Required by the Web Services Designer
Private components As System.ComponentModel.Container
'NOTE: The following procedure is required by the Web Services Designer
'It can be modified using the Web Services Designer.
'Do not modify it using the code editor.
<System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
components = New System.ComponentModel.Container()
End Sub
Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
'CODEGEN: This procedure is required by the Web Services Designer
'Do not modify it using the code editor.
End Sub
#End Region
'=====================================================================
'==================Funcion CambioMoneda===============================
'=====================================================================
<WebMethod(Description:="Una llamada a la funcion CambioMoneda requiere tres parámetros(en este orden):<br>moneda1,la moneda que quiere cambiar<br>moneda2, la moneda al la que quiere cambiar<br>cantidad, el valor que quiere cambiar.<br>Nota:Los nombres de las distintas divisas purden estar tanto en mayúsculas como en minusculas, pero siempre respetando el nombre almacenado en nuestra base de datos. Para ello consulte <i>MostrarMonedas</i>")> Public Function CambioMoneda(ByVal moneda1 As System.String, ByVal moneda2 As System.String, ByVal cantidad As System.String) As System.String
Dim cambio As System.String
'comprobamos si es un valor numérico
If IsNumeric(cantidad) Then
Dim val1 As System.Double
Dim val2 As System.Double
Dim valeuros1 As System.Double
Dim valeuros2 As System.Double
'variable que nos dice si la moneda es admitida o no
Dim ok As System.Boolean
Dim strConexion As String
Dim miConexion As OleDbConnection
Dim miComando As OleDbDataAdapter
Dim miDS As New DataSet()
ok = True 'en principio todo es correcto. Luego haremos las comprobaciones
'pasamos a minusculas ( por si meten el valor en mayúsculas)
moneda1 = LCase(moneda1)
moneda2 = LCase(moneda2)
'Conectamos con la base de datos Microsoft Access
strConexion = "PROVIDER=MICROSOFT.JET.OLEDB.4.0;" & "DATA SOURCE=" & Server.MapPath("monedasdb.mdb")
miConexion = New OleDbConnection(strConexion)
miConexion.Open()
'y ejecutamos la cadena SQL correspondiente para la primera moneda
miComando = New OleDbDataAdapter("SELECT * FROM tblmonedas WHERE Moneda='" & moneda1 & "';", strConexion)
'Ejecutamos el DataSet y rellenamos los datos en una tabla
miComando.Fill(miDS, "mimoneda1")
'========hacemos lo mismo para la segunda moneda=========
miComando = New OleDbDataAdapter("SELECT * FROM tblmonedas WHERE Moneda='" & moneda2 & "';", strConexion)
miComando.Fill(miDS, "mimoneda2")
'========================================================
'cerramos la conexion (ya tenemos los datos en el DataSet)
'ahora ADO.NET trabaja con datos desconectados
miConexion.Close()
Dim row As DataRow
Dim intContador As System.Int16 'nos dira cuantos registros hay
intContador = 0
'========================================================
'para comprobar si tenemos registros
'(la moneda introducida esta en la base de datos)
'como mucho habra uno(no puede haber dos monedas con el mismo nombre)
For Each row In miDS.Tables("mimoneda1").Rows
intContador = intContador + 1
valeuros1 = miDS.Tables("mimoneda1").Rows(0).Item("ValorEuros") 'valor en euros de la primera moneda
Next
If intContador > 0 Then 'si la moneda es valida (habia un registro)
val1 = CDbl(cantidad) / valeuros1 'valor en euros de la cantidad introducida
Else
ok = False 'la moneda no esta en la base de datos
End If
'========================================================
intContador = 0
'===========lo mismo para la segunda moneda==============
For Each row In miDS.Tables("mimoneda2").Rows
intContador = intContador + 1
valeuros2 = miDS.Tables("mimoneda2").Rows(0).Item("ValorEuros") 'valor en euros de la segunda moneda
Next
If intContador > 0 Then
val2 = valeuros2 'valor en euros de la segunda moneda
Else
ok = False
End If
'========================================================
If ok Then 'si todas las comprobaciones han ido bien
'redondeamos
'(no tendrian sentido más decimales, ya que lo más pequeño son los céntimos)
cambio = CStr(System.Math.Round(val1 * val2, 2))
Else 'alguna de las monedas no estaba en la base de datos
cambio = "moneda no admitida"
End If
Else 'no han introducido un valor numérico
cambio = "debe introducir un valor numérico"
End If
'y ahi va el resultado!!!! quien consuma el servicio web que haga lo que quiera
Return cambio
End Function 'CambioMoneda
'====================================================================
'===============Funcion MostrarMonedas===============================
'====================================================================
<WebMethod(Description:="Una llamada a esta función devuelve las monedas registradas en nuestra base de datos y el valor de 1€ en dicha moneda")> Public Function MostrarMonedas() As System.Data.DataSet
Dim strConexion As String
Dim miConexion As OleDbConnection
Dim miComando As OleDbDataAdapter
Dim miDS As New DataSet()
'Conectamos con la base de datos Microsoft Access
strConexion = "PROVIDER=MICROSOFT.JET.OLEDB.4.0;" & "DATA SOURCE=" & Server.MapPath("monedasdb.mdb")
miConexion = New OleDbConnection(strConexion)
miConexion.Open()
'y ejecutamos la consulta SQL
miComando = New OleDbDataAdapter("SELECT Moneda,ValorEuros FROM tblmonedas;", strConexion)
miDS = New DataSet("Monedas")
'Ejecutamos el DataSet y rellenamos los datos en él
miComando.Fill(miDS, "Monedas")
miConexion.Close() ' cerramos la conexión (ya tenemos los datos en el DataSet)
'devolvemos el dataset, y quien consuma el servicio que lo manipule
Return miDS
End Function 'MostrarMonedas
'=================================================================
End Class
El cliente lo implementamos con dos listas desplegables, cuya fuente de datos es el dataset devuelto por la funcion del servicio web MostrarMonedas. Así el usuario podra elegir entre que monedas de las disponiibles cambiar. Para que el usuario pueeda introducir la cantidad que desea cambiar habilitamos un campo de texto, para mostrar el resultado un label y un boton para procesar la peticion en el servidor. Además declaramos que todos estos controles se ejecuten en el servidor. Así podemos manejarlos como si de un formulario de Visual basic se tratara (web controls).
A continuación están los listados que muestran el código de la aplicación cliente. Al igual que en el servicio web, la lógica de la aplicación se encuentra en un archivo separado.
listado3 eurocliente.aspx
<%@ Page Language="vb" AutoEventWireup="false" Codebehind="eurocliente.aspx.vb" Inherits="clienteeuroconversor.WebForm1"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<title></title>
<meta name="vs_showGrid" content="False">
<meta name="GENERATOR" content="Microsoft Visual Studio.NET 7.0">
<meta name="CODE_LANGUAGE" content="Visual Basic 7.0">
<meta name="vs_defaultClientScript" content="JavaScript">
<meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5">
</HEAD>
<body>
<form id="Form1" method="post" runat="server">
<p style="FONT-SIZE: 16pt; FONT-FAMILY: Arial, Tahoma, Georgia">
euroconversor cliente
</p>
<TABLE cellSpacing="0" cellPadding="3" border="0" style="BORDER-RIGHT: black 1px solid; BORDER-TOP: black 1px solid; FONT-SIZE: 12px; BORDER-LEFT: black 1px solid; BORDER-BOTTOM: black 1px solid; FONT-FAMILY: Tahoma, Arial, Georgia; BACKGROUND-COLOR: #ffffcc">
<TR>
<TD>
Convertir la cantidad de
</TD>
<TD>
<asp:TextBox id="txtCantidad" runat="server" Width="100px"></asp:TextBox>
</TD>
<TD align="right">
<asp:DropDownList id="drpMonedas1" runat="server"></asp:DropDownList>
</TD>
</TR>
<TR>
<TD align="right">
</TD>
<TD align="right">
a
</TD>
<TD>
<asp:DropDownList id="drpMonedas2" runat="server"></asp:DropDownList>
</TD>
</TR>
<TR>
<TD>
</TD>
<TD align="middle">
<asp:Button id="cmdConvertir" runat="server" ForeColor="Black" BorderColor="Black" BorderWidth="1px" BorderStyle="Solid" BackColor="SkyBlue" Text="Convertir"></asp:Button>
</TD>
<TD>
</TD>
</TR>
<TR>
<TD colSpan="3">
<asp:Label id="lblResultado"
runat="server" Font-Names="Arial" Font-Size="15px"></asp:Label>
</TD>
</TR>
</TABLE>
</form>
<P style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">
© Copyright 2001 Ignacio Martín / Ion Calafel
</P>
</body>
</HTML>
listado4 eurocliente.aspx.vb
Public Class WebForm1
Inherits System.Web.UI.Page
Protected WithEvents drpMonedas1 As System.Web.UI.WebControls.DropDownList
Protected WithEvents drpMonedas2 As System.Web.UI.WebControls.DropDownList
Protected WithEvents txtCantidad As System.Web.UI.WebControls.TextBox
Protected WithEvents lblResultado As System.Web.UI.WebControls.Label
Protected WithEvents cmdConvertir As System.Web.UI.WebControls.Button
#Region " Web Form Designer Generated Code "
'This call is required by the Web Form Designer.
<System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
End Sub
Private Sub Page_Init(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Init
'CODEGEN: This method call is required by the Web Form Designer
'Do not modify it using the code editor.
InitializeComponent()
End Sub
#End Region
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'si no han enviado el formulario cargamos las listas las monedas disponibles
If Not (Page.IsPostBack) Then
'damos un nombre más manejable al servicio
Dim mieuro As localhost.euroconversor = New localhost.euroconversor()
'guardamos los datos en un dataview para no tener que llamar dos veces al servicio
Dim dv As System.data.DataView
dv = mieuro.MostrarMonedas.Tables("Monedas").DefaultView
'establecemos el origen de datos de las listas desplegables
drpMonedas1.DataValueField = "Moneda"
drpMonedas1.DataSource = dv
drpMonedas1.DataBind()
drpMonedas2.DataValueField = "Moneda"
drpMonedas2.DataSource = dv
drpMonedas2.DataBind()
End If
End Sub
Private Sub cmdConvertir_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdConvertir.Click
Try
Dim resultado As String
Dim mieuro As localhost.euroconversor = New localhost.euroconversor()
resultado = mieuro.CambioMoneda(drpMonedas1.SelectedItem.Text, drpMonedas2.SelectedItem.Text, txtCantidad.Text)
If IsNumeric(resultado) Then
'El servicio ha devuelto el cambio correctmente
lblResultado.Text = "<b>Cambio:</b> " & resultado
Else
'el servicio ha devuelro un error
lblResultado.Text = resultado
End If
Catch ex As Exception
'lo ignoramos
End Try
End Sub
End Class
Clic aquí para bajar el código y la base de datos