Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sending DateTimeOffset from Android to .NET Web API

I am using Azure Mobile Apps SDK for Android.

public class MyClass {
    public String Id;
    public String Code;
    public DateTimeOffset ClientCreatedAt;
}

MyClass myClass = new MyClass();
myClass.Id = "1234567890";
myClass.Code = "dfgdrvyet";
myClass.ClientCreatedAt = new DateTimeOffset(new Date());

It is being used as follows:

MobileServiceSyncTable<MyClass> myClassSyncTable = _client.getSyncTable(MyClass.class);
ListenableFuture<MyClass> responseFuture = myClassSyncTable.insert(myClass);

Upon insertion, the ClientCreatedAt is set to null, when I investigated the insert statement, it is the Gson within the library that is not serialising the DatetimeOffset, specifically, this line:

JsonObject json = mClient.getGsonBuilder().create().toJsonTree(item).getAsJsonObject();

When I replace the DateTimeOffset with Date, the value is serialised properly.

So, my questions are:

  1. Is it intended in Azure Mobile Apps for me to use the DateTimeOffset and if so, what is the right way to use it?
  2. Can I force Gson to serialise the DateTimeOffset properly? I looked at the Gson Annotations, but nothing that can help there. I am not sure if I should be creating a getter and a setter for serialising and deserialising.
like image 706
Adam Avatar asked Mar 01 '16 01:03

Adam


1 Answers

DateTimeOffset is actually a dumb wrapper of Date. Here it is in its entirety.

/**
 * Represents a point in time, typically expressed as a date and time of day
 */
public class DateTimeOffset extends Date {

    public DateTimeOffset(Date date) {
        this.setTime(date.getTime());
    }
}

I threw my hands up in the air and simply decided to use Strings instead, and joda-time's DateTime class via DateTime.parse(string) to handle them.

However the nice alternative is probably to register your own serialiser via MobileServiceClient.registerSerializer(...) but you won't get anything useful out of using their wrapper.

This SDK is rubbish.

edit: Using a custom (de)serialiser seems to work quite well:

private class DateTimeSerialiser implements JsonSerializer<DateTime>, JsonDeserializer<DateTime> {
    @Override
    public JsonElement serialize(final DateTime src, final Type typeOfSrc, final JsonSerializationContext context) {
        return new JsonPrimitive(src.toString());
    }

    @Override
    public DateTime deserialize(final JsonElement json, final Type typeOfT, final JsonDeserializationContext context) throws JsonParseException {
        return DateTime.parse(json.getAsString());
    }
}

Set it up to deserialise/serialise to/from the object of your choice, then set an instance of it via MobileServiceClient.registerSerializer + registerDeserializer. If using local sync, just use ColumnDataType.String or ColumnDataType.DateTimeOffset (it's just String under the hood). Now you can have your field set to the type you want.

private DateTime date;
like image 114
Tom Avatar answered Nov 01 '22 15:11

Tom