Portable Azure Mobile Services DTOs when using Xamarin and C#

Published on
Reading time
Authors

As part of an upcoming talk I am giving I am spending a lot of time working on a demo that shows how to do push notifications cross-device. One concept that is really drummed in when working in this space is that building reusable C# is key to leveraging the savings from building Windows Phone, iOS, Android apps this way.

A C# Azure Mobile Services client library exists for each of the platforms and it's really easy to use your standard C# classes as Data Transfer Objects (DTOs) for storage in Azure as a result. One item that tripped me up on Android and iOS was that I found I could write data to the cloud easily and while I could get a set of resulting objects back their properties were either null or in their default state. Not useful!

This is how my class looked - I had arrived at this after using DataMember and JsonProperty objects and finding, at first appearances, that I didn't need either for the code to actually work. I was wrong :).

public class Task : IBusinessEntity
{
  public Task () {}
  public int ID { get; set; }
  public string Name { get; set; }
  public string Notes { get; set; }
  public bool Done { get; set; }
  public string Assignee { get; set; }
}

The challenge in decorating the above class with DataMember is that this class isn't actually natively supported on Windows Phone - you will get a NotSupportedException the first time your application attempts to run any code that uses this class. The suggested fix in the Exception is to utilise the JsonProperty attribute instead which doesn't actually work on Android or iOS deployment. So... this is the fix I came up with - it's not pretty but it is leveraging one way to build portable C# code (note there is no default symbol defined for iOS builds which doesn't help!) Behold...

public class Task : IBusinessEntity
{
  public Task () {}

  public int ID { get; set; }

#if !WINDOWS_PHONE [DataMember(Name = "name")] #endif
  public string Name { get; set; }

#if !WINDOWS_PHONE [DataMember(Name = "notes")] #endif
  public string Notes { get; set; }

#if !WINDOWS_PHONE [DataMember(Name = "done")] #endif
  public bool Done { get; set; }

#if !WINDOWS_PHONE [DataMember(Name = "assignee")] #endif
  public string Assignee { get; set; } }

I think you'll find that compiler pre-processor directives like this will quickly become your friend when writing C# to target multiple platforms.