martes, 30 de diciembre de 2008

Cantidad de Visitas al Articulo:

Visual Studio 2005/2008 – Desarrollo Web

VS2008 Desde que comenzó el desarrollo de soluciones web, hace ya varios años, hubo siempre temas comunes en los sistemas que llevaban tiempo a los desarrolladores, y se repetían una y otra vez.

Visual Studio, desde su versión 2005 y heredada en 2008, ofrece una forma sencilla y potente de implementarlos sin necesidad de escribir demasiado código, y con la posibilidad de adaptarlos de acuerdo a cada necesidad.

Desde el punto de vista de los que nos dedicamos a desarrollo de productos, mas que a sistemas a medida, son características mas que importantes, en pos de la flexibilidad y productividad.

Los invito entonces, a esta introducción sobre los temas mas relevantes, basados en esas premisas.

Características Nuevas

Desarrollaré aquí una breve descripción de algunas nuevas características que permiten el desarrollo de soluciones web de forma fácil y rápida, dejando las puertas abiertas a adaptaciones y cambios de look and feel, sin demasiado esfuerzo.

Master Pages
Normalmente, los sitios mantienen una misma imagen en todas sus páginas, variando solamente en contenido y eventualmente las opciones de acceso dependiendo de los permisos por usuario. Esta características, en un principio, había que programarlas individualmente. VS2005 agregó el concepto de Página Principal o Master Pages. Las Master Pages definen una interfaz común para un grupo de páginas. Son en sí una página ASPX más, con extensión .master, y pueden ser referenciadas por las páginas del sitio, heredando de la master las características gráficas. La referencia se ve de la forma:”
<%@ Page Language=C# MasterPageFile=~/PaginaMaster.master ...

En estas páginas maestras, se definen espacios de información dinámicos, que permiten el cambio de contenido en las páginas finales, llamados ContentPlaceHolder.
Temas y Skins
Con las Master Pages solucionamos en parte el tema de la imagen uniforme para todas nuestras páginas del sitio, pero, si deseamos cambiar fácilmente esa interfase gráfica, todavía nos falta algo: Temas y Skins. Esta característica se basa en:
  • Hojas de estilo en cascada (Cascading Style-Sheets o CSS), las cuales pueden ser heredadas por las páginas ASPX al igual que un html, y permiten definir los estilos (colores, fuentes, etc.)
  • Creación de temas y máscaras (skin), a través de una carpeta llamada APP_themes, en la cual se pueden agregar uno o mas temas, donde básicamente se definen los estilos asociados a cada uno de los controles incluidos en las páginas, o bien a la página en general.
  • Asignación de los temas, ya sea a nivel página de la forma:
    <%@ Page Theme="TemaDefault" ... %>
    o a nivel sitio desde la configuración general del mismo en el archivo Web.Config, con la directiva:
    <?xml version="1.0"?>
    <configuration xmlns=
    http://schemas...>
    <system.web>
    <pages theme="TemaDefault"/>
    </system.web>
    </configuration>
Manejo de Sesiones
Si bien esta característica ya estaba desde las versiones anteriores de ASP, en esta versión se cambia algo pero sigue siendo análogo. Siendo HTTP un protocolo sin estado, ASP.NET guarda en la cabecera un ID único que el servidor envía al cliente en su primera petición. Este ID se mantiene dependiendo de que el cliente no cierre browser o del tiempo configurado en el servidor de duración de la misma.
Variables de Aplicación y Caché
En las versiones anteriores solo existían las variables de Aplicación para compartir ciertos datos entre todos los usuarios de una aplicación. Con un mecanismo de bloqueo para evitar errores. En esta versión se agrega el concepto de Caché, que permite incluir datos que son difíciles y costosos de conseguir (ejemplo: un query complejo en un dataset), incluso refrescándose solos cada cierto tiempo solos, para que cuando algún usuario lo necesite lo tome inmediatamente. Como siempre, dependerá de la lógica de negocios para saber si es factible utilizar esta característica o no. Para insertar un nuevo valor en el cache se puede hacer de la forma:
Cache("Clave") = Valor
o mejor aún:
Cache.Insert("MyData", datos, New CacheDependency(Server.MapPath("MyData.xml")))
Donde se define una dependencia del objeto en caché con el archivo MyData.xml. Si este cambia, entonces el objeto desaparece del Caché y se recarga la próxima vez que se use.
Existe además el Caché de Salida que permite definir que páginas se pueden guardar y por cuanto tiempo antes de regenerarse.
Autenticación y Autorización
La nueva versión permite definir en el archivo Web.Config, que tipo de autenticación tendrá el sitio y que accesos a páginas o subsitios tendrá cada usuario.
Además, surge el concepto de una nueva API: Membership y Roles, con la cual es muy fácil implementar (y extender) un sistema de administración de usuarios y roles, combinándolo con los Controles Web de Seguridad, que dan un look and feel básico para el ingreso de datos.

