viernes, 24 de febrero de 2012

No se puede generar una clase temporal (result=1).error CS0029: No se puede convertir implícitamente el tipo 'servicioType' a 'servicioType[]'

Agregué una referencia a un webservice en una solución web de .net, cuando hice el debug obtuve el siguiente error al intentar crear una instancia del webservice:


No se puede generar una clase temporal (result=1).error CS0029: No se puede convertir implícitamente el tipo 'servicioType' a 'servicioType[]' 

Comencé a investigar y el problema y su solución son muy entretenidos.

Parece ser que el webservice fue generado con una herramienta para exponer procedimientos almacenados creados en Oracle. El webservice tiene  la siguiente estructura:

<?xml version="1.0" encoding="UTF-8"?>
...
</WL5G3N0:types>

Se nota que es un error de conversión, me enteré que el error sucede solo al tratar de consumir el webservice con .NET, con Java no sucede, leyendo aquí  encontré un enlace a la pagina de soporte de Microsoft que explica como solucionar parcialmente el problema:

"Este problema se produce cuando el Asistente para publicación de servicios Web de BizTalk utiliza la herramienta de lenguaje de descripción de servicios Web (WSDL.exe) para generar la información de cliente. Cuando publica un esquema que contiene nodos anidados que tienen el atributo  maxOccurs  establecido en el valor "unbounded", la herramienta WSDL.exe crea matrices multidimensionales en el archivo datatypes.cs generado. Por lo tanto, el archivo datatypes.cs generado contiene tipos incorrectos para los nodos anidados."

pagina de soporte de Microsoft: http://support.microsoft.com/kb/891386

Ahora que sabemos que el error se produce en el programa WSDL.EXE al generar la clase que representa al webservice.  

Podemos solucionar el problema en pocos pasos:

1.- Generar una clase proxy  con la aplicación wsdl.exe que trae Visual Studio.
2.- Reparar a mano la clase generada.
3.- Crear una dll a partir de la clase reparada.
4.- Agregar la dll como referencia en nuestro proyecto.

Detalle de los pasos:

1.-Para ejecutar wsdl.exe debemos abrir una ventana de comando de Visual Studio, se puede levantar desde el menú inicio:

Inicio/Todos los programas/ Microsoft Visual Studio 2010/ Visual Studio Tools/ Visual Studio Command Prompt (2010)

Esto nos levanta una ventana de comando, para ejecutar el programa wsdl.exe, en la que escribiremos lo siguiente:

wsdl http://serverdesa.company.cl/info?WSDL 
Donde  http://serverdesa.company.cl/info?WSDL es la url del webservice incluyendo '?wsdl'.



 Después de ejecutar el comando,  aparece en la pantalla la ruta donde fue generada la clase.


2.- Ahora abrimos la clase que acabamos de generar y reemplazamos todas las ocurrencias de [][] por [].


3.- Nuevamente abrimos la ventana de comando del Visual Studio y ejecutamos la siguiente linea:

Para C#:
csc.exe /t:library /r:System.dll,System.Web.Services.dll,System.XML.dll [Nombre de la clase generada].cs


Para Visual Basic:
vbc.exe  /t:library /r:System.dll,System.Web.Services.dll,System.XML.dll [Nombre de la clase generada].cs

Después de ejecutar el comando, NO APARECE en la pantalla  la ruta donde fué generada la DLL, pero la genera en la misma carpeta VC.

4.- Ahora agregamos la DLL como referencia a nuestro proyecto.

Y Listo!

Créditos:
En esta pagina vi como generar la dll a partir de la clase:

Pagina de Soporte de  Microsoft que explica como editar la clase proxy (de forma engorrosa)
español:

ingles: