views:

811

answers:

2

Hi,

I am using an abstract class as a parameter in a web service call. Currently, I am including an XmlInclude of a derived class in the base class, like so:

[XmlInclude(typeof(DerivedClass))]
public abstract class BaseClass
{
}

However, I'd rather not include all of the derived types in the base class.

In http://www.pluralsight.com/community/blogs/craig/archive/2004/07/08/1580.aspx, the author mentions an alternative - writing the attribute above the web method instead, like so:

[WebMethod]
[System.Xml.Serialization.XmlInclude(typeof(DerivedClass))]
public BaseClass getClass() {
     return new DerivedClass(); 
}

However, I'd also like to not put the derived types in the web service either. Is there a way of keeping the attribute in the derived type?

+1  A: 

I don't see how in this case. If you are deserializing there is an overload for specify extra types array where you pass in the derived types.

eschneider
+1  A: 

Lets take it as a given that the framework would somehow need to know what types are in the type hiearchy when deserialization occurs, and how those types are represented in xml. It really has no way to infer this information if it is stored in a derived type.

You then have a couple of options: - use the XmlInclude attribute - specify the set of allowed types in the XmlSerializer Constructor overload

Now, if you're expecting a subclass to be passed in to the webservice, the webserver controls serialization and deserialization. So the XmlSerializer contstructor is no longer an option.

As you say, you can put the attribute on the webservice method instead of directly on the class. There's a trade-off between keeping your class "pure" and remembering to put those attributes in every place they may be required.

Of course, the real problem appears to be that you are trying to use your business objects as the message format in your webservice layer.

If you really want to keep the "message format" and "business object" responsibilities separate, then have another class (with the full hierarchy) for which the only use is to be used as a webservice parameter. In that case, there's no problem with sticking all the XmlInclude attributes you need, on the base class. Then, when making calls to the webservice, adapt your business object to and from the message format object. This gives you the added benefit of not applying webservice type constraints to the types of your parameters (eg no interfaces as parameters).

Of course, this method isn't as convenient.

In the end, the webservice needs to know what types to expect, or it won't be able to serialize and deserialize them properly.

And yes, this is a long winded explanation of why the answer is no, you can't only keep the attribute in the derived type. I'd love to be wrong though :)

Nader Shirazie