Problemas al Invocar un Web Service de .Net desde una página ASP Clasica

Aunque no sé si sea un escenario muy común, hay aplicaciones legacy escritas en ASP clásico que empiezan a integrarse con aplicaciones en .Net, bien sea como parte de un proceso paulatino de migración o como parte del proceso de agregar nuevas funcionalidades a la aplicación existente, en ambos escenarios una forma simple de integrar la aplicación ASP con la nueva aplicación .NET es exponer las nuevas funcionalidades de la aplicación .Net por medio de servicios web.

Aunque existe en La Red literatura respecto a la forma como debe hacerse esta invocación del Web Service desde la página web no todos los ejemplos apuntan a escenarios reales, el objetivo de este post es mostrar cómo debe realizarse esta integración para aplicaciones del mundo real.

1. El primer problema consisten en identificar cuáles son los tipos de datos que se van a transferir entre la aplicación ASP y la aplicación .NET, mi recomendación es pasar datos de tipos básicos del CRL, es decir, strings, longs, integers. Aunque es posible pasar objetos representados como XML para que después sean des-serializados por la aplicación .NET esto complica bastante el escenario e incluye nuevos elementos de error. (Nosotros transferimos solo strings y creamos los objetos en la aplicación .NET, para lo cual creamos los constructores adecuados)

2. El siguiente problema es identificar quien es el realmente el cliente del servicio, en la mayoría de los escenarios el cliente del servicio es código del lado del servidor, (el código que esta entre los tags es el código del servidor), también es posible que el cliente sea alguna de las funciones JavaScript de la página que se quiere invocar. (Este es el escenario que derivó en la existencia de AJAX Asynchronous JavaScript And XML). Por ahora nos enfocaremos en el escenario donde el código del lado del servidor es quien consume el web service.

3. Ahora debemos seleccionar la forma como se comunicará la aplicación asp con el servicio web, básicamente hay dos opciones, usar SOAP, o usar el parser de xml (HTTP Post) que contiene un objeto poco conocido llamado MSXML2.ServerXMLHTTP que puede ayudarnos a realizar estas llamadas. Básicamente es un tema de gusto, facilidad y conveniencia, sin embargo como es necesario tener instalado el Toolkit de SOAP para poder usar los objetos de SOAP desde ASP clásico y dicho componente se queda sin soporte a partir de Marzo 31 del 2008, entonces nosotros preferimos usar HTTP Post.

4. Bien lo siguiente es escribir el código del servicio web y modificar la página ASP para que lo consuma, lo del servicio web no lo vamos a profundizar, es una clase con la decoración WebService con algunos métodos decorados WebMethod, etc. un ejemplo sencillo puede ser algo como esto:


Imports System.Web.Services
Imports System.Web.Services.Protocols
Imports System.ComponentModel
<System.Web.Services.WebService(Namespace:="
http://MyNameSpace/services/MyProduct
> _
<System.Web.Services.WebServiceBinding(ConformsTo:=WsiProfiles.BasicProfile1_1)> _
<ToolboxItem(False)> _
Public Class WorkFlowServices
Inherits System.Web.Services.WebService
<WebMethod()> _
Public Function ServiceTest() As String
Return "En Ejecucion..."
End Function
<WebMethod()> _
Public Function MyMetodoconParametros(ByVal Client As String, ByVal UserID As Long, ByVal IDProcessCase As Long, _
ByVal Sequence As Long, ByVal EntryDataType As String, ByVal IDEntryData As String, ByVal EntryData As String) As Long
...hacer algo, retornar algo.
End Function
End Class

5. Ahora como consumir este Web Service desde la página ASP clásica, es algo como esto:


<%
Dim xmlhttp
Dim DataToSend
Dim postUrlpostUrl = "http://IPMyServer/Services/WorkFlowServices.asmx/MyMetodoconParametros"
DataToSend="Client=Tester&UserID=1&IDProcessCase=80&Sequence=0" & _&EntryDataType=TestWebService&IDEntryData=0&EntryData=1"
Response.write postURL
Response.write "<br>"
Set xmlhttp = server.Createobject("MSXML2.ServerXMLHTTP")
xmlhttp.Open "POST",postUrl,false
xmlhttp.setRequestHeader "Content-Type","application/x-www-form-urlencoded"
xmlhttp.send DataToSend
Response.Write(xmlhttp.responseText)
%>

Lo importante de este segmento de código, es la forma como se construye la invocación del método, la variable postURL tiene la dirección del servicio web así como el nombre del método que se va a invocar. Luego la variable DataToSend tiene la información de los valores que toman los diferentes parámetros que se van a pasar al método del web service (la recolección de estos parámetros depende del tipo de uso e interfaz que se tenga con los usuarios pero puede ser la recolección de una forma usando request.form o la recolección de los parámetros del QueryString que invocó la páginas ASP).

Otra cosa importante es la definición del encabezado en la linea xmlhttp.setRequestHeader “Content-Type”,”application/x-www-form-urlencoded” .

Listo, se invocó el web service, ahora el resultado puede recuperarse de una de estas propiedades: responseBody, responseStream, responseText, and responseXML., (nosotros usamos response.text que nos retorna todo el entity body como un stream)

Tips Súper Importantes:

• Cuando su cliente del servicio web sea el propio código ASP (“del lado del servidor”) se recomienda usar el objeto MSXML2.ServerXMLHTTP que ha sido diseñado y optimizado para comunicaciones entre servidores.
• El código anterior genera un error en la mayoría de los servicios web del framework 2.0, es un error del tipo “Request format is unrecognized for URL” o en español “Formato de solicitud no reconocido para la dirección URL” esto se debe a que los protocolos Get y Post están deshabilitados por omisión (default) en las aplicaciones del framework 2.0 para todas las peticiones de orígenes diferentes a Localhost. (Esa es la razón por la que la página de prueba de los servicios web como se ve desde otra maquina no tiene el formulario Test Service), por lo tanto para que efectivamente se realice la invocación hay que habilitar estos protocoles, eso se hace incluyendo las siguientes líneas en el archivo web.config del servicio web de .net.


<system.web>
<webServices>
<protocols>
<add name="HttpGet"/>
<add name="HttpPost"/>
</protocols>
</webServices>
(...)
</system.web>

En este artículo hay más información del comportamiento de los protocolos, aunque solo habla del framework 1.1. También ocurren con en el framework 2.0.

Espero que sea de utilidad

Juan Carlos Peláez
MCTS

Keywords: Web Services, ASP Clasic, .Net, Framework 2.0, VB, “Formato de Solicitud no reconocido”,

2 replies on “Problemas al Invocar un Web Service de .Net desde una página ASP Clasica”

  1. Tengo una rutina que genera un XML para enviar al servicio de la Agencia de Protección de datos. Los datos que me proporciona la Agencia son los siguientes:

    <<>> ¿Podrías proporcionarme una rutina en ASP clásico para el envío de la cadena XML?

    1. Hola Ulises, gracias por escribirme, la verdad esto lo escribí en 2007 y ya no tengo muy presente como podría hacerse el envío en la forma que mencionas usando XML, aunque creo que hacer una cadena con todo el XML teniendo en cuenta que no se supere el tamaño del Querystring sería una solución.

Comments are closed.