MVC 4 Web API Quirks

The ASP.NET MVC 4 Beta includes ASP.NET Web API which makes it very easy to expose data through a REST API in either XML or JSON with very little code.  There are some great tutorials on the asp.net site to get up and running.  After working with MVC 4 for a while, I have discovered a few quirks, so hopefully these tips will save you some time.

XML and IEnumerable Properties

The MVC4 ApiController will automatically detect the request's Content-Type to see if it is expecting application/json or text/xml in the response.  One of my model classes had a collection as one of the properties and I was using a generic IEnumerable<MyClass> to define that property:

public class Team
{
    public int TeamId { get; set; }
    public string TeamName { get; set; }
    public IEnumerable<Person> TeamMembers { get; set; }
}

Everything seemed to be working while I was testing with JSON, but when I tried an XML Content-Type, I would get JSON back instead of XML! 
I eventually tried using a List<> instead of an IEnumerable<> and then both XML and JSON Content Types worked.  I prefer to use IEnumerable instead of List when possible, but in this case, I'd rather leverage Web API serialization and use a List:

public class Team
{
    public int TeamId { get; set; }
    public string TeamName { get; set; }
    // Need to use List<> here instead of IEnumerable,
    // otherwise text/xml type will not work
    public List<Person> TeamMembers { get; set; }
}

Calculated Properties

Another oddity I ran into while using Web API was an issue with calculated properties.  I will use this Person class as an example of returning a calculated Age property:

public class Person
{
    public int PersonId { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public DateTime Birthday { get; set; }
    public int Age
    {
        get
        {
            DateTime now = DateTime.Today;
            int age = now.Year - Birthday.Year;
            if (Birthday > now.AddYears(-age)) age--;
                 
            return age;
        }
    }
}

This seems simple enough, but when I looked in the serialized results that contained this class, the Age property was missing for both XML and JSON Content Types.
I discovered that the reason for this is that Web API will not serialize readonly properties.  Since my Age property only has a "get" accessor, it was ignored.

I am hoping this will be resolved in the final version of MVC 4, but for now, a simple solution is to add a "dummy" setter on the property:

public int Age
{
    get
    {
        DateTime now = DateTime.Today;
        int age = now.Year - Birthday.Year;
        if (Birthday > now.AddYears(-age)) age--;
                 
        return age;
    }
    // Current version of MVC won't serialize readonly properties.
    // Trick it with a setter that does nothing
    set { var temp = value; }
}



comments powered by Disqus