Web services and derived classes
[WebMethod] public MyBase SayHello() { return new MyDerivedClass(); } public class MyBase { } public class MyDerivedClass : MyBase { }
When doing this in an ASP.NET 2.0 (and I imagine ASP.NET 1.1 functions similarly), I get hit with this exception:
System.InvalidOperationException: There was an error generating the XML document. --->
System.InvalidOperationException: The type MyNamespace.MyDerivedClass was not expected.
Use the XmlInclude or SoapInclude attribute to specify types that are not known statically.
This seems to be a major design flaw in the implementation of the Xml Serializer (which was rumoured to be completely revamped in 2.0). It seems strange that I should need to go into my web service and add an XmlInclude attribute every time I add a new derived class.
Can anyone explain this, or any possible workarounds?
It’s because of the XSD. The wsdl must contains a description of every return types explained by an xsd, so derived type cannot be resolved.
The only workarround is to create a kind of container that implements IXmlSerializable. It’s must serialize manually every type and add also the type name for the deserilization but I will not be cross plateform.
Hope this help
David
I’ve run into the same exception that I believe is a bug also. But this has to do with the auto-generated proxy class when adding a web reference to a project.
Lets say the proxy class has some sort of Send( basetype ) method on it. The BaseType is defined in the proxy as well. For reasons that are besides the point of this thread, I needed to create a type derived from the base type, which could implement an interface. The derived type is completely blank. The base type completely satisfies the implementation of the interface.
At first I just tried calling proxy.Send( derivedType ) and received the same exception you received. I thought ok, thats a little weird, but figured I would just cast up to the base type ( remember I’m not losing anything from the empty derived type ).
So, I called proxy.Send( ( BaseType ) derivedType )… I am sending the expected type. I still receive this ridiculous exception.
Why would the following work ( work with me on the “all properties” )
BaseType baseType = new BaseType();
baseType.[ all properties ] = derivedType.[ all properties ];
proxy.Send( baseType );
but this not work
BaseType baseType = ( BaseType ) derivedType;
proxy.Send( baseType );
In both cases, I am sending an object whose runtime type is the type expected by the proxy. AHHHHHHHH… This is not a case where XmlInclude or SoapInclude are helpful… I can not add these attributes to the proxy class every time VS autogenerates it ( still in development, proxies are going to be updated fairly consistently ), if this were the case, I might as well just modify the proxy to implement the interface and have no derived type. This is all besides the point… how are the two code samples I gave different?
I figured a way around my problem at least. I included partial classes for the BaseType which were empty, but declared that the BaseType implemented my interface ( which they completely satisfied ). This allowed my proxies to be updated during development, since I knew the BaseType wouldn’t change, and I didn’t have to keep modifying the autogenerated proxy to implement and interface.


