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