title: .NET asmx web services: serialize object property as string property to support versioning
body: <p>I am in the process of upgrading our web services to support versioning. We will be publishing our versioned web services like so:</p>
  
  <pre><code>http://localhost/project/services/1.0/service.asmx
  http://localhost/project/services/1.1/service.asmx
  </code></pre>
  
  <p>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.</p>
  
  <p>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 <code>AddPostToBlog</code> command would take in a <code>Post</code> object instead of an <code>IPost</code>.</p>
  
  <pre><code>// Old AddPostToBlog constructor.
  public AddPostToBlog(Blog blog, Post post) {
      // constructor body
  }
  </code></pre>
  
  <p>With the introduction of versioning, I would like to maintain the original <code>Post</code> while adding a <code>PostOnePointOne</code>. Both <code>Post</code> and <code>PostOnePointOne</code> will implement the <code>IPost</code> 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).</p>
  
  <pre><code>// New AddPostToBlog constructor.
  public AddPostToBlog(Blog blog, IPost post) {
      // constructor body
  }
  </code></pre>
  
  <p>This brings us to my question regarding serialization. The original <code>Post</code> class has an enum property named <code>Type</code>. 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:</p>
  
  <pre><code>// 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; }
  }
  </code></pre>
  
  <p>The <code>XmlMagic</code> refers to an <code>XmlAttribute</code> 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).</p>
  
  <p>Does anyone know how to accomplish this?</p>