Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't I expose an interface in a .NET asmx web service?

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?

like image 855
mcliedtk Avatar asked Apr 05 '10 21:04

mcliedtk


2 Answers

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).

like image 133
Aaronaught Avatar answered Nov 08 '22 11:11

Aaronaught


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.

like image 37
Joshua Avatar answered Nov 08 '22 09:11

Joshua