views:

158

answers:

3

I have a .NET web service (using asmx...have not upgraded to WCF yet) that exposes the following:

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

When I attempt to bind to the web service, I get the following serialization error:

Cannot serialize member WidgetVersion1 of type IWidget because it is an interface.

I have tried adding various attributes to the IWidget interface (XmlIgnore, SoapIgnore, NonSerialized), but they are not valid on an interface.

Does anyone know why I am unable to expose the interface? I assume WSDL does not support interfaces, but couldn't .NET get around this by simply not serializing the interface? Are there any ways around this apart from removing the IWidget interface from the WidgetVersion1 and WidgetVersion2 class definitions?

+2  A: 

Make a function AsIWigit() that returns a private bridge class that implements said interface.

This will provide a way to convert these classes to the appropriate interface as needed and will work with the ASMX services.

Joshua
+1 nice idea for getting around this
mcliedtk
A: 

Because interfaces can't be serialized.

See http://stackoverflow.com/questions/659039/web-service-cant-serialize-an-interface

Michael Shimmins
+4  A: 

WCF can't serialize an interface either; in fact, it's impossible to serialize an interface over SOAP.

The reason (simplified) is that, when deserializing, .NET has to be able to create some actual concrete class. An interface is an abstract concept; there always has to be a "real" class implementation behind it in order for an actual instance to exist.

Since you can't construct a physical instance of an interface, it also can't be serialized.

If you're trying to use the XmlIgnoreAttribute, understand that applying it to the type won't accomplish anything. It needs to be applied to the member instead. In other words:

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

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

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

...will serialize OK, because the serializer won't try to serialize the Intf property. You just can't add the [XmlIgnore] attribute to the IMyInterface type definition (it won't compile).

Aaronaught
Thanks for the clear explanation; it makes perfect sense.
mcliedtk
I was wondering if that was the case and then read the question again and though he was trying to use a class that had an interface.
Joshua