Kevin Marshall's Epic Work Blog for Awesome People

@ksmarshall - i <3 software
in

Facebook Developer Toolkit 3.0 – ASP.NET MVC Sample

It’s almost time for the long awaited release of the Facebook Developer Toolkit 3.0, the most awesomest release of the toolkit to date. The new version has great support for ASP.NET, ASP.NET MVC, Silverlight, WinForms, WPF and basically any place you can run .NET. Ryan Powers and I worked on adding MVC support last week. (actually Ryan did all the coding, I just advised). We are going to build out more samples because that seems to have been a slight problem in previous versions.

So getting started with a Facebook ASP.NET MVC FBML canvas application.

First create a new app in Facebook. For a simple example you only need to go to the canvas section and set the “Canvas Page URL” and “Canvas Callback URL” and “Render Method” to FBML.  I named my app “FdtMvcSample”.

image

Save your Application Secret and API Key from the Basic section somewhere. You’ll need to put those in your web.config later. Now you can setup a new MVC project in Visual Studio. We’ll call it “FdtMvcSample”.

In your web.config add in your secret and API key:

   1: <appSettings>
   2:     <add key="Secret" value="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"/>
   3:     <add key="ApiKey" value="bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"/>
   4: </appSettings>

For development of Fbml canvas apps it’s easiest to use IIS and put your machine in the DMZ or port forward. I use gotdns.com for dynamic DNS and set my callback Url to be my dynamic DNS name / IIS virtual directory name.

You’ll need to configure your MVC project to use IIS instead of the local dev server so Facebook can call back to it. Just make sure your virtual directory name matches the callback URL directory.

image

In your MVC project you also need to add a reference to the Facebook.dll and Facebook.Web.Mvc.dll.

In my sample I removed most of the template items from the project. To connect with Facebook, we’ll focus on the HomeController.cs:

 

   1: [HandleError]
   2: public class HomeController : Controller
   3: {
   4:     private const string REQUIRED_PERMISSIONS = "read_stream,publish_stream";
   5:  
   6:     public ActionResult Index()
   7:     {
   8:         var api = this.GetApi();
   9:         ViewData["userId"] = api.Session.UserId;
  10:         return View();
  11:         
  12:     }
  13:  
  14:     //ApiKey & Secret in web.config
  15:     [FacebookAuthorization(IsFbml = true)]
  16:     public ActionResult Friends()
  17:     {
  18:         var api = this.GetApi();
  19:         var friends = api.Friends.GetUserObjects();
  20:  
  21:         return View(friends);
  22:     }
  23:  
  24:     [FacebookAuthorization(IsFbml = true, RequiredPermissions = REQUIRED_PERMISSIONS)]
  25:     public ActionResult Stream()
  26:     {
  27:         var api = this.GetApi();
  28:         var stream_data = api.Stream.Get(null, null, null, null);
  29:         
  30:         return View(stream_data.posts.stream_post);
  31:     }
  32: }
  33: }

For MVC, we added attributes to control authentication.  You can specify if it’s Fbml or iFrame or required permissions (and API key / secret if you don’t put them in the web.config) In the above code, the Index action is our public landing page and requires no authentication. The Friends action requires authentication to get the user’s friends’ names and the Stream action requires read_stream and publish_stream permission. The attribute runs before you action and redirects to the Facebook app authorization screen if needed and then redirects back to the action. One thing to note, adding permissions like that requires us to check which permissions are already granted and redirect to the prompt permission screen. Since that requires a call to Facebook each time the action is called, it would be best to get all the permissions granted on some initial landing page. Plus the user can get that out of the way upfront. If you need page specific permissions, then it would be best to use the Fbml fb:prompt-permission in your view before those actions are called.  This method is fine also, but just be aware of the impact.

On the controller we added an extension method to retrieve the Api object for making making Facebook calls based on the users current Facebook session. (You can optionally pass in the key/secret if they are not in the web.config)

In this simple example, I’m just passing the list of friends as the model to bind to the view.

 

   1: <%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" 
   2:     Inherits="System.Web.Mvc.ViewPage<IList<user>>" %>
   3:  
   4: <asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server">
   5:     <h2>Friends</h2>
   6:     <ul>
   7:     <% foreach (user u in Model)
   8:        { %>
   9:         <li><%= u.name %></li>
  10:     <% }%>
  11:     </ul>
  12: </asp:Content>

and in the master page I have some simple Fbml with a helper for generating the tabs.

   1: <%@ Master Language="C#" Inherits="System.Web.Mvc.ViewMasterPage" %>
   2: <%@ Import Namespace="FdtMvcSample.Helpers" %>
   3: <div id="header">
   4: <fb:tabs>
   5:   <%= Fbml.TabItem("Home", "Index", "Home", this.ViewContext) %>
   6:   <%= Fbml.TabItem("Friends", "Friends", "Home", this.ViewContext) %>
   7:   <%= Fbml.TabItem("Stream", "Stream", "Home", this.ViewContext) %>
   8: </fb:tabs>
   9: </div>
  10: <div id="main_content">
  11: <asp:ContentPlaceHolder ID="MainContent" runat="server" />
  12: </div>
  13: <div id="footer">
  14: </div>

The tab helper could most likely be more elegant. I just threw that in there to see how we’d do FBML helpers. We discussed making a full set of FBML helpers but that would be a significant effort and I’m not how much they are needed.

So that’s all the code needed to build a simple Facebook ASP.NET MVC FBML canvas application.

You can download the code here.  I put the full source of the required FDT components, but after the 3.0 release you can just use the new binaries.

If you would like to see a more complex example or have questions, just post in the forums.

Comments

No Comments