Conclusiones y Referencias Finales

Cuando se comienza a utilizar este tipo de características, uno no puede dejar de pensar en lo artesanal que era todo hace nada mas que un par de años. Por suerte las tecnologías avanzan, y permiten dejar las “iluminaciones creativas” para otro tipo de temas.

Existen en el sitio de MSDN de Microsoft, muchos tutoriales en español, que explican paso a paso estas y otras características de diversos productos, que son un excelente punto de partida en la utilización de los mismos. La invitación es entonces, a compartir cualquier duda o sugerencia.

So Far, So Good!

Leer más...
Cantidad de Visitas al Articulo:

Feliz Navidad y Muy Próspero Año 2009!!!

Solo quería terminar este 2008 deseando a través de este espacio los mejores augurios para el año que se viene.

Año 2008 que pasó rápido para mi, con muchos cambios y muchas lecciones aprendidas.

Definitivamente puedo decir que la balanza arroja saldo positivo, con el nacimiento de mi segundo hijo, el título de MBA de mi esposa, los nuevos desarrollos personales en otros ámbitos, etc..

Ojalá podamos seguir encontrándonos en este u otro espacio, y compartiendo ideas, siempre con la buena onda instaurada como base de la comunicación.

Feliz Año Nuevo!!

Que se cumplan todos nuestros deseos!!!

So Far, So Good!!

Imágenes by Flickr

Leer más...

lunes, 15 de diciembre de 2008

Cantidad de Visitas al Articulo:

Firma Digital en PDF

Firma_PDF Días atrás estuve probando las firmas digitales en PDF. Hacía buen tiempo que no trabajaba en temas relacionados con PKI, y me interesé en el tema debido a un artículo de un diario español, donde decían que un sistema de notificaciones a infractores de tránsito sería implementado con PDF firmado digitalmente.

Lo primero fue descargar las herramientas necesarias y luego, hacer un ejemplo básico con un certificado autogenerado. Aquí detallo la problemática, las herramientas utilizadas y los ejemplos desarrollados, para que sirva de punto de partida, si alguien necesita implementar algo del estilo.

Herramientas Utilizadas

Las herramientas que utilicé son:

Ejemplo

El proceso es el siguiente:

  1. Se genera con o lee un archivo PDF.
  2. Se carga un certificado digital en un formato PKCS12.
  3. Se genera un objeto de firma.
  4. Se lo inserta dentro del documento PDF original.

El código sería algo como:

import java.io.*;
import java.security.*;
import java.security.cert.Certificate;
import com.lowagie.text.*;
import com.lowagie.text.pdf.*;

