Azure Mobile Services and DateTimeOffset

Important update: Please, see a comprehensive post by Carlos Figueira that recommends two additional workarounds for this issue.

I ended up implementing a combination of my approach below and Carlos’ custom JsonConverter.

I use DateTimeOffset very extensively, my corresponding SQL Azure table in mobile services uses datetimeoffset(3) column. The issue that I had was somewhere during JSON.NET serialization, the DateTimeOffset lost the offset and got converted to UTC. I couldn’t find any solution, until I experimentally started playing with the Mobile Services Client SerializationSettings, exposed in the latest SDK. Changing DateTimeZoneHandling  didn’t seem to help much until I discovered this post by Carlos. I changed it a little bit, keeping the idea, and voila: my DateTimeOffset now saves in Azure Mobile Services, no problem. If you know a better way, please let me know:

 

                MobileService.SerializerSettings.DateTimeZoneHandling = Newtonsoft.Json.DateTimeZoneHandling.RoundtripKind;
                // remove date time converter
                var conv = MobileService.SerializerSettings.Converters.Where(c => c is MobileServiceIsoDateTimeConverter).FirstOrDefault();
                if (conv != null)
                {
                    MobileService.SerializerSettings.Converters.Remove(conv);
                }
 
 

Retrieving more data from Azure Mobile Services using paging and LoadAllAsync extension

Azure Mobile Services allow you to take 50 records at a time by default, or 1000 records at maximum. What if you have more records and want to retrieve the entire table? I just created this beautiful extension method to help you get any amount of data you want, given any page size you want. This simple call to LoadAllAsync will asynchronously load ALL data from a WAMS table in pages of 1000 (or whatever number you specify) records (may also be good for bandwidth reasons):

var updatedReports = await azureTable.Where(r => r.complete == true).LoadAllAsync();

And this is an extension method, which elegantly does exactly what it says: loads all data. Enjoy:

        public async static Task<List<T>> LoadAllAsync<T>(this MobileServiceTableQuery<T> table, int bufferSize = 1000)
        {
            var query = table.IncludeTotalCount();
            var results = await query.ToEnumerableAsync();
            long count = ((ITotalCountProvider)results).TotalCount;
            if (results != null && count > 0)
            {
                var updates = new List<T>();
                while (updates.Count < count)
                {

                    var next = await query.Skip(updates.Count).Take(bufferSize).ToListAsync();
                    updates.AddRange(next);
                }
                return updates;
            }

            return null;
        }