code blog foo - tag line bar

Integrating Facebook's fb:request-form with your ASP.NET MVC Application

In this blog post. I'll show you how to integrate Facebook's fb:request-form into ASP.NET MVC Application. If you've tried using the Facebook documentation on how to integrate this control into your website, you'll find that it's not entirely correct. Hopefully I can shed some light on how to get this thing working....so read this blog post before you decide to throw your dev box out of the window and take up basket weaving.

Why Leverage fb:request-form?

Integrating your application with the Facebook community is a sure fire way to bring traffic to your site. The <fb:request-form /> control gives loyal users of your website the ability to invite their Facebook friends. Here are some screen shots:


<fb:request-form /> when visiting http://www.examplegames.com


<fb:request-form /> condensed shows when visiting http://apps.facebook.com/examplegames


screen shot of pop-up when user clicks the submit button

Prerequisites

In order to do any kind of Facebook integration, you need to register your app with Facebook and you need to provide a way for users to authenticate using their Facebook log in. This blog post shows you how to register your site and integrate Facebook's login mechanism with your ASP.NET MVC web site.

Html for fb:request-form

This is the code for your view that is needed to show the fb:request-form with a full sized friend selector.

<!-- pull down Facebook's Javascript SDK -->
<script src="http://connect.facebook.net/en_US/all.js"></script>

<!-- the Facebook's Javascript SDK looks for this div when attempting to parse FMBL -->
<div id="fb-root">
    <fb:serverfbml width="750px">
        <script type="text/fbml">
            <fb:fbml>
            	<fb:request-form
                    action="http://www.examplegames.com/Friends/AddFacebookFriend/" 
                    method="post" 
                    type="Invite" 
                    content="I wanted to add you as a friend on example Games.  We can use this network to borrow games from each other and keep track of our video game library. <fb:req-choice label='example Games' url='http://apps.facebook.com/examplegames/' />">
          			<fb:multi-friend-selector max="10" showborder="false" actiontext="Invite Friends to example Games" email_invite="true" bypass="cancel" />
            	</fb:request-form> 
            </fb:fbml>
        </script>
    </fb:serverfbml>
</div>
        
<script type="text/javascript">
    FB.init({
        apiKey: 'f3ff8e4ed6becc81176d0b2517c9c44c',
        status: true, // check login status
        cookie: true, // enable cookies to allow the server to access the session
        xfbml: false  // parse XFBML 
    });

    //retrieving the log in status gets things going
    FB.getLoginStatus(handleSessionResponse);

    function handleSessionResponse(response) {
        FB.XFBML.parse();
    }
</script>

Html for fb:request-form condensed

This is the code for your view that is needed to show the fb:request-form in a condensed form.

<!-- pull down Facebook's Javascript SDK -->
<script src="http://connect.facebook.net/en_US/all.js"></script>

<div id="fb-root">
    <fb:serverfbml width="650px">
        <script type="text/fbml">
            <fb:fbml>
            	<fb:request-form
                    action="http://www.examplegames.com/Friends/AddFacebookFriend/" 
                    method="post" type="Invite" content="I wanted to add you as a friend on example Games.  We can use this network to borrow games from each other and keep track of our video game library. <fb:req-choice label='example Games' url='http://apps.facebook.com/examplegames/' />">
          			<fb:multi-friend-selector condensed="true" style="width: 650px" max="10" showborder="false" actiontext="Invite Friends to example Games" email_invite="true" bypass="cancel" />
                    <fb:request-form-submit label="Send Invite" />
            	</fb:request-form> 
            </fb:fbml>
        </script>
    </fb:serverfbml>
</div>
        
<script type="text/javascript">
    FB.init({
        apiKey: 'f3ff8e4ed6becc81176d0b2517c9c44c',
        status: true, // check login status
        cookie: true, // enable cookies to allow the server to access the session
        xfbml: false  // parse XFBML 
    });

    //retrieving the log in status gets things going
    FB.getLoginStatus(handleSessionResponse);

    function handleSessionResponse(response) {
        FB.XFBML.parse();
    }

</script>

After the form submits to Facebook

The fb:request-form takes in an action and method parameter. After Facebook does its thing, the fb:request-form will perform the HTTP POST against the method URI. Here is a snippet:

<!-- in this particular example an HTTP Post would be performed against the AddFacebookFriend controller action will be called -->
<fb:request-form
    action="http://www.examplegames.com/Friends/AddFacebookFriend/"
    method="post"

This is the AddFacebookFriend controller action:

[ActionName("AddFacebookFriend")]
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult AddFacebookFriend(FormCollection formCollection)
{
    //from the form collection, create a key value pair (just easier to work with for me, you dont have to do this)
    List<KeyValuePair<string, string>> results = new List<KeyValuePair<string, string>>();
    foreach (string key in formCollection.AllKeys)
    {
        results.Add(new KeyValuePair<string, string>(key, formCollection[key]));
    }

    string[] tokens;
    
    //in the uncondensed fb:form-request, there will be a form collection key called "emails[]" which will contain a comma delimited list of emails
    if (results.Any(s => s.Key == "emails[]"))
    {
        string emails = results.SingleOrDefault(s => s.Key == "emails[]").Value;
        tokens = emails.Split(',');
        foreach (string token in tokens)
        {
            //after the emails have been split, you can do whatever you want with the emails
        }
    }

    //both the uncondensed and condensed fb:form-request will contain a key called "id[]" which will contain a list of facebook id's
    if (results.Any(s => s.Key == "ids[]"))
    {
        string facebookUserIds = results.SingleOrDefault(s => s.Key == "ids[]").Value;
        tokens = facebookUserIds.Split(',');
        foreach (string token in tokens)
        {
            //after the id's have been split, you can do whatever you want with them
            //keep in mind that Facebook has already taken care of sending the request on its end
            //also keep in mind that the facebook user id's are of type System.Int64 (long), NOT int/System.Int32
        }
    }

    return RedirectToAction("Index", "Friends", new { invitationsSent = true });
}

Wrapping up

I think that's everything. You have your view code for creating both a condensed and uncondensed fb:request-form. And you have the controller action that handles the request. You can always send me an email if you have any additional questions (email is located on the about page).


Written: 6/11/2010