Formatting Hypermedia Link Properties into Atributes in .Net Web API

If you're like me, and I know I am, you've been playing around with .Net Web API for a little while now. In an attempt to create Hypermedia where your returned objects include lots of links to related things or actions, you probably created a Link class that looked something like this:

    public class Link
    {
        public string Rel { get; set; }
        public string Href { get; set; }
        public string Method { get; set; }
    }

And you probably included this class as a property of some other more significant class like this:

    public class Task
    {
        public long? TaskId{ get; set; }
        public List<Link> Links { get; set; }
        public string Status { get; set; }
    }

Now what you had hoped you were creating probably looked like:

<Task xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/Acme.Web.Api.Models">
 <TaskId>1</TaskId>
 <Links>
  <Link Href="/Tasks/1" Method="GET" Rel="self"></Link>
 </Links>
 <Status>Beginning Import</Status>
</Task>

But then you were sorely kind of disappointed when your output looked like:

<Task xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/Acme.Web.Api.Models">
 <TaskId>1</TaskId>
 <Links>
  <Link>
   <Href>/Tasks/1</Href>
   <Method>GET</Method>
   <Rel>self</Rel>
  </Link>
 </Links>
 <Status>Beginning Import</Status>
</Task>

Well fear not for Lord Zoltan has the solution.

Simply implement IXmlSerializable.

Solution:

    public class Link : IXmlSerializable
    {
        public string Rel { get; set; }
        public string Href { get; set; }
        public string Method { get; set; }
        public XmlSchema GetSchema()
        {
            return null;
        }
        public void ReadXml(XmlReader reader)
        {
        }
        public void WriteXml(XmlWriter writer)
        {
            writer.WriteAttributeString("rel", Rel);
            writer.WriteAttributeString("href", Href);
            writer.WriteAttributeString("method", Method);
        }
    }

Now whether or not that is it for implementing Hypermedia in your Web API, I'm not going to say that. But I certainly am one step closer at least as far as formatting is concerned. I still have more to read up on fun little keywords like HAL.