I am a danish programmer living in Bangkok.
Read more about me @ rasmus.rummel.dk.
Webmodelling Home > Social Media > Interacting with Facebook API using C#
Do good

Facebook API C# Examples

Updated Nov 2012. Facebook API tutorial in C# - writing to a users facebook wall step-by-step with source code.

Just as I was dusting off my old facebook account trying to grasp what social media was all about destiny would it that one of Favourite Design's customers wanted to integrate their comment & blog system with Facebook. Rather than having one of our already over worked programmers to figure it out, I thought I would do it myself (for once) and also I figured that it would be interesting if my Discussions Forum & Comments WebControl directly supported Facebook integration.

Integrating a blog or a website with Facebook turned out not to be all that difficult - just follow the 5 steps below (only 3, 4 & 5 are necessery) and you will have your website write to users facebook walls in no time.

  1. Concepts
  2. Proof of concept - Try it out - write to your facebook wall and list your friends
  3. Create a Facebook application
  4. Setup localhost development - more convenient
  5. Write to Facebook wall - finally & with full code

Concepts

Facebook user objects and their relationships are normally referred to as a social graph, see Wikipedia on socal graph, however if including not only the user objects and their relationships but also the users photos, messages etc. and their relationships, then this is an expansion of the social graph concept and the whole is normally referred to as an open graph.

Facebook API makes it possible to interact with the Facebook open graph and is therefore often referred to as Open Graph API or just Graph API.

Then interacting with the Facebook API, that is: interacting with facebook users and their objects, you need to do so through a Facebook Application. This facebook application is one that you have to create @ facebook (see below how to do that). Then you request Facebook users for permissions to interact with their objects, the users are actually giving these permissions to your Facebook App, not to you - therefore then interacting with a Facebook users objects, your code will always need to authenticate as your Facebook App (since permissions are given to your Facebook App).

