2009-09-17 15 views
6

Tengo este escenario donde un método webservice que estoy consumiendo en C# devuelve un objeto Business, cuando llamo al método webservice con el siguiente código obtengo la excepción "No se puede lanzar el objeto tipo de ContactInfo para escribir ContactInfo" en la clase reference.cs de la referencia webNo se puede convertir el objeto del tipo MyObject para escribir MyObject

Código:

ContactInfo contactInfo = new ContactInfo(); 
Contact contact = new Contact(); 

contactInfo = contact.Load(this.ContactID.Value); 

sería muy apreciada Cualquier ayuda.

+0

¿Ha actualizado su referencia web últimamente? – womp

Respuesta

10

Esto se debe a que uno de los objetos ContactInfo es un proxy del servicio web y está en un espacio de nombre diferente.

Es un problema conocido con los servicios web de estilo asmx. En el pasado, implementé la copia superficial automática para evitarla (here's how, aunque si lo hiciera de nuevo, probablemente miraría AutoMapper).

Por ejemplo, si usted tiene un conjunto con la siguiente clase:

MyProject.ContactInfo 

y regresa una instancia del mismo a partir de un método web:

public class DoSomethingService : System.Web.Services.WebService 
{ 
    public MyProject.ContactInfo GetContactInfo(int id) 
    { 
     // Code here... 
    } 
} 

Entonces, cuando usted agregar la referencia Web para su proyecto de cliente, realmente obtiene esto:

MyClientProject.DoSomethingService.ContactInfo 

Esto significa que si, en su cliente ap plicatura, se llama al servicio web para obtener una ContactInfo, usted tiene esta situación:

namespace MyClientProject 
{ 
    public class MyClientClass 
    { 
     public void AskWebServiceForContactInfo() 
     { 
      using (var service = new DoSomethingService()) 
      { 
       MyClientProject.DoSomethingService.ContactInfo contactInfo = service.GetContactInfo(1); 

       // ERROR: You can't cast this: 
       MyProject.ContactInfo localContactInfo = contactInfo; 
      } 
     } 
    } 
} 

Está en la última línea que utilizo mi clase ShallowCopy:

namespace MyClientProject 
{ 
    public class MyClientClass 
    { 
     public void AskWebServiceForContactInfo() 
     { 
      using (var service = new DoSomethingService()) 
      { 
       MyClientProject.DoSomethingService.ContactInfo contactInfo = service.GetContactInfo(1); 

       // We actually get a new object here, of the correct namespace 
       MyProject.ContactInfo localContactInfo = ShallowCopy.Copy<MyClientProject.DoSomethingService.ContactInfo, MyProject.ContactInfo>(contactInfo); 
      } 
     } 
    } 
} 

NOTA
Esto sólo funciona porque la clase proxy y la clase "real" tienen exactamente las mismas propiedades (una se genera a partir de la otra por Visual Studio).

0

¿Cómo hace referencia a la clase en su proyecto de servicio web y en su proyecto de consumidor? Si simplemente ha utilizado un enlace de archivo, esto bien podría explicar la causa del error. La manera en que funciona la serialización para .NET (servicios web o de otro modo, creo) es mediante el uso de la reflexión para cargar/volcar los datos de un objeto. Si los archivos están simplemente vinculados, entonces en realidad se están compilando en diferentes tipos en diferentes ensamblajes, lo que explicaría por qué tiene el mismo nombre pero no puede convertirlos. Recomiendo crear una biblioteca 'Core' a la que se refieran tanto el servicio web como el proyecto del consumidor, y que contenga la clase ContactInfo que utiliza en todas partes.

0

Esto no es un problema, es una característica.

Son dos clases independientes. Compare los dos y observe que la clase proxy no tiene ninguno de los constructores, métodos, indizadores u otro comportamiento de la clase original. Esto es exactamente lo mismo que sucedería si consume el servicio ASMX con un programa Java.

+1

@Downvoter: ¿quieres que a alguien le importe lo que piensas? Entonces tendrás que decir lo que piensas. "-2" no dice mucho. En cambio, di por qué bajaste tu voto. –

+0

No debería comportarse de esta manera. Tenemos este problema cuando utilizamos un proxy generado solamente, no cuando usamos el método CreateChannel, pero nuestro problema es el mismo que en esta publicación. No creo que esto sea una característica. – schmoopy

+0

@schmoopy: está usando servicios web ASMX, no WCF. No hay un método 'CreateChannel'. –

1

Como varias de las otras respuestas han sugerido, es porque .NET las ve como dos clases diferentes.Yo personalmente recomendaría usar algo como AutoMapper. Lo he estado usando, y parece bastante impresionante. Puedes copiar tus objetos en 1-2 líneas de código.

Mapper.CreateMap<SourceClass, DestinationClass>(); 
destinationInstance = Mapper.Map<SourceClass, DestinationClass>(sourceInstance); 
0

Parece que tiene dos clases diferentes en ambos extremos. Su aplicación tiene clase ContactInfo y su servicio web también tiene la clase ContactInfo. Ambas son dos clases completamente diferentes. Una forma es usar la clase WebService de su lado. Si usa ContactInfo dentro de su servicio web, se serializará y estará disponible para su uso en el lado del cliente.

1

En realidad, esto no es un error. ¡Es un problema con los cambios de versión de su propio proyecto! ¡Debido a que su ejecución final no utiliza las referencias originales importadas en la compilación!

Por ejemplo, estaba haciendo un servidor de chat, cliente. Usé una estructura de paquete para transmitir datos en el proyecto del cliente. Luego importó la misma referencia al proyecto del servidor.

Al emitir Packet packet = (Packet)binaryFormatter.Deserialize(stream); recibí el mismo error. ¡Porque la referencia de ejecución real en el proyecto del servidor no es la referencia ahora en el proyecto del cliente! ¡Porque he reconstruido el proyecto del cliente muchas veces después!

En la fundición <new object>=(<new object>) <old object> siempre el nuevo objeto debe ser una versión más nueva o la misma que el antiguo.

Lo que hice fue construir un proyecto separado para crear una DLL para la clase Packet e importé el archivo DLL a ambos proyectos.

Si realicé algún cambio en la clase Packet, tengo que volver a importar la referencia al cliente y al servidor.

¡Entonces la fundición no dará la excepción anterior!

0

También puede modificar su archivo References.cs generado por Visual Studio cuando se agrega la referencia web. Si elimina las clases generadas por el proxy y agrega una referencia (usando sentencias) a sus clases personales, podrá usarlas de inmediato, sin una copia/reflexión superficial o mapeo pesado. (pero tendrá que volver a aplicar su modificación si regenera la capa de proxy).

También traté de serializar el objeto proxy y deserializarlos en mis clases de DTO, pero era bastante pesado en cuanto a los recursos, así que terminé modificando la capa Referencias cs generadas.

esperan que ayude a otras personas que vienen aquí :)

amablemente.

Cuestiones relacionadas