Outputting custom xml with .net web api

I recently had to create a REST service using .net’s web api. The only problem was that it was outputting the class name and properties ‘as-is’ and the root node was just was ‘ArrayOfClassName.’ This post is about outputting custom elements, attributes and root nodes using Xml serialization.

The problem in question was automating an xml feed of google promotions. You can upload a custom xml file into the google custom search tool that contains promotions. These are links that always appear at the top of the listings based on a given query.

So initially I created a class called ‘ExtendedSearchPromotion’ (there was also a ‘SearchPromotion’ class which I’m not going to go into here). This had properties for title, description, image url, queries etc. There was also a class called ‘ExtendedSearchPromotions’ looking like this…

public class ExtendedSearchPromotions
{
 public List<ExtendedSearchPromotion> Promotions { get; set; }
 public int Start { get; set; }
 public int NumberOfPromotions { get; set; }
 public int TotalPromotions { get; set; }
}

The output xml file must contain all these elements. However, the Start, NumberOfPromotions and TotalPromotions have to appear as attributes, not elements. Also, the Promotions element has to be output as an array of ‘Promotion’ objects. Finally, the root node must be called ‘Promotions.’

Lots of people seem to be outputting custom xml by creating wrapper classes. This seemed like a bit of a clumsy was of doing things. Xml Serialization attributes to the rescue!

Adding custom serialization

The first step is to just add the necessary attributes to the class properties and the class itself, like so…

[XmlRoot(ElementName = "Promotions")]
public class ExtendedSearchPromotions
{
 [XmlElement("Promotion")]
 public List<ExtendedSearchPromotion> Promotions { get; set; }

 [XmlAttribute("start")]
 public int Start { get; set; }

 [XmlAttribute("num")] 
 public int NumberOfPromotions { get; set; }

 [XmlAttribute("total")]
 public int TotalPromotions { get; set; }
}

So, instead of the root being ‘ArrayOfExtendedSearchPromotions’ or ‘ExtendedSearchPromotions’ it just becomes ‘Promotions.’ This root node contains the attributes for start, num and total and contains an array of ‘Promotion’ elements.

For google custom search to accept the promotions, they must also be marked up with xml serialization attributes for all their respective values (title, description etc).

Inside the controller, the action just returns an object of type ‘ExtendedSearchPromotions’…

public ExtendedSearchPromotions GetExtendedSearchPromotions()
{
 var esp = new ExtendedSearchPromotions();
 esp.Promotions = GetExtendedSearchPromotionItems();
 esp.Start = 0;
 esp.TotalPromotions = 0;
 esp.NumberOfPromotions = 0;
 return esp;
}

Setting the XML formatter

The final step is to explicitly set ExtendedSearchPromotions to use the xml serializer. This is done in the ‘OnApplicationStarting’ event…

var promotionsXmlFormatter = GlobalConfiguration.Configuration.Formatters.XmlFormatter;
            promotionsXmlFormatter.SetSerializer<ExtendedSearchPromotions>(new XmlSerializer(typeof(ExtendedSearchPromotions)));

This is much nicer than setting the Global configuration to use the XML serializer, since in this project I also have web api controllers that are called using javascript and will return JSON.

Conclusion

This is the output so far, nice and custom-ified. I thought I’d create a post about this because I had to trawl loads of different pages to gather all the relevant bits of info. Let me know if there’s a better way to do it.

Promotions XML output

Promotions XML output

 

One thought on “Outputting custom xml with .net web api

Leave a Reply