The wFace – windows phone 7 facebook integration Series
This article series shows how to use the Facebook graph_API (http://developers.facebook.com/docs/API) in a windows phone 7
(wp7) Silverlight application. All used tools are free software - for downloads take a look at the links at the end of this
document.
Part1
Part2
Part3
What we’ve done so far
We made a windows phone 7 application with 2 forms. A MainForm with some buttons and login page. This login page provides us with an
access_token which we need to make Facebook API calls.
Our MainForm looks like this:
Figure 1: Application Main page

And in code behind we have the following handlers:
Important Update to Part 1In part one I described how to retrieve the access token (bug workaround). I did miss the
"expires" parameter in the code. This parameter is optional - but we can get it in the results so we have to get rid of it.
This
is the code to handle it:
Retrieving data
Our next step is to retrieve data from Facebook. The page loaded handler already enables the buttons when we are logged in, so we
can focus on handling the button events.
Let's start with the LoadUserData button.
In the Facebook graph_API documentation
(http://developers.facebook.com/docs/API) we learn that:
- All responses are JSON objects. We'll discuss this later.
- All objects can be accessed in the same way
- Objects are connected via relationships
- There is a special object named "me"
Let's take a closer look at point 2. The examples show links like https://graph.facebook.com/btaylor or https://graph.facebook.com/25190... This means we have to provide a name or an ID to access objects.
And for
point 3 we have links like https://graph.facebook.com/btaylor/friends. In simple words: these "relationships" are something like the basic
object link followed by a "subdirectory" which provides the subject we want to access.
Last not least (for point 4) the name (ID)
of the object (as in point 2) can be replaced with the special name "me". In this case we get access to logged in account. This will
mostly be our favorite object, since the user gave us (our Facebook application) access to his elements.
Finally point 1 tells us
that we will get all data as "JSON objects". JSON is a common format specification to transfer (store) objects. WCF services are also
capable to communicate using JSON formatted data. The good old ASP.NET Webservices used SOAP, an XML based format which produces (in
most situations) dramatically more "noise". So the overhead is much bigger than with JSON.
There are also other formats like BSON
or simply binary transfer - but that is a different story.
Let's focus on JSON. And the best way to do this is best done by
looking on what's going on.
Retrieving JSON with a browser
If we open the link https://graph.facebook.com/btaylor in the Internet Explorer we get a
message that the document type is unknown and are asked to store the result in a file.
For Firefox an addon called JSONView https://addons.mozilla.org/en-US/firefox/addon/10869/
can be installed. This displays JSON results in the browser window.
Calling https://graph.facebook.com/btaylor shows:
Notice the gender property - it reads "männlich" which is a localized version of the gender name. Since I
work on a German OS it shows the German name "männlich" (male). This is OK when we plan to display this information to our users - but
to check the result in our software it would be better to get a predictable result.
Retrieve "non localized" resultsOf course the results are always localized. But we decide the language and therefore
get consistent results.
To do this add the parameter locale=... to the URLs
When we call https://graph.facebook.com/btaylor?
locale=en_US we get:
So now we have "male" and can easily compare in our software.
By the way - do you remember the
access_token? It seems as if the calls do even work without this "magic value". And definitely a lot of the calls do work.
BUT - what we get is the "public data". If we add a valid access_token to the calls we'll get what we want (or to be
serious - what our Facebook application was asking for). We can check this by trying to retrieve btaylor's friends list https://graph.facebook.com/btaylor/friends
That's the (expected) result of such a call. For calls which are allowed in general (like access to btaylor's profile) we
get no error message; instead we get limited data.
So to get better results we need an access_token.
Filtering resultsThe Facebook graph_API provides ways to reduce the transferred data fields. Since transfer (last not
least) costs money we should always use that "filtering" to reduce the amount of data transferred over the network.
This is also
describe in the developer documentation:
To get what we want (our user data in this case) we will use a filtered query like this: https://graph.facebook.com/me?fields=id,name,gender,link,hometown,picture&locale=en_US
This brings us back to
our wp7 application.
Extend our FBUri class
Since we already have a nice class which provides methods to get our formatted URIs (inclusive parameters) we will extend this class
with a URI that will give us our profile data.
After adding a new URL and a method to get the URI including our access_token we can focus on data retrieval.
How to get data programmatically
There are different ways to get the data. In the first part of this article series we used a WebBrowser control. This was mandatory
since we must provide a form where the user can enter his credentials. And the idea behind this (maybe you remember) was - the user
enters his credentials at a Facebook page - we (our software) never see his username / password.
In the current case the things
are different. First we get (as you see when you open such a link in IE) the data in a "not browser suitable" way. And second - there
is no need to display something (like a form or so).
The easiest way to make such web calls is little class called "WebClient".
We know that the result of our calls will be a string which is JSON formatted. And using intellisense we find that the WebClient offers
a method DownloadString which takes a URI as parameter.
Your intellisense doesn't show DownloadString? That's
correct! Since we work in Silverlight there are no synchronous web calls. What we have to use is
DownloadStringAsync.
For those of you not familiar with Silverlight Web callsEvery web call in Silverlight is asynchronous. So the pattern
is to set up a handler for "...Completed" and then call the ....Async method.
In the handler you will either get an Error or a
"Result" which is exactly the same you would get with a synchronous call of the method.
Replace the btnGetUserData_Click handler in MainPage.xaml.cs with the following code:
Let's take a look at this code. First we define a WebClient. In our button handler we check if this thing is null. If so,
we create it and attach a completed handler.
Next we try to call DownloadStringAsync. We use a try / catch here since such calls
can fail without ever reaching the completed handler. A typical example is if you provide a wrong formatted URI.If the call is accepted
further errors (like host not reachable or error results from the called site) will be handled in the completed handler.
The
completed handler (for the moment) simply checks for errors. If no error occurs we'll display the result in our UI (the blue text at
the end of the form) and (if you debug the application) in the VS output window.
This is what a result might look
like:
Here another result:
Exactly what we've been asking for. Notice that the second result contains "hometown" which is also an object inside the
"outer object" (curly brackets surround objects). The reason for this difference - Nina did not fill "hometown" in her user profile,
while I did. So always expect the absence of values / properties in Facebook results.
Further this is a simple string - what we
need in our .NET world is a class. Since the JSON structure is pretty easy we could write a parser but the good news we will get one
for free.
You remember, before I mentioned that WCF also supports JSON data. And (I didn't mention but treat it as fact)
Silverlight has building WCF support. So there must be some kind of Serializer which can handle JSON data.
JSON Serialization
Sherlock:It is there Dr. Watson let's use it
Watson:How can we find it Mr. Holmes?
Sherlock:We know it is a
Serialzer...
Watson:already search System.Runtime.Serialization - I could not find it Mr. Holmes!
Sherlock:We know it has
some relation to Web Services - did you check System.Servicmodel.Web?
Watson:Just a moment - I added a reference, but I find
nothing in System.Servicemodel.Web!
Sherlock:It is a Serializer - try System.Runtime.Serialization...
Let's follow Dr.
Watson and add a reference to System.Servicemodel.Web to our project. Next place your cursor somewhere in the completed handler and
type System.Runtime.Serialization. Intellisense should pop up and in the List you should find Json. Select it and next you should get a
class called System.Runtime.Serialization.Json.DataContractJsonSerializer.
This is the class we have been searching for.
But what does "DataContract" mean? If you work with WCF you will learn that there are a lot of contracts. And a DataContract is simply
a contract which defines how data "looks" (it's a bit more but we don't care here) - or for our need how it should be
serialized.
Namespaces in different assembliesIt is normal to extend (provide) some functionality in "related"
assemblies.
In the Serialization case we have System.Runtime.Serialization which is extend by Json.
Since Json is
(primarily) used in Web Services the System.Runtime.Serialization namespace is extended in the System.Servicemodel.Web assembly.
To define / use Data contracts we also need a reference to the System.Runtime.Serialization assembly. So add a reference to
the project.
As mentioned above we want to have the user data in a class. We already have a folder HelperClasse - add a new class
to it - FBUser. Next we will analyze the data we WANT to get from Facebook and build properties for in our class. You remember, Name,
Link, Picuture, Gender and Hometown are the elements what we are looking for. And for further calls to the API the ID would also be
good to have.
But before we do this let's take a look at the data we got from our Facebook API call.
Notice two things - the ID of our user is surrounded by quotation marks while the field id in hometown is not! In our
case this doesn't matter - but for other calls this may be relevant. "values" are strings while values without quotation marks are
numbers. So let's build the properties - but doing this we will change the names to get a "good looking notation".
Notice 2 things. First (for the sake of "simple code") I built a contained class named "FBHomeTown". Next I made the
properties "null proof". You remember that the Facebook API doesn't return anything if a property is not set in the user account. This
means that we always have to check if a value is present or not. Assume we want to check if the Hometown name is "Linz". With this
"null proof" approach we can simply write:
Else we would first have to check if HomeTown is null, further we must check in Name
is null and so on.
Now that we have our class the serializer must be able to assign values to it. Of course
it has no chance to find the members since we gave them different names. But this is where the contract takes place.
We can add
contract attributes to our class. They inform the serializer about the relations between our class and the data (JSON). Finally our
class looks like this;
Notice that the contained class FBHomeTown also has a DataContract attribute. Every property has its
special DataMember attribute with a Name= parameter. There we fill the names we found in our JSON
data.
We are almost done with JSON - the only thing left is de-serialization. Using intellisense we learn that a
DataContractJsonSerializer has a method Read which takes a stream as parameter. We (unfortunately) have a string with
JSON data. To handle this we will build our own JsonStringSerializer. Add a class to our "HelperClasses" directory and name it
JsonStringSerializer. To provide more flexibility we will add a generic method which returns a de-serialized class. As parameter we
pass the strings we get from our Facebook API calls. The method looks like this:
This method creates (depending on the generic type) a DataContractJsonSerializer. Next it uses the string to create a
memory stream which will be passed to the ReadObject method. Notice that we use Encoding.UTF8 to get the bytes of our
string. If your "JSON service" uses a different encoding you would have to change this.The Facebook API sends data UTF8 encoded - so we
use it here.
Let's stick the things together. In the first part of this series we already built our MainPage UI. The interesting
part (for now) is the Grid named fbUserGrid:
First we have a "headline" - User Date. Then we have an image control which is bound to "PictureLink". "PictureLink"
sounds familiar, doesn't it? YES - it is the name of one of our FBUser class properties. The same we have for Name, Gender and
HomeTown.Name. For the last binding: it is possible to bind (as the name tells) a path not only to a property. So here we
bind to the HomeTown property of our FBUser and in this class to the member Name.
To bring in our FBUser instance we simply bind
it to the grid. And the controls will then bind to the elements of the object which is bound to the grid.
Let us change our
completed handler. Be aware that binding could fail, so we try / catch this also.
Notice that the FBUser member is defined static! Do you know why I did this?
I mentioned in part one that the
navigation framework creates / destroys pages when we navigate. In this case if we (for an example) navigate to the "Friends list" our
MainPage is destroyed. When we navigate back we get a brand new MainPage - unfortunately without our FBUser.
Navigation - YES we
also have to handle this - bring back our FBUser to Grid binding. Change the Loaded event handler to:
The last line binds our FBUser to the grid. If it is null (we didn't load it) simply no data is displayed.
Time to
run our project! Login, click "Load User Data" and you should see something like this:
Figure 2: MainPage with user data

Looks good, doesn't it?
If you answer the question with NO -
right click on your project in the VS Solution Explorer and choose "Open in Expression Blend..." - make your design changes
there.
Retrieving (more) complex data
Since we have done our first simple data retrieval let us expand this a bit by loading a list of our friends.
Before we go
into details add a new URI to our FBUris class. Add the following lines:
Next add a new "Windows Phone Portrait Page" to the project. Name it PGFriends. To open the page change the button
handler in MainPage.xaml.cs to:
By the way - you can try to change the "static FBUser" to non static and run the application. You'll see that after you
open PGFriends and come back to MainPage that the user data is lost.
Retrieve the friends list
Above we have seen that the Facebook API provides "relations". This is exactly what we need in this case. And we also have seen that
a call to the "friends relation" needs an access_token. We already have a function for this in our FBUri class and further
we know that a WebClient is what we need to make an API call. And since our page shall provide us with a friends list the only thing it
should do is to obtain the list and show it. So there is no need for buttons or whatever. The page loads - we get the list and display
it - done. This and the knowledge we have from retrieving our user data we can simply add the needed code to our PGFriends.
Add a loaded handler simplifiedDouble click somewhere in the blank space of the form in the "Page
Designer".
This will add a PageLoaded handler.
First add a "Loaded" event handler than write (copy) the following code:
This looks pretty the same like the code we use to load our user data. But since we don't know what we will get and how
to display it we simply write the results to the VS output window (for the moment).
Let's run the application and see what we
get. It is a good idea to place a breakpoint at the line where we get the result, so we can inspect the data there. What we get is
something like this:
This is our friend list. All data here is public - except the fact that they are a friend of mine. In other words, what I
get is a part of the public data. The access_token is needed to get the list. So what we get is no "secret" at all. The
only protected thing is the list itself. Anyhow I've hidden some of the data (ID's and Name) except for my relatives. Notice a thing
about the name there is a "name": "xxx Pfl\u00fcgl", this is encoded and will extend to an umlaut.
We get a "something"
containing FBUser objects. Of course the object do only contain two elements this should not irritate us - we know Facebook result can
have "missing properties".
More interesting is how we get the list. If we "read" JSON it says we get:
- An object with a
data property
- The
data property is something enclosed in square brackets []
- In the brackets we find FBUser objects
This is how JSON represents Arrays. So to de-serialize our data we need a class that has a property "data" which is a FBUser
object array.
OK, let us add a new class in HelperClasses and name it FBFriends (notice the plural):
I tend to say building this class was not really a hard job.
Display the friends list
Now let's display our friends in a nice list. I imagine a list with the user image (profile picture) and the name in a second
column. The problem - we only got Name and ID in our list. So the "PictureLink" of our FBUser object is empty.
Luckily Facebook
provides separate link to access profile pictures. All you need to know is the ID of the user.
The link is: http://graph.facebook.com/ID/picture So let us extend our FBUser class
with a property for this.
Notice this property is read only and needs no DataMember attribute since it is not serialized.
There
is another thing we know - Facebook profile pictures have a dimension of 57x57 pixels. Knowing this we can easily create a ListBox with
"good looking" entries. Open PGFriends and add the following markup to the ContentGrid:
Again I added the well known info section at the bottom of the page. For the ListBox I provided a template which is a
grid with a line height of 80 (to get margins) and in the first column an Image with the Height 60. This is bound to the new FBUser
Property "PicLink".
Further notice that I bound the ItemsSource to the path "Friends" (which is the array in our FBFriends
class). So we simply have to set the Listbox's DataContext to an object of the type FBFriends.
The final code also changes the
Debug.WriteLine to a more useful display in the two information lines on the bottom of our page.
Of course we could cache our friends or do other optimizations. But to simply obtain and display the list this is all we
need to do. And here is a part of the result:
Figure 3: A part of the Friends List

Notice here that the "name": "xxx Pfl\u00fcgl", was translated to an
Umlaut. And also notice that my daughter didn't correctly rotate her profile picture.
Sending data
The final thing is to post to our wall. To do this we should know that:
- A post (feed entry) has some "special sections"
- The data must be "posted"
- The result is the id of the new post
I'll not explain the sections of a wall post in detail. You can find this in the Facebook API documentation. Or better learn it
by analyzing a self made post.
To post let us first create a new page. Add a new "Windows Phone Portrait Page" to the project.
Name it PGPost. To open the page change the button handler in MainPage.xaml.cs to:
And before I dive deeper in how to post to the wall let us build the UI for the PGPost page. Change the ContentGrid
to:
Please do not forget to add the button handler (just delete the text - type a blank and follow intellisense). Notice 2
things here:
- We bind data to the controls
- We use "Mode=TwoWay" in most cases
And this is what the page should look using this markup:
Figure 4: The Post Page

To enable easy data-binding we will create a class which represents a wall post. Add add new
class to our HelperClasses directory and name it FBWallPost - change the code to:
Here you can see the possible values of a wall post. These values have to be sent to the Facebook API. We have to do the
same what Facebook does - if a property has no value - don't send it. The data must be sent in a format similar to the other parameters
we passed till now. With one little difference - but that comes later.
First let us write a function which returns such a "query
string":
Notice that:
- The parameter
access_token is not preceded with an ampersand or a question mark.
- Every parameter (except the
access_token which we never "decoded") is UrlEncoded
- If a property is empty - we simply do not add it to the result string
What we have to do now is to create such an object, bind it to our grid and when the user presses the send button we simply
call this method to create our "well formatted" data we will send to Facebook.
First we add a loaded event handler to our page
and add the following code:
We also added our well known UpdateUI function. Notice that I call the FBWallPost constructor with true -
which produces sample data. So we don't have to fill the form by hand just to see how posting works.
Of course our FBUris class
needs to be extended with the "post to wall" method. Add the following lines there:
Notice that we don't pass the access_token like we did in the prior methods. I wrote above that there is a
difference between the former called functions and writing a post to the wall. Here it comes!
While the data we sent before was
very limited (in the meaning of amount / size), a wall post can be pretty large. This means it could exceed the "maximum URL length".
So data must be passed in a different way. What we did till now was (from a HTTP perspective) a GET operation. GET operations transfer
their data directly via the URL. The rule - after the address follows a question mark, followed by a list of name / values pairs
separated with an ampersand.
Above (describing the GetPostParameters method) I asked you to notice that
access_token is not preceded with a question mark (or an ampersand). The reason is that that question mark is specific to the GET
operation.
In our case we will use a different operation - called POST. Here the data is transferred in the HTTP headers. This
eliminates the "URL length limit". And it means that Address and data are no longer one "string". Instead we have the URI and the data
as two parts of the call. That is why GetPostMessageUri only returns a native address and doesn't need the access_token.
This is instead provided via the GetPostParameters method of our FBWallPost class.
Data binding was set two "TwoWay
mode" which means that what we type is transferred back to the bound object. So all we have to do is send what the object contains.
Let's do this by changing the button event handler in our PGPost page:
Notice that we now use a different method of the WebClient class. Instead of DownloadStringAsync we use
UploadStringAsyn. Therefore (of course) we have to handle a different completed event.
And notice further that
UploadStringAsync has a second parameter where we provide the data transfer mode - POST in this case - and the data
values are passed as third parameter.
When we run the application and post to our wall we can check the results by visiting our
Facebook home page. Let's run it and check (without changing any data in the form) the results:
Figure 5: Facebook post made with our wp7 application

Notice the little rectangle in
front of "about a minute ago..." This can be replaced with an icon. You can change this in the application settings at http://www.facebook.com/developers/
Further the image as well as
"Testname" are linked to the link you provide with your post. And last not least the text "NinasFirstApp" is linked to the "application
page". It is something like a normal Facebook page. You can customize this page to provide further information about your
application.
This is the end
So finally we reached the end of our series. There are much more operations available in the Facebook API. But they are all very
similar to what we have done here. Check the "call URL", provide a test call and analyze the results. Write your classes for the
results - implement the JSON data contract - done.
What is left?
In general this example contains most of the things you need to know if you want to write a wp7 application that interacts with the
Facebook API. But there are some pitfalls in the API. You will stumble into one of them almost for sure (if you do more than what we
have done here). But hopefully other developers had the same problem and there is already a solution on the web. One (very famous)
pitfall is the "logout".
I only must enter my credentials onceYou may have notice that after the first run of your application the login page
simply loads some pages and tells that it is logged in.
Restart the simulator - and you get asked for credentials
again.
Keep your app closed for several hours (>2) and you are also asked again.
The reason for this - Facebook caches
your credentials in cookies on the client and automatically redirects you if they access_token is still valid or if the user choose
"remember me" at logon.
There is a "logout page" - which finally doesn't work. In general it works - but only if you delete some
"forgotten cookies".
Wp7 provides no access to the cookies of your app - so this fails. But there is hope! Redirect the user
to:
string strLogoutURL2 = "http://m.facebook.com/logout.php?confirm=1&next=" + HttpUtility.UrlEncode
("http://www.facebook.com");
wbLogin.Navigate(new Uri(strLogoutURL2, UriKind.Absolute));
You will reach a page with the
address http://touch.facebook.com/login.php From here close your
"logout page" or navigate to the "Facebook API Login page" as we did before.
There are plenty of other things left - good design, perfect error handling, a good pattern (MVVM, MVC, ...) for data / UI
separation, animations, automatic navigation and so forth.
Just start with the login page - there is already (commented) code
which redirects the user back after he authenticate our Facebook application. A potential enhancement would be a in-between page which
just displays some kind of "welcome my friend" which disappears after some time.Meanwhile you could fetch the user data (and / or)
friends list in a background thread...
Resources
The wFace – windows phone 7 facebook integration Series
This article series shows how to use the Facebook graph_API (http://developers.facebook.com/docs/API) in a windows phone 7
(wp7) Silverlight application. All used tools are free software - for downloads take a look at the links at the end of this
document.
Part1
Part2
Part3
About Manfred Pohler
 |
Sorry, no bio is available
This author has published 5 articles on DotNetSlackers. View other articles or the complete profile here.
|
Please login to rate or to leave a comment.