If you haven’t heard, Microsoft and Clarity Consulting have released version 3 of the Facebook Developer Toolkit (FDT). As described on the Codeplex home page the main goals for version 3 were:

Provide better doc and samples
• Provide support for Silverlight
• Provide support for ASP.NET MVC
• Provide improved support for WPF
• Provide improved support for FBML (FBML Server Controls)
• Provide a login control that can be used to replace the BasePage and/or MasterPage for Canvas Development
• Improve out of the box support for Extended Permission Prompts
• Refactor core source to improve maintainability and design
• Fix known bugs

Although several great examples are shipped with the latest version of FDT, none of them target authenticating users via Facebook Connect on ASP.NET MVC apps. Luckily, you’ll find that ASP.NET MVC apps aren’t all that different from Web Form apps in this regard.

Goals

  • The goals of this contrived example are:
  • Host a “Connect with Facebook” button in the Index view of our HomeController.
  • Popup the Facebook Connect page when the button is clicked.
  • Upon successful login, redirect back to the AuthenticateFacebook action on the HomeController so we can verify the user is in fact logged in and grab some user info.
  • Redirect to the About view on the HomeController and display some personal information from Facebook Connect.

Assumptions

Before we begin, I’m going to make the following assumptions:

  • You’ve already created an ASP.NET MVC project with which you want to authenticate users via Facebook Connect
  • You’ve already downloaded FDT 3 and added a reference to Facebook.dll to your ASP.NET MVC project
  • You’ve already created a Facebook application using the Developer application on Facebook.
  • You’ve made a note of your Facebook application’s API Key and Application Secret.

Index View

Setting up the Index view is a pretty trivial task. The first order of business is to add a reference to the Facebook JavaScript file. Simply add this to the <head></head> tag of your view (or most likely your master page):

Code Snippet
  1. <script src="http://static.ak.connect.facebook.com/js/api_lib/v0.4/FeatureLoader.js.php" type="text/javascript"></script>

The next thing we need to do is add the Facebook Connect button on the view:

Code Snippet
  1. <a title="Facebook" href="#" onclick="FB.Connect.requireSession(function(){window.location='/Home/AuthenticateFacebook';}); return false;"><img alt="Connect with Facebook" src="http://static.ak.fbcdn.net/images/fbconnect/login-buttons/connect_light_large_long.gif"></a>

Notice how the FB.Connect.requireSession accepts a function which is what happens upon a successful login by the user. In this instance we’re redirecting the browser to the AuthenticateFacebook action on the HomeController, but you can change this to whatever you like.

The last thing we need to do is add the required FB.Init JavaScript call at the very bottom of our Index view:

 

Code Snippet
  1. <script type="text/javascript">
  2.     FB.init('00000000000000000000000000000000', 'XdReceiver');
  3. </script>

As stated on the Facebook Developer Wiki, this call safely initializes the Facebook API for use on a Connect site or iframe application. The first parameter is your application’s API key, while the second URL of our cross domain communication channel file which we’ll be creating next.

XdReceiver

For security reasons, web browsers restrict web sites from making AJAX calls across domains. In general this is a very GOOD thing but can be a bit of  a headache when trying to integrate your site with an external site. Hoverever, there are ways around this – in Facebook’s case they use an iframe (i.e. XdReceiver). You can read all the gory details about it here.

Setting up our XdReceiver involves two simple steps. First, open up HomeController.cs and add the following action:

Code Snippet
  1. public ActionResult XdReceiver()
  2. {
  3.     return View();
  4. }

Next, add a view named XdReceiver to the Home folder in your Views folder - be sure to uncheck the Select master page on the Add View dialog. Replace the entire contents of the view with the following:

Code Snippet
  1. <%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage" %>
  2. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
  3. <html xmlns="http://www.w3.org/1999/xhtml">
  4.     <body>
  5.         <script src="http://static.ak.connect.facebook.com/js/api_lib/v0.4/XdCommReceiver.js" type="text/javascript"></script>
  6.     </body>
  7. </html>

AuthenticateFacebook Action

Up until now we’ve been laying the foundation for our Facebook Connect application - now onto the good stuff! The AuthenticateFacebook action on the HomeController is where all the magic happens.

Code Snippet
  1. public ActionResult AuthenticateFacebook()
  2. {
  3.     
  4.     ConnectSession _connectSession = new ConnectSession("00000000000000000000000000000000", "00000000000000000000000000000000");
  5.  
  6.     if (!_connectSession.IsConnected())
  7.     {
  8.         // The request does not contain the details of a valid Facebook connect session - you'll probably want to throw an error here.
  9.     }
  10.     else
  11.     {
  12.         // Authenticated, create API instance.
  13.         Api _facebookAPI = new Api(_connectSession);
  14.  
  15.         // Load user.
  16.         user user = _facebookAPI.Users.GetInfo();
  17.  
  18.         string fullName = user.first_name + " " + user.last_name;
  19.         DateTime dob = DateTime.ParseExact(user.birthday, @"MMMM d, yyyy", System.Globalization.DateTimeFormatInfo.InvariantInfo);
  20.         long userId = _connectSession.UserId;
  21.  
  22.         TempData["FullName"] = fullName;
  23.         TempData["Dob"] = dob;
  24.         TempData["UserId"] = userId;
  25.  
  26.         return RedirectToAction("About", "Home");
  27.     }
  28.  
  29.     return RedirectToAction("Index", "Home");
  30.     
  31. }

For the most part, the AuthenticateFacebook action is straight forward. We first create a ConnectSession using our API Key and Application Secret. If the user was successfully authenticated the session will be connected which means we can then create an instance of the Api and use that to access information about the user. In this case, we’re retrieving the user’s name, date of birth, and user id and then redirecting them to the About view on the HomeController.

About View

The about view simply displays the user’s name, date of birth, and user id that we stuffed into the TempData collection.

Code Snippet
  1. <%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>
  2.  
  3. <asp:Content ID="aboutTitle" ContentPlaceHolderID="TitleContent" runat="server">
  4.     About Us
  5. </asp:Content>
  6.  
  7. <asp:Content ID="aboutContent" ContentPlaceHolderID="MainContent" runat="server">
  8.     <p><%=TempData["FullName"]%>, you were born on <%=TempData["Dob"]%> and your Facebook user ID is: <%=TempData["UserId"]%></p>
  9. </asp:Content>

Conclusion

Hopefully this sample shows you just how easy it is to add Facebook Connect to your ASP.NET MVC. In a real world application you’ll probably want to create a user account in your site’s membership system (Membership Provider for instance) and then map the user’s Facebook Connect user id to your site’s user id.

I’ve zipped up a sample which you can download here: MvcFBConnectSandbox.zip