I am in the process of upgrading our web services to support versioning. We will be publishing our versioned web services like so:
http://localhost/project/services/1.0/service.asmx
http://localhost/project/services/1.1/service.asmx
One requirement of this versioning is that I am not allowed to break the original wsdl (the 1.0 wsdl). The challenge lies in how to shepherd the newly versioned classes through the logic that lies behind the web services (this logic includes a number of command and adapter classes). Note that upgrading to WCF is not an option at the moment.
To illustrate this, let's consider an example with Blogs and Posts. Prior to the introduction of versions, we were passing concrete objects around instead of interfaces. So an AddPostToBlog
command would take in a Post
object instead of an IPost
.
// Old AddPostToBlog constructor.
public AddPostToBlog(Blog blog, Post post) {
// constructor body
}
With the introduction of versioning, I would like to maintain the original Post
while adding a PostOnePointOne
. Both Post
and PostOnePointOne
will implement the IPost
interface (they are not extending an abstract class because that inheritance breaks the wsdl, though I suppose there may be a way around that via some fancy xml serialization tricks).
// New AddPostToBlog constructor.
public AddPostToBlog(Blog blog, IPost post) {
// constructor body
}
This brings us to my question regarding serialization. The original Post
class has an enum property named Type
. For various cross-platform compatibility issues, we are changing our enums in our web services to strings. So I would like to do the following:
// New IPost interface.
public interface IPost
{
object Type { get; set; }
}
// Original Post object.
public Post
{
// The purpose of this attribute would be to maintain how
// the enum currently is serialized even though now the
// type is an object instead of an enum (internally the
// object actually is an enum here, but it is exposed as
// an object to implement the interface).
[XmlMagic(SerializeAsEnum)]
object Type { get; set; }
}
// New version of Post object
public PostOnePointOne
{
// The purpose of this attribute would be to force
// serialization as a string even though it is an object.
[XmlMagic(SerializeAsString)]
object Type { get; set; }
}
The XmlMagic
refers to an XmlAttribute
or some other part of the System.Xml namespace that would allow me to control the type of the object property being serialized (depending on which version of the object I am serializaing).
Does anyone know how to accomplish this?