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; }
}