2010-04-05 22 views
7

Tengo un servicio web .NET (usando asmx ... no han actualizado a WCF todavía) que expone lo siguiente:¿Por qué no puedo exponer una interfaz en un servicio web .NET asmx?

public class WidgetVersion1 : IWidget {} 
public class WidgetVersion2 : IWidget {} 

cuando intento para enlazar con el servicio web, me sale el siguiente error de serialización :

No se puede serializar el miembro WidgetVersion1 de tipo IWidget porque es una interfaz.

He intentado agregar varios atributos a la interfaz iwidget (XmlIgnore, SoapIgnore, NonSerialized), pero no son válidos en una interfaz.

¿Alguien sabe por qué no puedo exponer la interfaz? Supongo que WSDL no es compatible con las interfaces, pero ¿no podría .NET solucionar esto simplemente sin serializar la interfaz? ¿Hay alguna forma de evitar esto aparte de eliminar la interfaz de IWidget de las definiciones de clase WidgetVersion1 y WidgetVersion2?

Respuesta

10

WCF no puede serializar una interfaz o bien; de hecho, es imposible serializar una interfaz sobre SOAP.

La razón (simplificada) es que, cuando deserialización, .NET tiene que ser capaz de crear una clase concreta real. Una interfaz es un concepto abstracto; siempre debe haber una implementación de clase "real" detrás para que exista una instancia real.

Como no puede construir una instancia física de una interfaz, tampoco se puede serializar.

Si está intentando usar el XmlIgnoreAttribute, comprenda que al aplicarlo al tipo no se logrará nada. En su lugar, se debe aplicar al miembro . En otras palabras:

public class SerializableClass 
{ 
    [XmlElement] 
    public int ID { get; set; } 

    [XmlElement] 
    public string Name { get; set; } 

    [XmlIgnore] 
    public IMyInterface Intf { get; set; } 
} 

... serializará bien, porque el serializador no tratará de serializar la propiedad Intf. Simplemente no puede agregar el atributo [XmlIgnore] a la definición de tipo IMyInterface (no se compilará).

+0

Gracias por la explicación clara; tiene perfecto sentido. – mcliedtk

+0

Me preguntaba si ese era el caso y luego volví a leer la pregunta y aunque intentaba usar una clase que tenía una interfaz. – Joshua

2

Realice una función AsIWigit() que devuelve una clase de puente privado que implementa dicha interfaz.

Esto proporcionará una forma de convertir estas clases a la interfaz adecuada según sea necesario y funcionará con los servicios ASMX.

+0

+1 buena idea para evitar – mcliedtk

Cuestiones relacionadas