public boolean sign(String pathpdf, String pathPKCS12, String passwordPKCS12) {
String fileKey = pathPKCS12 ;
String fileKeyPassword = passwordPKCS12 ;
try {
//Crea un KeyStore
KeyStore ks = KeyStore.getInstance("pkcs12");
//Carga Certificado
ks.load(new FileInputStream(fileKey), fileKeyPassword.toCharArray());
String alias = (String)ks.aliases().nextElement();
//Recupera Clave Privada
PrivateKey key = (PrivateKey)ks.getKey(alias, fileKeyPassword.toCharArray());
//Recupera Cadena de Certificacion si existe
Certificate[] chain = ks.getCertificateChain(alias);
//Lee Documento PDF y crea archivo de salida con otro nombre para no pisar el original
PdfReader pdfReader = new PdfReader((new File(pathpdf)).getAbsolutePath());

File outputFile = new File(pathpdf + ".signed.pdf");
// Crea la firma en el objeto PdfStamper de la librería iText
PdfStamper pdfStamper;
pdfStamper = PdfStamper.createSignature(pdfReader, null, '\0', outputFile);
PdfSignatureAppearance sap = pdfStamper.getSignatureAppearance();
sap.setCrypto(key, chain, null, PdfSignatureAppearance.SELF_SIGNED);
sap.setReason("Test GGS");
sap.setLocation("");
// Posiciona la Firma
sap.setVisibleSignature(new Rectangle(10, 10, 50, 30), 1, "sign_ggs");
pdfStamper.setFormFlattening(true);
pdfStamper.close();
}
catch (Exception key) {
key.printStackTrace();
return false;
}
return true;
}

Pendientes

Lo que quedaría pendiente, y si alguien lo completa les agradecería incluya un comentario es:

  1. Probar con versiones diferentes de JRE.
  2. Investigar en versiones anteriores de iText si ya estaba esta característica incluida.

So far, so good!

Imágenes by Tinypic

Leer más...

viernes, 28 de noviembre de 2008

Cantidad de Visitas al Articulo:

Applets - Ayudando el Deployment

Para complementar el artículo anterior acerca de JTwain, es que escribo este nuevo, incorporando varios tips importantes en el momento de poner en producción un applet, especialmente si éste debe tener acceso a ciertos recursos locales de la máquina cliente, o ejecutar acciones que requieran de permisos especiales.

También abordo temas como el empaquetado (en archivos JAR) con librerías externas, y un método fácil y rápido de testing y debug, utilizando la consola de Java standard.

Primero - Packaging (Empaquetado)

JAR Cuando terminamos de desarrollar un applet, y debemos empezar a probarlo dentro del contexto de la aplicación de negocios, se hace necesario empaquetarlo en un archivo JAR (no entraré en detalles de porqué, dado que hay mucha información al respecto). Lo que ocurre normalmente, es que en nuestro ambiente de desarrollo, el applet funciona perfectamente, pero cuando lo empaquetamos y lo colocamos en un sitio, comienzan los problemas. Uno de los errores mas comunes es que en el empaquetado nos olvidemos de hacer referencia a las librerías externas utilizadas en el desarrollo y que se necesitan en tiempo de runtime.

Para solucionar esto, y evitar que el JAR generado sea muy grande, se pueden colocar las librerías mencionadas (JAR de éstas) en una ubicación específica en el mismo sitio, y hacer referencia a ellas en nuestro applet a través del archivo MANIFEST.MF, incluyendo la ruta en la propiedad Class-Path. Por ejemplo el archivo quedaría:

Manifest-Version: 1.0
Main-Class: MiEspacioDeNombres.MiClase.class
Class-Path: lib_externa1.jar lib_externa2.jar lib_externa3.jar

