The big news a couple of weeks ago was the opening up of the Facebook Places API and launching a Deals Service as well. The Places API is pretty straightforward to work with so I’ve updated the Sample MVC App to show an example of calling it, specifically getting a user’s checkins and search for places given a search term, latitude and longitude, and distance. I’ve also had a few requests to show a few other calls, so I’ve included a sample for displaying a user’s wall (feed) and how to use offline_access to retrieve a user’s wall even when they aren’t logged in. Additionally, I’ve refactored some of the code a bit to be a little cleaner, but I’ve only written samples using the official C# SDk (I assume thats what everyone’s using at this point).
Setting the proper extended permissions
We’re going to be using two new extended permissions here, checkins and offline_access, so the first change we need to make is in Home/Index.aspx.
<fb:login-button autologoutlink='true' onlogin='window.location.reload()' perms='read_stream, publish_stream, read_friendlists, user_activities, user_checkins, offline_access'></fb:login-button>
The first time you log in after making these changes you should get prompted with a confirmation dialog from facebook.
Places and checkins
The code to get a user’s checkins unsurprisingly makes a call to the Facebook Checkin service
public ActionResult GetCheckins()
{
JSONObject checkins = helper.Get("/me/checkins");
if (checkins != null)
{
var data = checkins.Dictionary["data"];
List<JSONObject> checkinData = data.Array.ToList<JSONObject>();
ViewData["Checkins"] = checkinData;
}
ViewData["Name"] = Session[Constants.FacebookNameKey];
ViewData["isConnected"] = helper.IsConnected;
return View("Index");
}
The structure of the returned data is as follows:
{
"data": [
{
"id": "CheckinID",
"from": {
"name": "UserName",
"id": "UserId"
},
"place": {
"id": "PlaceId",
"name": "Giants World Series Victory Parade Route",
"location": {
"latitude": 37.78627395,
"longitude": -122.40441083333
}
},
"application": null,
"created_time": "2010-11-03T19:45:31+0000"
}
]
}

Note that the data set returned from a call to the checkins api will be paged. I’ve only ever checked in once, hence the single item in mu list.
The search call is somewhat different since you need to have 4 parameters set, the query term, the latitude and longitude of the center of the lcoation, and the distance from the center to use (the 5th parameter, ‘type’ is just set to ‘place’ in the code below). I’ve provided some sample data (which is just the sample data used in the Facebook example), which can be loaded by pressing the ‘Load Test Data’ button. If you want to test a different address and need to find a valid lat/long setting, you can use http://geocoder.us/ to convert an address.
public ActionResult SearchPlaces(FormCollection form)
{
Dictionary<string,string> parameters = new Dictionary<string,string>();
parameters.Add("q", form["q"]);
parameters.Add("center", String.Format("{0},{1}",form["lat"], form["long"]));
parameters.Add("type", "place");
parameters.Add("distance", form["distance"]);
JSONObject searchResults = helper.Get("/search", parameters);
if (searchResults != null)
{
var data = searchResults.Dictionary["data"];
List<JSONObject> places = data.Array.ToList<JSONObject>();
ViewData["Places"] = places;
}
ViewData["Name"] = Session[Constants.FacebookNameKey];
ViewData["isConnected"] = helper.IsConnected;
return View("Index");
}
Nothing fancy about the returned data either, it’s pretty similar to the data for the checkin. One thing to note though is that the location item may not have an address associated with it, so you need to account for that when working with the data (the sample just checks for the existence of the ‘street’ key in the location array).
{
"data": [
{
"name": "Philz Coffee",
"category": "Local business",
"location": {
"street": "4023 18th St",
"city": "San Francisco",
"state": "CA",
"zip": "94114-2501",
"latitude": 37.760863,
"longitude": -122.433326
},
"id": "151116474914629"
},
{
"name": "Ritual Coffee Roasters",
"category": "Local business",
"location": {
"latitude": 37.75659,
"longitude": -122.4211
},
"id": "119185971453428"
},
...
]
}