For Authentication & Authorization Facebook is following the OAuth 2.0 protocol. Permissions granted by Facebook users (to your Facebook App) will translate into an OAuth access token (which is a string obtainable by your C# code). Here is a logic step-by-step illustration of what happens :

  1. A person here called Rasmus lands on this page, facebook-api.aspx.
  2. Rasmus writes "Test" into the textarea field below and press the submit button.
  3. Upon postback facebook-api.aspx redirect Rasmus browser to Facebook to let Facebook prompt Rasmus to authorize Webmodelling publish_stream access (public stream access allows a Facebook App to write to a users Facebook wall).
  4. If Rasmus is not currently logged on to Facebook, Facebook do not know who the person is and presents a Facebook login page.
  5. After Rasmus login, Facebook see if Rasmus have earlier authorized the Webmodelling App publish_stream access.
  6. If Rasmus have not earlier authorized the Webmodelling App publish_stream access, then Facebook will present a new page asking whether Rasmus want to authorize publish_stream access to the Webmodelling App.
  7. Facebook will redirect Rasmus browser back to facebook-api.aspx and if Rasmus authorized or have earlier aurhorized publish_stream access to the Webmodelling App, then Facebook will add a code key to the querystring.
  8. The C# code for facebook-api.aspx can then use that code key value to request an access token from Facebook. The access token returned by Facebook specifies permission scope (publish_stream) for a specific user (Rasmus) for a specific Facebook application (Webmodelling) as well as a time limit the access token is valid.
  9. With the access token, the C# code of facebook-api.aspx can now interact with the Facebook API eg. to post a message on Rasmus Facebook wall.

Try it out

As a proof of concept, I have created 2 live try-outs of the exact code we are going through in this tutorial. The try-outs are not only fun, but you will also be able to see the OAuth authorization process live (the full process is available only first time you try, if you want to see the full process again, you will need to de-authorize the webmodelling App in your facebook account).

  • Write to your own Facebook wall

    Write some test text in the textarea below, press the submit button and follow the process.

  • List your Facebook friends

    Just press the submit button (if you have already done the above test, authorization will be skipped and you will get your friend list immediately).


How to create a Facebook application

Then interacting with the Facebook API, you do so through a Facebook Application. The most important elements of a Facebook Application is :

  • App Name : a descriptive name, eg. Webmodelling.
  • App URL : eg. http://webmodelling.com/ (the application cannot be used outside of the urls domain)
  • App ID : publicly available and must be submittet to Facebook each time you interact with the Facebook API.
  • App Secret : not publicly available but must be submittet to Facebook each time you need to create an access_token.

If you do not yet have a Facebook Application, you need to create one. Creating a Facebook Application is a very fast procedure, just follow the steps below :

  1. Navigate your browser to https://developers.facebook.com and press the "Log In" link.
  2. After login press the "Apps" link.
  3. If you have any Apps, the first App is default selected. Press the "Create New App" button.
  4. In the "Create New App" dialog, write an appropriate name for your Facebook Application (here I named it MyAppName) and press the Continue button.
  5. You need to pass a Captcha (to avoid automated app creations).
  6. After passing the Captcha, you can set properties for your new App, we only need to set 1 property, the App Url which in our case is called "Site URL" under "Website with Facebook Login" (the Facebook App is now valid if it is used from "Site URL", in my case if used from http://webmodelling.com). Press the "Save Changes" button to save the App.
  7. The Facebook App is now saved and available across the world in a couple of minutes. Press the "Apps" link to get to your App list with your new App default selected - just to get an overview.
  8. Overview of your Facebook Apps.

Congratulations - you now have a Facebook Application that you can use to interact with the Facebook API doing all sorts of things with other peoples objects. However before we continue to do the actual code, we better setup support for developing on localhost, see next.


Setup localhost development

Then developing your Facebook integration, most likely you are developing on localhost, therefore you need a way to have Facebook approving your Facebook application on your localhost - luckily Facebook have made it easy : What Facebook does then validate an API request is to parse out the domain from the url referer of the API request and match the domain against domains allowed for the Facebook App that the API request belongs to. As you can set any domain name in the url referer of an http request, you don't need to setup a real global domain. The most easy solution is to :

  1. In your Facebook App set the App Domain property to YourDomain.com (in my case webmodelling.com), this way Facebook will allow your API requests to come from any subdomain of YourDomain.com :
    1. Login to https://developers.facebook.com and navigate to Apps.
    2. Select the App you want to use for integrating with Facebook API (in my case it is Webmodelling) and click on "Edit Settings".
    3. Under basic settings set "App Domains" to YourDomain.com (in my case webmodelling.com) and press the "Save" button. Facebook will now allow an API request to come from any subdomain of YourDomain.com (you will still need to authenticate using AppID & AppSecret of course).
  2. In your c:\windows\system32\drivers\etc\hosts file to add the following line :
    • 127.0.0.1    develop.YourDomain.com : your browser will now match develop.YourDomain.com to localhost.
  3. Setup your IIS to map develop.YourDomain.com to your website, eg. if your website is an application under Default website, then Default website must be mapped to develop.YourDomain.com :
    1. Launch IIS
    2. Right click on Default website (or wherever your website is located) to open the "Edit Bindings" dialog.
    3. Add develop.YourDomain.com to port 80 (in my case YourDomain is webmodelling).
  4. Everytime you launch your development application in your browser, you need to substitute the "localhost" part with "develop.YourDomain.com", like this :
    • http://localhost/_webmodelling/webmodelling/WebmodellingWeb/webbits/socialmedia/facebook-api.aspx
    • http://develop.YourDomain.com/_webmodelling/webmodelling/WebmodellingWeb/webbits/socialmedia/facebook-api.aspx

Congratulations : you are all set to develop Facebook integration on your localhost.


Write to Facebook wall - full code

Finally we are ready to start! Follow the steps below and/or download the FBWrite C# Code (if downloading the code, you still need to perform step 1, 2 & 3).

  1. Add you Facebook application AppID & AppSecret to you web.config file :
    <appSettings>
        <add key="facebook:AppId" value="YourAppID"/>
        <add key="facebook:AppSecret" value="YourAppSecret"/>
    </appSettings>
    
  2. Create a new C# .aspx page called fbwrite.aspx
  3. In fbwrite.aspx insert the following :
    <asp:TextBox ID="tbMessage" runat="server" TextMode="MultiLine" Rows="5" Columns="30"></asp:TextBox>
    <br /><asp:Button ID="btnSubmit" runat="server" Text="Send to my Facebook" OnClick="btnSubmit_Click" />
    
  4. In fbwrite.aspx.cs insert the following at the top of the page above the class definition :
    using System;
    using System.Web;
    using System.Net;
    using System.IO;
    using System.Configuration;
    using System.Collections.Specialized;
    
  5. In fbwrite.aspx.cs insert the following class globals :
    string facebook_urlAuthorize_base = "https://graph.facebook.com/oauth/authorize";
    string facebook_urlGetToken_base = "https://graph.facebook.com/oauth/access_token";
    string facebook_AppID = ConfigurationManager.AppSettings["facebook:AppID"];
    string facebook_AppSecret = ConfigurationManager.AppSettings["facebook:AppSecret"];
    
  6. In fbwrite.aspx.cs insert the following in Page_Load :
    if (!IsPostBack) 
    {
    	if (Request["code"] != null) 
    	{
    		//After this page have redirected the users browser to Facebook asking to be authorized to write to the
    		//users wall, Facebook will redirect back to this page and if authorized having a "code" key in the querystring
     
    		//Since we have a code we got authorized and can now
    		//1) get an access_token
    		//2) use the access_token to write to the users Facebook wall
    		string authorizationCode = Request["code"];
    		string access_token = Facebook_GetAccessToken(authorizationCode);
    		if (access_token == "")
    		{
    			Response.Write("Could not get access_token");
    			return;
    		}
    		Facebook_WriteWall(access_token, (string)Session["Message"]);
    	}
    }
    
  7. In fbwrite.aspx.cs create the button handler, btnSubmit_Click :
    protected void btnSubmit_Click(object sender, EventArgs e)
    {
    	string message = tbMessage.Text;
     
    	//necessary to save the message in a session since under the authentication & authorization process we are going to loose ViewState
    	Session["message"] = message;
     
    	Facebook_AuthorizeApplication();
    }
    
  8. In fbwrite.aspx.cs create the Facebook_AuthorizeApplication() procedure :
    private void Facebook_AuthorizeApplication()
    {
    	//In this function we ask the user to authorize our Facebook application using an authorization request url
     
    	//the authorization request url need to be appended
    	//1) Our AppID
    	//2) The permission scope (here publish_stream)
    	//3) A Url that Facebook can redirect the users browser to then Facebook is finish asking the user whether permission can be granted
     
    	string scope = "publish_stream"//see: http://developers.facebook.com/docs/authentication/permissions/ for extended permissions
    	string urlAuthorize = facebook_urlAuthorize_base;
    	urlAuthorize += "?client_id=" + facebook_AppID;
    	urlAuthorize += "&redirect_uri=" + Facebook_GetRedirectUri();
    	urlAuthorize += "&scope=" + scope;
     
    	//redirect the users browser to Facebook to ask the user to authorize our Facebook application
    	Response.Redirect(urlAuthorize, true); //this cannot be done using WebRequest since facebook may need to show dialogs in the users browser
    }
    

    After the users browser is redirected to urlAuthorize :

    1. Facebook will first check if the user is logged in with facebook and if not then display a login dialog to authenticate the user.
    2. After the user is authenticated (using either facebook cookie on the users browser or using the login dialog), Facebook will check if the user have already granted Webmodelling access to the requested resources and if not then display a dialog letting the user decide whether to grant permission or not.
    3. After Facebook knows if the user want to authorize our Facebook application the requested permission scope, Facebook will redirect the users browser back to our website using the redirect_uri and in case we were authorized Facebook have appended the redirect_uri with a querystring code key containing the access_token.
  9. In fbwrite.aspx.cs create the Facebook_GetAccessToken() procedure :
    private string Facebook_GetAccessToken(string pAuthorizationCode)
    {
    	//In this function we use the authorization code from before to obtain an access_token.
    	//The access_token can be used to request resources from a specific user within the authorized permission scope
    		
    	//The access_token request url need to be appended
    	//1) Our AppID
    	//2) Our AppSecret
    	//3) The exact same redirect_uri that was used before then authorized
    	//4) The authorization code we just got from Facebook
     
    	string urlGetAccessToken = facebook_urlGetToken_base;
    	urlGetAccessToken += "?client_id=" + facebook_AppID;
    	urlGetAccessToken += "&client_secret=" + facebook_AppSecret;
    	urlGetAccessToken += "&redirect_uri=" + Facebook_GetRedirectUri();
    	urlGetAccessToken += "&code=" + pAuthorizationCode;
     
    	string responseData = RequestResponse(urlGetAccessToken); //we write RequestResponse a little later
    	if (responseData == "")
    	{
    		return "";
    	}
    	NameValueCollection qs = HttpUtility.ParseQueryString(responseData);
    	string access_token = qs["access_token"] == null ? "" : qs["access_token"];
     
    	return access_token;
    	//(The access_token is valid only from within the site domain specified for our Facebook application)
    }
    
  10. In fbwrite.aspx.cs create the Facebook_WriteWall() procedure :
    private void Facebook_WriteWall(string pAccessToken, string pMessage)
    {
    	//In this function we will write to the users Facebook wall by posting the message through the Facebook Graph API
     
    	//The post url need to be appended :
    	//1) A username (I don't understand why, however I guess "me" will translate to the user embedded in the access_token)
    	//2) A data type (here feed)
    	//3) The access_token
     
    	string username = "me";
    	string datatype = "feed";
    	string urlWriteWall = "https://graph.facebook.com/" + username + "/" + datatype + "?access_token=" + pAccessToken;
     
    	//the message to post as a key/value pair
    	string entityMessage = "message=" + Session["message"];
    	entityMessage += "&picture=http://webmodelling.com/_images/jewelpit.png";
    	entityMessage += "&link=http://webmodelling.com";
    	entityMessage += "&name=Rasmus";
    	entityMessage += "&caption=Writing to Facebook wall";
    		
    	HttpPost(urlWriteWall, entityMessage); //we write HttpPost a little later
    }
    
  11. In fbwrite.aspx.cs create the Facebook_GetRedirectUri() helper procedure :
    private string Facebook_GetRedirectUri()
    {
    	string urlCurrentPage = Request.Url.AbsoluteUri.IndexOf('?') == -1 ? Request.Url.AbsoluteUri : Request.Url.AbsoluteUri.Substring(0, Request.Url.AbsoluteUri.IndexOf('?'));
    	NameValueCollection nvc = new NameValueCollection();
    	foreach (string key in Request.QueryString) { if (key != "code") { nvc.Add(key, Request.QueryString[key]); } }
    	string qs = "";
    	foreach (string key in nvc)
    	{
    		qs += qs == "" ? "?" : "&";
    		qs += key + "=" + nvc[key];
    	}
    	string redirect_uri = urlCurrentPage + qs; //urlCallback have to be exactly the same each time it is used (that's why the code key is removed)
     
    	return redirect_uri;
    }
    
  12. In fbwrite.aspx.cs create the HttpPost() helper procedure :
    private string HttpPost(string pUrl, string pPostData)
    {
    	HttpWebRequest webRequest = (HttpWebRequest)HttpWebRequest.Create(pUrl);
    	webRequest.ContentType = "application/x-www-form-urlencoded";
    	webRequest.Method = "POST";
    	byte[] bytes = System.Text.Encoding.UTF8.GetBytes(pPostData);
    	Stream requestWriter = webRequest.GetRequestStream(); //GetRequestStream
    	requestWriter.Write(bytes, 0, bytes.Length);
    	requestWriter.Close();
     
    	Stream responseStream = null;
    	StreamReader responseReader = null;
    	string responseData = "";
    	try
    	{
    		WebResponse webResponse = webRequest.GetResponse();
    		responseStream = webResponse.GetResponseStream();
    		responseReader = new StreamReader(responseStream);
    		responseData = responseReader.ReadToEnd();
    	}
    	catch (Exception exc)
    	{
    		throw new Exception("could not post : " + exc.Message);
    	}
    	finally
    	{
    		if (responseStream != null)
    		{
    			responseStream.Close();
    			responseReader.Close();
    		}
    	}
     
    	return responseData;
    }
    
  13. In fbwrite.aspx.cs create the RequestResponse() helper procedure :
    private string RequestResponse(string pUrl)
    {
    	HttpWebRequest webRequest = System.Net.WebRequest.Create(pUrl) as HttpWebRequest;
    	webRequest.Method = "GET";
    	webRequest.ServicePoint.Expect100Continue = false;
    	webRequest.Timeout = 20000;
     
    	Stream responseStream = null;
    	StreamReader responseReader = null;
    	string responseData = "";
    	try
    	{
    		WebResponse webResponse = webRequest.GetResponse();
    		responseStream = webResponse.GetResponseStream();
    		responseReader = new StreamReader(responseStream);
    		responseData = responseReader.ReadToEnd();
    	}
    	catch (Exception exc)
    	{
    		Response.Write("<br /><br />ERROR : " + exc.Message);
    	}
    	finally
    	{
    		if (responseStream != null)
    		{
    			responseStream.Close();
    			responseReader.Close();
    		}
    	}
     
    	return responseData;
    }
    

Congratulations - you are ready to try it out : in Visual Studio set fbwrite.aspx as start page and press F5 (don't forget in your browser url field to substitute localhost with develop.YourDomain.com).

The above code is very functional as it is and I also think it makes a good base for a wide range of Facebook integration, eg. I have manipulated it a little to get it working from inside my custom Forum & Comments control, Discussions.


Bonus code : List Facebook friends

To list a Facebook users friends, we can reuse most of the above code except most notably the Facebook_WriteWall function (as we don't want to write to facebook wall here). Either copy the code from the below steps and/or download the full FBFriends C# Code (if you download the code, you will still need to follow step 1, 2 & 3 below).

  1. Add you Facebook application AppID & AppSecret to you web.config file : (if you have not already done that following the fbwrite example above)
    <appSettings>
        <add key="facebook:AppId" value="YourAppID"/>
        <add key="facebook:AppSecret" value="YourAppSecret"/>
    </appSettings>
    
  2. Create a new C# .aspx page called fbfriends.aspx (as opposed to fbwrite.aspx above)
  3. In fbfriends.aspx insert the following : (differs from fbwrite because there are no textarea field)
    <asp:Button ID="btnSubmit" runat="server" Text="Show My Friends" OnClick="btnSubmit_Click" />
    
  4. In fbfriends.aspx.cs insert the following using statements at the top (above the class definition) :
    using System;
    using System.Web;
    using System.Net;
    using System.IO;
    using Newtonsoft.Json; //you need this 3. party assembly, downloadable from http://json.codeplex.com/
    using System.Configuration;
    using System.Collections.Generic;
    using System.Collections.Specialized;
    
  5. In fbfriends.aspx.cs insert the following class globals : (same as for fbwrite)
    string facebook_urlAuthorize_base = "https://graph.facebook.com/oauth/authorize";
    string facebook_urlGetToken_base = "https://graph.facebook.com/oauth/access_token";
    string facebook_AppID = ConfigurationManager.AppSettings["facebook:AppID"];
    string facebook_AppSecret = ConfigurationManager.AppSettings["facebook:AppSecret"];
    
  6. In fbfriends.aspx.cs insert the following in Page_Load : (same as for fbwrite except that we call the Facebook_ListFriends function instead of Facebook_WriteWall)
    if (!IsPostBack)
    {
    	if (Request["code"] != null)
    	{
    		//After this page have redirected the users browser to Facebook asking to be authorized to write to the
    		//users wall, Facebook will redirect back to this page and if authorized having a "code" key in the querystring
     
    		//Since we have a code we got authorized and can now
    		//1) get an access_token
    		//2) use the access_token to write to the users Facebook wall
    		string authorizationCode = Request["code"];
    		string access_token = Facebook_GetAccessToken(authorizationCode);
    		if (access_token == "")
    		{
    			Response.Write("Could not get access_token");
    			return;
    		}
    		Facebook_ListFriends(access_token); //in fbwrite we called Facebook_WriteWall
    	}
    }
    
  7. In fbfriends.aspx.cs create the button handler, btnSubmit_Click : (btnSubmit_Click differs from fbwrite because we don't need to store the text to write)
    protected void btnSubmit_Click(object sender, EventArgs e)
    {
    	Facebook_AuthorizeApplication();
    }
    
  8. In fbfriends.aspx.cs insert the Facebook_ListFriends function :
    private void Facebook_ListFriends(string pAccessToken)
    {
    	string username = "me";
    	string dataType = "friends";
    	string urlGetFriends = "https://graph.facebook.com/" + username + "/" + dataType + "?access_token=" + pAccessToken;
    	string jsonFriends = RequestResponse(urlGetFriends);
    	if (jsonFriends == "")
    	{
    		Response.Write("<br /><br />urlGetFriends have problems");
    		return;
    	}
    	Friends friends = JsonConvert.DeserializeObject<Friends>(jsonFriends); //we write the Friends class later
     
    	foreach (Friend friend in friends.data) //we write the Friend class later
    	{
    		Response.Write("<br />" + friend.name);
    	}
    }
    
  9. Copy the following 5 functions from the fbfriends example above or from the downloadable fbfriends C# Code file and insert them into fbfriends.aspx.cs :
    1. Facebook_AuthorizeApplication()
    2. Facebook_GetAccessToken()
    3. Facebook_GetRedirectUri()
    4. HttpPost()
    5. RequestResponse()
  10. In fbfriends.aspx.cs insert the Friend class (outside of the fbfriends class definition) :
    public class Friend
    {
    	public string id { getset; }
    	public string name { getset; }
    }
    
  11. In fbfriends.aspx.cs insert the Friends class (outside of the fbfriends class definition) :
    public class Friends
    {
    	public List<Friend> data { getset; }
    }
    

Congratulations - you should now be able to list anybodys Facebook friends.

This concludes my Facebook API C# Examples tutorial, please use the comments below to help, ask for help or just voice your opinion.


Appendix : Relevant links


Appendix : Common errors and solutions

  1. Authentication request errors OAuthException Missing client_id parameter

Reason : Look closely at your authentication request url, you will see that the client_id (aka AppID) is missing.

Example : https://graph.facebook.com/oauth/authorize?client_id=&redirect_uri=http://webmodelling.com/socialmedia/facebook/fbwrite.aspx&scope=publish_stream - the client_id value is empty.

Solution : In the querystring of your authentication request url, you need to insert a client_id key with the value of your Facebook AppID. Like this :
https://graph.facebook.com/oauth/authorize?client_id=YourAppID&redirect_uri=http://webmodelling.com/socialmedia/facebook/fbwrite.aspx&scope=publish_stream

  1. Authentication request errors OAuthException Invalid redirect_uri: Given URL is not allowed by the Application configuration.

Reason : Your authentication request does not contain a valid redirect_uri in the querystring. The redirect_uri value must be within the domain of your Facebook application.

Example : You have forgot to set "Site URL" under "Website with Facebook Login", so your Facebook App does not have any App Url in which case an authentication request like https://graph.facebook.com/oauth/authorize?client_id=144708635601028&redirect_uri=http://webmodelling.com/socialmedia/facebook/fbwrite.aspx&scope=publish_stream will fail because the domain part of the redirect_uri value, webmodelling.com, does not match your Facebook App Url.

Solution : Be sure your redirect_uri match your Facebook App Url site domain OR is within your Facebook Apps "App Domains".


Comments

You can comment without logging in
Profile
Username
Password
Password
Email
Nickpic
Get notified on reply to own posts  (only works if you specify an email address)
Get notified on receiving a PM  (only works if you specify an email address)
Remember my username
Remember my password
signature
Words: Chars: Chars left: 
    


click to top Facebook API Tutorial