A few weeks back I wrote about the official C# SDK from Facebook and provided some sample code demonstrating how to use it to get some basic information about the logged in user. Admittedly the initial sample asp.net mvc code was fairly simple in order for it to be straight forward and easy to understand. I’ve decided to expand a bit on the sample in order to demonstrate how to use the Open graph API to perform a few more interesting calls, notably:

  • Post to a user’s wall
  • Retrieve a list of the user’s friends
  • Retrieve a list of the user’s activities

The original sample code demonstrated how to authenticate a user and make calls using both the official C# sdk and a home grown solution. I’ve kept that approach but have organized and refactored the samples a bit better to make it hopefully more clear. The new version of the sample code allows you to login/out to facebook only on the home page. Once logged in you can go to the ‘Official’ and ‘Custom’ tabs to view your friends, activities or to post a message to your wall. While the functionality is the same between the two tabs, the code behind them is different. I assume most people would use the official SDK but I provided an alternative just as a point of interest. OK, I was bored really, and just wanted to see how it could be done differently.


In any case, the first step before running the code is to make sure you clear any previous permissions granted to this app (or whatever app you will be using with the sample code). The login button on the home page now requests extended permissions so you’ll probably need to remove it from your list of allowed applications if you’re running the latest code with a facebook app that was using the original sample code. The actual list of permissions being request are perms=’read_stream,publish_stream,read_friendlists,user_activities’, and the full list of permissions available can be found here http://developers.facebook.com/docs/authentication/permissions.

Official C# SDK

The code to use the Facebook API can be found in the OfficialFacebookController. By default index view will simply show the name of the logged in user, which uses the same code present in the HomeController (and the original post<)

string token = HttpUtility.UrlDecode(fbConnect.AccessToken);
FacebookAPI api = new FacebookAPI(token);
JSONObject me = api.Get(“/” + fbConnect.UserID);
ViewData["Name"] = me.Dictionary["name"].String;

There are three other actions a logged in user can take here, view their friends list, view their activity list, and post a message to their wall.

  1. Clicking the Get Friends button will call the GetFriends action in the controller. The call is simply api.Get("me/friends"), which returns a dictionary with a data key and an array of JSONObjects, representing all of the friends for the user. You could also call it with something like, api.Get("/" + fbConnect.UserID + "/friends"): "me" just uses the currently logged in user.

    Facebook.FacebookAPI api = new Facebook.FacebookAPI(token);
    JSONObject me = api.Get("/" + fbConnect.UserID);
    JSONObject friendsData = api.Get("/me/friends");
    var data = friendsData.Dictionary["data"];
    List<JSONObject> friendsList = data.Array.ToList();
    
    ViewData["Name"] = me.Dictionary["name"].String;
    ViewData["Friends"] = friendsList;
    

    The data itself is just the name and facebook id of the user's friends, so the view just loops through the friendsList collection and displays in this format Name - Id

    <%= friend.Dictionary["name"].String %> - <%= friend.Dictionary["id"].String %>
    

  2. Similarly, clicking the Get Activities button will call the GetActivities controller. The code is pretty much the same as the above friends code, but calls api.Get("/me/activities");. The data is also slightly different, since the activity data contains more information (such as category, and create_date). So, the view follows pretty much the same format but displays more fields:

    <%= activity.Dictionary["name"].String%> - <%= activity.Dictionary["id"].String%>- <%= activity.Dictionary["category"].String%>- <%= activity.Dictionary["created_time"].String%>
    

  3. Finally, the message section allows the user to enter a message and post it to a user's wall. Entering text and clicking the Post Message button will call the PostMessage action. Instead of calling the Get method of the FacebookAPI class, we call Post:

    Dictionary postArgs = new Dictionary();
    postArgs["message"] = message;
    JSONObject post = api.Post("/" + fbConnect.UserID + "/feed", postArgs);
    

    The post call also returns a JSONObject which contains the id of the new post. Just for verification, we show this in the view.

Custom C# classes

The display of the custom code looks pretty much the same as the official sdk, so I won't post any images of the views. The primary classes involved are FacebookConnect.cs, FacebookObjects.cs and OpenGraph.cs. Note that compared to the original sample code I've removed the "DEMO" prefix and added a few more methods to OpenGraph, renamed the DEMOFacebookUser to FacebookObjects, and added objects to FacebookObjects.cs. These serve as the definition for our extra calls

You might also notice in FacebookObjects that the DataContract and DataMember attributes have been removed from FacebookUser. One of the more significant changes is the way in which the Call method in the OpenGraph class works. Initially it was using the DataContractJsonSerializer class, which required you to mark your class and it's properties with DataContract and DataMember attributes. However, this serializer seems to have some issues parsing certain JSON strings. So instead I've changed the code to use the JavascriptSerializer which seems to work just fine. In fact it's more flexible and seems to take less configuration than DataContractJsonSerializer, which is why it was probably undeprecated (dedeprecated?). In addition to the use of JavascriptSerializer, the Call method also takes an additional parameter to specify the type of http request made. This allows us to use the same code to make a POST request, which is necessary when writing to a user's wall. The new Call method looks like this:

private T Call<T>(string url, string methodType) where T : class
{
	T result;
	HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
	request.Method = methodType;

	using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
	using (StreamReader reader = new StreamReader(response.GetResponseStream()))
	{
		JavaScriptSerializer jsSerializer = new JavaScriptSerializer();
		string jsonData = reader.ReadToEnd();
		result = (T)jsSerializer.Deserialize<T>(jsonData);
	}

	return result;
}

The various Get/Post methods in the OpenGraph class are pretty similar to the original GetCurrentUser method and rely on the objects defined in the FacebookObjects.cs file. For example, the GetCurrentUserFriends looks like the following:

public List<FacebookFriend> GetCurrentUserFriends(string accessToken)
{
	string parameters = "me/friends?access_token=" + accessToken;
	string url = baseUrl + parameters;

	FacebookFriendData call = Call<FacebookFriendData>(url, GET);

	return call.Data;
}

The action just needs to call this method with a valid access_token. For example, the GetFriends action in CustomFacebookController, calls the following:

List<FacebookFriend> friends =  openGraph.GetCurrentUserFriends(fbConnect.AccessToken);

Once this has been placed into the ViewData dictionary, we can just pull it out and iterate through it like so:

<%
	List<FacebookSampleMVC2App.FacebookFriend> friendsList = ViewData["Friends"] as List<FacebookSampleMVC2App.FacebookFriend>;
	foreach(FacebookSampleMVC2App.FacebookFriend friend in friendsList) {
%>
	<%= friend.Name %> - <%= friend.Id %><br />
<%  } %>

The logic/view for retrieving the user's activities and posting to the user's wall are fairly similar.

Wrap up

So there you have it, some sample code to do a bit more than just display the user's name and facebook id. The custom classes and the official sdk are pretty similar in the sense that they both just call REST methods like 'me/friends', 'me/activities' and 'me/feed' from https://graph.facebook.com/. The official SDK is more flexible however, since it doesn't need to have classes defined for each of the types, instead relying on JSONObject to wrap the dictionaries/arrays/scalars returned from the api calls.

Download the code here

Update - 11/15/2010

I recently updated the sample project with more samples, which can be viewed here: http://onishimura.com/2010/11/15/facebook-c-and-asp-net-mvc-updated-code-samples-for-places-wall-offline-access/