Algunos detalles importantes son que la separación de los JAR debe ser con espacios, la lista NO debe ser en una sola línea si hay varios JAR (el largo de cada fila no debería superar los 80 caracteres, y cuando pasamos a la fila de abajo, debemos dejar un espacio inicial para que sea reconocida. Un ejemplo completo se puede descargar de aquí. En este ejemplo las librerías se deberían ubicar en el mismo directorio del JAR de nuestro applet.

Segundo - Permisos de Ejecución

Si el applet no accede a ningún recurso local de la máquina cliente donde ejecuta, no habrá problemas con los permisos de ejecución, de otra forma, es necesario agregar esos permisos en el archivo java.policy, ubicado en el directorio C:\Archivos de programa\Java\jre<version>\lib\security (obviamente si la distribución del sistema operativo es en inglés será C:\Programs Files). Allí se deben agregar los permisos necesarios de acuerdo a nuestras necesidades. En ésta página encontrarán detalles de suma utilidad para este tema. Por supuesto que una salida rápida es agregar permisos para todo de la forma:

permission java.security.AllPermission;

Esto soluciona rápidamente el problema de funcionamiento, pero abre la puerta a potenciales ataques malintencionados. Mi recomendación es que se tomen el trabajo de ir probando (si al menos no tienen claro que permisos necesitan) y habilitando solo lo necesario. Para este trabajo es útil el siguiente punto de testing y debug.

Tercero - Testing y Debug

Cuando desarrollamos un applet utilizamos una versión específica de Java. Otro problema común es que no sabemos cual es la versión instalada en la máquina cliente que lo ejecutará. Para evitar malos resultados, es necesario entonces probar el applet con diferentes versiones JVM.

Para esto es muy útil:

  1. Habilitar la consola de Java en tiempos de ejecución
  2. Ir cambiando la versión de java, con la que el navegador utilizado en las pruebas, ejecutará el applet.

Para lo primero se debe ingresar a Panel de Control > Java > Avanzado y habilitar la consola de la forma:

Consola

Para lo segundo, en Panel de Control > Java > Java, se habilita o deshabilita la versión que deseamos utilizar con el navegador, de la forma:
Consola_Ver

Nota: Es necesario cerrar el navegador cada prueba que hagamos para que no use caché.

Luego, cuando ejecutamos el applet desde el navegador, llamando a la página donde se encuentra, Java abre automáticamente la Consola y muestra allí cualquier excepción que se produzca, tanto por falta de permisos como por fallas del funcionamiento propio del applet (faltas de librerías externas, etc.).
Consola_Debug

So far, so good!

Images by Tinypic

Leer más...

viernes, 7 de noviembre de 2008

Cantidad de Visitas al Articulo:

Comparación de Navegadores

Logos Desde hace buen tiempo que vengo probando los 3 navegadores mas usados últimamente en Windows, o al menos los 3 mas nombrados: Internet Explorer - IE (Microsoft), Firefox (Mozilla) y Chrome (Google).

Como siempre ocurre, existen pro y contras en cada uno, y aquí enumeraré algunas de esas características, como ayuda para seleccionar uno de los 3, de acuerdo a cada necesidad.

Tabla comparativa

Esta tabla comparativa permite tener una idea rápida de los pro y contras de cada navegador:

CaracterísticaChrome Firefox IE
ok GráficaDiseño minimalista. Cambio algunos conceptos arraigados de otros navegadores.Permite personalizar el diseño gráfico a través de plantillas que se descargan del site.No permite cambios además de los colores básicos desde Windows.
okSoporte AppletSi - Pero solo versión de java versión 1.6.0_10-rc-b28 (mas adelante explico por que).Si - Desde versión 1.3 probé que funciona bien.Si - Desde versión 1.3 probé que funciona bien.
okSoporte ActiveXNoNoSi
okSoporte PDFSiSiSi
okSoporte FlashSiSiSi
okRapidez (de 1 a 10)978
okUsabilidad (de 1 a 10)7 (Cambió algunas convenciones ya establecidas por los demás navegadores)99
okLengüetasSiSiSi (pero desde versión 7 en adelante)
okRobustez (de 1 a 10)899
okEstabilidad (de 1 a 10)97Versión 6 - 9
Versión 7 - 7
Versión 8 - 6

El análisis podría seguir, con varios puntos mas, pero con estos desarrollados creo que se pueden sacar algunas conclusiones.

Temas Importantes

Un tema importante que agregó Chrome, es que cada lengüeta se ejecuta como un thread separado, lo que permite que si alguna de las lengüetas falla, no es necesario cerrar las demás, solo se cierra esa. Ese es el motivo por el cual fue desarrollado y permite ejecución de applets con la última versión de JRE (versión 1.6.0_10-rc-b28). Esta versión hace factible esta característica. De todas formas, "no todo lo que brilla es oro". Me pasó algunas veces que al fallar una lengüeta, igualmente tuve que cerrar todas las demás. Otro tema destacable es que es Open Source, por lo que puede ser descargado el código fuente para generar una versión de navegador personalizada.

Otro tema relevante de mencionar es el soporte de ActiveX. No se la causa, aunque se me ocurre que es netamente comercial (licenciamiento), por el que Firefox (Mozilla) o Chrome (Google) NO soportan ActiveX. La realidad indica que existen varias soluciones web que se basan en ActiveX, lo que hace que estos navegadores pierdan mercado con respecto al IE (Microsoft). Quizá alguien pueda comentarme cual es el motivo real de este tema.

Conclusiones

Si el objetivo del navegador es para acceso a webmail, lectura de diarios on line, búsqueda de información en general, Chrome es una buena opción, dado que es un navegador liviano, rápido, y con su diseño minimalista (y opciones reducidas también), hace la vida fácil a los usuario inexpertos. Una vez que se acostumbran a la nueva propuesta de diseño, es fácil de manejar y configurar.

Si usa Windows como sistema operativo, IE (Microsoft) viene incluido en él. Por lo que al instalar el sistema operativo, también se configura el navegador. Esto hace que no se necesite descargar ni instalar nada externo. Facilita la instalación y soporta tanto Applet como ActiveX.

Si es un fanático de la imagen, Firefox (Mozilla) le dará a través de los temas y complementos, gran variedad de opciones para jugar.

Ahora, decida y disfrute.

So far, So good!

Imágenes by Tinypic

Leer más...

miércoles, 5 de noviembre de 2008

Cantidad de Visitas al Articulo:

JTwain - Utilizando el scanner desde Java

Con motivo de una consulta, estuve probando y analizando librerías, algunas gratuitas y otras licenciadas, para el manejo de scanners en Java. Todas ofrecen características similares y permiten manejar un scanner bajo el standard TWAIN, claro que con algunas diferencias sustanciales, las cuales son relevantes en momento de seleccionar la correcta para nuestro proyecto.

Aquí expongo algunas experiencias de la librería seleccionada en mi caso y comparto información útil y ejemplos, para aquellos que necesiten desarrollar alguna aplicación basada en este tema. Además dejo referencias de otras librerías, y temas relacionados, como el reconocimiento de códigos de barras de las imágenes capturadas y OCR.

Librerías

Algunas librerías que puedo mencionar, son:

LibreríaDescripción
image mmscomputingEs una librería Open Source, que además del manejo de scanner para Windows, implementa Sane (manejo de scanner para Linux), fax, etc. Está disponible para Java y funciona perfectamente con JRE 1.4.2 o superior. Tiene un foro bastante completo y el coordinador (Michael Meiwald) responde muy rápidamente ante consultas. Sus respuestas son de gran ayuda. Además, existen ejemplos de uso de la librería muy completos y operativos, que ayudan mucho en el momento de armar nuestra solución.
imageJTwainEs licenciada, y permite el manejo del scanner, además de tratamiento de imágenes TIFF multipágina. El valor depende del modo de licenciamiento, dentro del rango de USD 198 a Euros.
imageMorenaEs el sucesor de JavaTwain. También cubre tanto Twain como Sane. Es una librería licenciada

Existen algunas mas, que no las probé, pero que cubren aproximadamente los mismos temas.

Trabajando con el standard

Todas las librerías permiten seleccionar el scanner con el que deseamos trabajar, así como el formato de imagen a capturar (JPG, TIFF, etc), calidad y tamaño de la misma.

En el caso de la librería que finalmente recomendé, mmscomputing, se debe implementar una interface en donde existe un método llamado negotiate, donde se realizan todos los ajustes de calidad de imagen, tamaño, y algunos otros, de acuerdo al standard TWAIN y las características soportadas de éste en el scanner seleccionado. Por ejemplo:

private void negotiate(ScannerIOMetadata metadata) {
ScannerDevice sd = metadata.getDevice();
try {
//Anulo pantalla de configuracion del scanner
sd.setShowUserInterface(false);
//Seteo que muestre barra progreso del scanner
sd.setShowProgressBar(true);
//Seteo area de escaneo
sd.setRegionOfInterest(TopLeft,TopRigth,Width,Heigth);
sd.setResolution(dDPI);
} catch (Exception e) {
addToLog("Error configurando scanner [" + e.getMessage() + "]",true);
metadata.setCancel(true);
}

if (metadata instanceof TwainIOMetadata) {
TwainSource source = null;
try {
source = ((TwainIOMetadata) metadata).getSource();
} catch (Exception ex) {
if (source!=null) source.setCancel(true);
}

try {
/* Habilito esto si deseo saber que está implementado del standard para
este scanner
TwainCapability[] cap = source.getCapabilities();
for (int h = 0; h < cap.length; h++) {
System.out.println(cap[h].getName());
}
*/

source.setShowProgressBar(true);
source.setCapability(TwainConstants.ICAP_UNITS, TwainConstants.TWUN_INCHES);

//Seteo colo de la imágen a capturar

if
(isColor) {
source.setCapability(TwainConstants.ICAP_PIXELTYPE, TwainConstants.TWPT_RGB);

} else if (isGrayScale) {
source.setCapability(TwainConstants.ICAP_PIXELTYPE, TwainConstants.TWPT_GRAY);
} else if (isBW) {
source.setCapability(TwainConstants.ICAP_PIXELTYPE, TwainConstants.TWPT_BW);
}
} catch (Exception e) {
if (source!=null) source.setCancel(true);
addToLog("Error configurando scanner [" + e.getMessage() + "]",true);
e.printStackTrace();
}
}

Formatos de Salida

Si la necesidad es escanear imágenes de una página, lo mejor es utilizar JPG, que guarda una buena relación entre tamaño y calidad (es una imagen comprimida con pérdida).

Si la necesidad es escanear imágenes multipágina, es necesario entonces usar TIFF.

Un problema que encontré, es que varias de ellas están generando archivos archivos .TIFF pero de la versión mas nueva (6.0) pero el visualizador de Windows, NO lo reconoce, porque por alguna razón nunca se actualizó a ese formato. Conclusión, si se desea visualizar la imagen generada en TIFF, ya sea multipágina o no, se debe usar otro software. Por ejemplo yo uso IrfanView, que es gratuito.

Por último, es bueno mencionar, que existen otras opciones de generación que no sean imágenes. Por ejemplo, una opción es PDF. Si usamos por ejemplo, una librería gratuita llamada iText, podemos generar documentos PDF multipáginas, con el agregado que en este caso podemos incluir imágenes de distintos tamaños, colores y calidades, contrario al caso de TIFF donde no es factible.

OCR y Códigos de Barras

Cuando lo que escaneamos es un formulario por ejemplo, que contiene uno o más códigos de barra, a veces es útil reconocerlos, y con el valor obtenido, hacer un control para nuestra aplicación. Para ello es necesario otras librerías como por ejemplo Aspose (es licenciada con un valor aproximado entre 390 y 1200 Euros, dependiendo del tipo de licenciamiento). Esta librería permite reconocer en una imagen JPG o TIFF un código de barras de diferentes tipos (CODE128, PDF417, etc).

El funcionamiento es muy sencillo, dado que existen primitivas para generar y reconocer códigos, así como también letras (OCR), con una buena calidad final.

Comentario Final

Son varias las opciones existentes, y se pueden combinar de muchas maneras, de tal forma que el proyecto en curso tenga final feliz.

So far, So good!

Imágenes by TinyPic

Leer más...

martes, 9 de septiembre de 2008

Cantidad de Visitas al Articulo:

Web Services con Visual Studio 2005

VS2005_2 Errores inesperados

Días atrás me encontré con un error inesperado cuando estaba consumiendo un Web Service de un tercero, al cual no tenía la posibilidad de acceder como para pedir ningún tipo de revisión.

Como comentario adicional antes de seguir en el desarrollo de éste tema, me gustaría hacer referencia al artículo anterior, donde hablo acerca de las facilidades actuales para los programadores, en la búsqueda de soluciones en línea ante problemas inesperados. En otra época, este inconveniente posiblemente hubiera retrasado el desarrollo quizá varios días, mientras que en la actualidad fueron un par de horas, de búsqueda en foros, blogs, etc., mas pruebas.

El problema

Consistía en que utilizando Visual Studio 2005, herramienta de desarrollo de Microsoft, generaba el proxy de conexión a un Web Service de un tercero sin problemas, automáticamente como lo permite este IDE en particular. Luego programaba la utilización de un método específico, y compilaba la aplicación sin errores. El error surgía cuando instanciaba el objeto del Web Service, de la forma:

using (TipoWS ws = new TipoWS()) { }

La excepción indicada era algo como: "Message = "No se puede reflejar el método TipoWS.Metodo."

Y la InnerException indicaba: InnerException {"El elemento XML 'Datos-Respuesta' del espacio de nombres 'urn:TipoWS' hace referencia a un método y a un tipo. Cambie el nombre del mensaje del método utilizando WebMethodAttribute o cambie el elemento raíz del tipo utilizando XmlRootAttribute."}

Luego de leer varios casos similares, y con la imposibilidad de acceder a modificar el WSDL del Web Service, encontré algunos indicios de solución, que me llevaron a resolver el tema, así que aquí lo comparto con Uds. por si alguno se encuentra con este inconveniente en el futuro.

La Solución

Consistió simplemente en modificar el nombre en el atributo SoapDocumentMethodAttribute, en uno de los dos métodos en que se referenciaba. Existían dos métodos del Web Service que se generaban en el archivo Reference.cs, de la forma:

[System.Web.Services.Protocols.SoapDocumentMethodAttribute("", RequestNamespace="urn:TipoWS",
ResponseElementName="Datos-Respuesta", ResponseNamespace="urn:TipoWS", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
[return: System.Xml.Serialization.XmlElementAttribute("Respuesta", Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
public Respuesta Metodo1([System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified, IsNullable=true)] Encabezado Encabezado, [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified, IsNullable=true)] Parametro Parametro, [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)] out respuesta Respuesta) {

[System.Web.Services.Protocols.SoapDocumentMethodAttribute("", RequestNamespace="urn:TipoWS",
ResponseElementName="Datos-Respuesta", ResponseNamespace="urn:TipoWS", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
[return: System.Xml.Serialization.XmlElementAttribute("Respuesta", Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
public Respuesta Metodo2([System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified, IsNullable=true)] Encabezado Encabezado, [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified, IsNullable=true)] Parametro Parametro, [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)] out respuesta Respuesta) {

Los métodos, Metodo1 y Metodo2, en el SoapDocumentMethodAttribute, hacían referencia a ResponseElementName="Datos-Respuesta". Esto provocaba el error en tiempo de ejecución antes mencionado.

La solución fue modificar uno de los dos a ResponseElementName="Datos", y el restante dejarlo como había sido generado.

Luego de compilar nuevamente el proyecto, la aplicación funcionó perfectamente.

Conclusiones

Puedo mencionar como conclusiones lo siguiente:

Es una solución factible, y que funciona, teniendo en cuenta la imposibilidad de acceder a modificar el Web Service o mejor dicho la definición WSDL.
En algún blog leí que el error se producía porque al generarse de esta forma el llamado a los métodos, no se cumplía con cierto estándar, pero no encontré mayor información al respecto como para dar fe de esta afirmación.

Aunque leí acerca de los atributos SoapDocumentMethodAttribute, (aunque en honor a la verdad no demasiado en profundidad) no encontré una razón lógica por la cual se de el error.

Tampoco encontré referencias concretas al porqué se genera así el proxy, como para determinar si en el momento de la generación, el programador a través de parámetros de generación, pude exigir chequeos de ésta naturaleza, de tal forma de evitar tener que retocar a mano el archivo generado automáticamente. Especialmente porque cada vez que se refresca la referencia al Web Service, se debe volver a modificar el archivo nuevamente.

Si algún lector tiene una explicación concreta acerca del problema, y una solución potencial, les pido lo publiquen como comentario de tal forma de poder cerrar este tema de la mejor forma posible. Sino, al menos tienen una ayuda para poder cumplir con los tiempos de desarrollo comprometidos :-).

Imágenes by TinyPic

So far, So good.

Leer más...
 
Este Weblog, InforMateando..., está licenciado bajo Licencia Creative Common - por Gustavo Suhit