Retrieving a user’s wall
The previous iteration of the sample including an example on how to post to a user’s wall, so getting a user’s wall is a natural corollary. Getting a user’s feed is accomplished by making a call to ‘me/feed’
public ActionResult GetWall()
{
JSONObject wallData = helper.Get("/me/feed");
if (wallData != null)
{
var data = wallData.Dictionary["data"];
List<JSONObject> wallPosts = data.Array.ToList<JSONObject>();
ViewData["Wall"] = wallPosts;
}
ViewData["Name"] = Session[Constants.FacebookNameKey];
ViewData["isConnected"] = helper.IsConnected;
return View("Index");
}
The returned data can differ depending on the type of the wall post, so when working with the data you just need to check for the presence of the appropriate dictionary keys before trying to use it. For example:
<%
foreach (Facebook.JSONObject wallItem in wallPosts)
{
string wallItemType = wallItem.Dictionary["type"].String;
if (wallItemType == "photo" || wallItemType == "video")
{
%>
<li><% if (wallItem.Dictionary.ContainsKey("name")) { %><%= wallItem.Dictionary["name"].String%> <% } %> (<%= wallItemType %>) <br /> <a href='<%= wallItem.Dictionary["link"].String %>'><%= wallItem.Dictionary["link"].String %></a></li>
<% }
else if (wallItemType == "status") { %>
<li><%= wallItem.Dictionary["from"].Dictionary["name"].String%> <br /> <%= wallItem.Dictionary["message"].String%></li>
<% } %>
Note that a picture or video may or may not have a name so you’ll need to check for that as well.

Offline Access
The offline_access extended permission is pretty cool, it basically extends the life of the access_token you receive after logging in via OAuth. The example I wrote just stores this in a cookie (named FacebookAccessToken) the first time you log in with your account. Normally you’d want to store this in a database or some other more permanent store.
public ActionResult GetOfflineWall()
{
if (HttpContext.Request.Cookies[Constants.TokenCookieName] == null ||
String.IsNullOrEmpty(HttpContext.Request.Cookies[Constants.TokenCookieName].Value))
{
return View("Index");
}
JSONObject wallData = helper.GetWhileOffline("/me/feed");
if (wallData != null)
{
var data = wallData.Dictionary["data"];
List<JSONObject> wallPosts = data.Array.ToList<JSONObject>();
ViewData["OfflineWall"] = wallPosts;
}
return View("Index");
}
The GetWhileOffline method beind used there just takes the access_token out of the FacebookAccessToken cookie and uses that when instantiating the FacebookAPI object…(in FacebookHelper.cs)
public JSONObject GetWhileOffline(string apiCall)
{
JSONObject jsonObject = null;
if (HttpContext.Current.Request.Cookies[Constants.TokenCookieName] != null ||
!String.IsNullOrEmpty(HttpContext.Current.Request.Cookies[Constants.TokenCookieName].Value))
{
string token = HttpContext.Current.Request.Cookies[Constants.TokenCookieName].Value;
token = HttpUtility.UrlDecode(token);
Facebook.FacebookAPI api = new Facebook.FacebookAPI(token);
jsonObject = api.Get(apiCall);
}
return jsonObject;
}

Thats really all there is to it, as long as you have the extended permission ‘offline_access’ and an access_token that was created when a user logs in after granting this permission, you should be able to make offline calls.
[...] Facebook, C# and ASP.NET MVC – Updated code samples for places, wall and offline access [...]
[...] This post was mentioned on Twitter by Justin Soliz, onishimura. onishimura said: Facebook, C# and ASP.NET MVC – Updated code samples for places, wall and offline access http://bit.ly/cGAOpL [...]
Hi,
Can you make a sample for silverlight using the 4.0.2 version of “facebook c# sdk”
I have tried by downloading the latest code of the sdk which has samples, but i can’t get the silverlight facebook.dll to build and when i link the samples to the 4.0.2 version of the DLL, the sample will not compile because they made changes to the SDK for calling the API.
I think a lot of people would appreciate this.
Best Regards,
Peter
Hi, I’ve been trying to get your sample to run pointing to my appId with no luck. I’m able to log in but don’t have the accessToken in the Index action after logging in. The only thing that I changed was the appId so I’m guessing I don’t have my facebook app setup correctly. Any change you can tell me how you have the facebook app setup?
Thanks, wyatt
Great article and helpers.
I noticed that the GetCurrentUser method in the OpenGraph class has the attional param and value “field=picture” on the graph call. This will just return the picture. and not the user info. remove that param and the user is returned.
maybe this changed on the graph since publishing.
Good work
This is a nice article..
Its very easy to understand ..
And this article is using to learn something about it..
c#, dot.net, php tutorial
Thanks a lot..!
thanks very much for this. i’ve been using the heavier-weight Facebook library on Code Project and it’s good to see an end-to-end example in MVC using the FB C# SDK. appreciate you sharing.
Hey,
Great stuff you got here, Helped me a lot!
However couldn’t seem to figure out how to change the name of the app from SampleMVC to something else..
thanx for the wall post idea, but do u by any chance know how to get the news feed too…this post tells us only about out wall post…
thanx again
Great Work!
I am unable to open the Sample MVC2 app.. the Facebook API app opens fine. I am running Windows 7 on a 64 bit machine with
- .NET 2.0 – 4.0
- MVC 1 – 3
- All Windows updates…?
Any suggestion?
Thanks