Lessons learned: Getting Android to connect to a WCF service

The initial concept of my mobile application was built on a Windows Phone 7 front end, tied nicely together with a WCF SOAP service on the back. I used “Add Service Reference”, and I pretty much forgot about the fact that I was programming against a web service. That was March. This is April. In [...]

The initial concept of my mobile application was built on a Windows Phone 7 front end, tied nicely together with a WCF SOAP service on the back. I used “Add Service Reference”, and I pretty much forgot about the fact that I was programming against a web service.

That was March. This is April.

In migrating to Android, I’ve come face to face with the beast that is .NET – Java interop. I’ve heard many tales in many night time stories about brave, young, dashing developers like myself being slaughtered by that ugly beast.

Yet, through 3 weeks of constant battle, flowing tears, and jubilant victories, I smote his ruin upon the mountainside.

Here are some tips for other dare devils such as myself looking to follow in these large footsteps:

Lesson 1: Lose the SOAP, get some REST.

Moving forward to my Android development, I quickly realized that any pretenses I had of using the existing WCF SOAP service with Android needed to be lost. Sure I could use ksoap, but come on folks, learning an entirely new platform is hard enough; there is no way I am going to complicate that by integrating in some 3rd party framework.

What’s a player to do?

Simple, wrap the existing Service Contract in a WCF REST-ful Service Contract! The process of wrapping the existing SOAP service with a REST-ish type of interface was quite painless.

I went from an interface like this:


    [OperationContract]

    SendChallengeResponse SendChallenge(long fromID,

    long toID,

    string challengeXML,

    out DateTimeOffset dateSent,

    long challengeDefinitionID,

    MessageOptions options,

    AuthnToken authnToken);

    

To:


    [WebInvoke(UriTemplate = "Challenges/CreateChallenge?fromUserID={fromUserID}&toUserID={toUserID}&challengeDefinitionID={challengeDefinitionID}&message={message}&dateSent={dateSent}&token={authnToken}",
    RequestFormat = WebMessageFormat.Xml, ResponseFormat = WebMessageFormat.Xml)]

    SendChallengeResponse SendChallenge(long fromUserID, long toUserID, long challengeDefinitionID, string message, string dateSent,
    string authnToken);

    

DevDiv, you’ve done it again! Converting a SOAP contract to a REST-ful contract in .NET 4.0 took about as long as it did for me to get off the first time a woman touched me “down there”.

In retrospect, I can see why everybody seems to have such a hard-on for REST (or as I would call it, HTTP web services). It doesn’t require any fancy mucking about with SOAP envelopes. (If you used WCF this wouldn’t be a problem, since WCF does everything but write your application code for you) Now the huge drawback that I see is that I can’t get the same strongly typed client that I do with a WSDL. This, combined with the short-bus XML libraries in Android, make the whole process of serialization a giant pain in the ass.

But I am sure there are a million Android developers out there who love the fact that they can write their own serialization code. Well I don’t. I’d much rather be out somewhere doing lines off a hooker’s ass than writing a god damned XML serializer.

Lesson 2:
The Android Time class was designed by an intern, either that, or a retard.

I never thought simply passing Dates between Android and WCF would be such a pain in the ass. Seriously, its 2011, why can’t everybody just agree to at least by default output dates in a common format and support the parsing of that common format across the board?

Not to mention, Android includes its own concept of a Date which is called a “Time” object. According to the docs, the Time class is “light weight” and “quick”. Come on now, I used to be a Redmond PM. I would drop those words whenever I had no idea what I was talking about (which was frequent). The actual interface of this class looks like it was sketched out by Lindsay Lohan. I’ve been very impressed with the patterns and interface design across the Android platform…except when it comes to Time.

I’m particularly fond of such gems as:

    void setToNow();

    void Parse(string input);

    

I don ‘t want to be a player hater, but come on, a void method for setting the current time?!Why aren’t these statics? Why does the parse() method not support the same subset of formats that the Java Date class does?

Anyways, I found the best way to achieve interop between the Android Time class and the .NET DateTimeOffset was to use the RFC 3339 format. Luckily, the Time class includes a parse3339() which will read a DateTimeOffset .NET object formatted according to this string:

“yyyy’-'MM’-'dd’T'HH’:'mm’:'ss’.'fff’Z'”

Coming from .Android to .NET, I was able to use the format3339() method on the Time class to output a date string that could be parsed with the format specified above with the DateTimeOffset.parse() method.

But wait, there is a wrinkle. I wanted to standardize on UTC times across the board. Server, client, everything in UTC. However, if one does not instantiate the Time class with the “UTC” timezone in the constructor, then the Time class will output an additional “+000Z” to indicate the time zone, this will cause the DateTimeOffset object to barf attempting to parse it.

Lesson 3: WCF serialization errors may leave you a “connection reset by peer” error on the Android side

I had a DataContract that included a type that was non serializable. I didn’t know this. I sat there staring at a “connection reset” error on the Android side even after having debugged fully through the WCF call behind it (with no errors being thrown). It was only after I used Fiddler to execute the command directly was I able to see that WCF was throwing an exception post-call when serializing the object.

I love Fiddler. What a cool tool. But what’s with the “Object not set to a reference” dialog error that it throws every once in a while? Seriously, Microsoft must have hired the same intern who designed the Time class to be apart of the Fiddler team. Somehow code which I imagine to be equivalent to:

</pre>
    try {
    Obj.dosomething();
    }

    catch (NullReferenceException e) {
    Dialog.Show(e.getMessage());
    }

    

Got passed a code review and into a source tree. Displaying a dialog box which tells me there is a NullReferenceException is really not all that more useful than displaying the stack trace itself. In fact, I wish Fiddler did just crash on the Exception, at least I could figure out what was causing it.

About Bobby Gill

I am the creator of Bahndr, founder of New York based app development lab, Blue Label Labs and editor at Idea to Appster. I like crepes and I am fascinated by big data.

  • http://www.deanblakely.com Gary Blakely

    For the past few months I have been in the process of converting three of my WP7 apps to Android and, like you, my WP7 apps use WCF SOAP. I found your article because I was having trouble with dates so this was very useful to me.

    Like you, I ended up using REST and found I could do anything with a POST. I wrote a .NET Web API service that the Android apps post to with identical methods to my WCF SOAP service. Sometimes I duplicate the code and sometimes the Web API service calls the WCF SOAP service (they are on the same server).

    Turns out I really like the android platform and the background service capability is way better than WP7.

    Thanks for making this post else I would still be in DateTime hell.