Home > Rate-It > Making a Facebook Wall Post using the new Graph API and C#

Making a Facebook Wall Post using the new Graph API and C#

One of the features coming up with Rate-It is the ability to post your ratings/reviews to your Facebook wall.  For this, we decided to go with the new Facebook Graph API.

There are quite a few tricks and obstacles in the way of you doing this, particularly because the documentation omits a few details and the documentation is very PHP- or Javascript-centric.  With this in mind, we’ve posted below some very detailed instructions on how to get the system going using Microsoft C#.

 

Debug your Facebook Application from localhost

One of the first problems you’ll have is trying to debug your application, and for this the easiest way is via localhost.  We have seen a few posts suggesting that this is not possible, but it is – and it is easy.  Simply setup a new application at www.facebook.com/developers and then enter your localhost information where a URL is required.  We’ve copied a screenshot of ours below:

image

 

Getting a user to Authorize your Application

Refer: http://developers.facebook.com/docs/authentication/

Facebook has a two-step approach for a user to authorize your application.  The first is to connect their Facebook account.  The second is to switch the Facebook account code with an OAuth account code.

The key to all this, and the most problems you’ll have is simply structuring your URLs.  There are three, and here they are:

        /// The callback page where the user is returned to after authorizing with FB

        /// </summary>

        /// <returns></returns>

        private string FacebookAfterAuthorize()

        {

            return SiteRoot + "services/facebook/canvas/afterauthorise.aspx";

        }


        /// <summary>

        /// Once FB returns a user code to us, we need to use the OAuth key in queries

        /// </summary>

        /// <param name="code"></param>

        /// <returns></returns>

        public string FacebookOAuthAccessTokenFromFacebookCode(string codeReturnedFromInitialFacebookRequest)

        {

            var url = "https://graph.facebook.com/oauth/access_token"

                .AppendQueryString("client_id", Configuration.Current.FacebookAPIKey)

                .AppendQueryString("client_secret", Configuration.Current.FacebookAPISecret)

                .AppendQueryString("code", codeReturnedFromInitialFacebookRequest)

                .AppendQueryString("redirect_uri", this.FacebookAfterAuthorize())

                ;


            return url;

        }


        /// <summary>

        /// The link the user clicks when they want to initialize their connection to FB

        /// </summary>

        /// <returns></returns>

        public string FacebookAuthorize()

        {

            var url = "https://graph.facebook.com/oauth/authorize"

                .AppendQueryString("client_id", Configuration.Current.FacebookAPIKey)

                .AppendQueryString("scope", "publish_stream,offline_access")

                .AppendQueryString("redirect_uri", this.FacebookAfterAuthorize())

                ;


            return url;

        }

Step 1 – Connect the Facebook Account

Simply create a hyperlink and present it to the user.  The hyperlink contains various GET parameters which tell Facebook who you are and what you want to do with the user’s account.  Here is our one:

var url = new LinkManager().FacebookAuthorize();

BtnFacebookAuthorize.NavigateUrl = url;

 

Pretty simple.  This redirects the user to a Facebook page where they are presented with something like this:

image

Assuming the user selects ‘Allow’, they are redirected to the redirect_url parameter you specified in the hyperlink.  In our case, this was /services/facebook/canvas/afterauthorize.aspx.  Let’s look at that now.

Step 2 – Switching the Facebook Code for the OAuth Code

The Graph API uses the OAuth system to authenticate users and at this point, we only have some kind of Facebook code.  We get the OAuth code by POSTing the Facebook code back up to Facebook.  I’ll let the code do the talking:

 

public void ProcessAfterAuthorization(HttpRequest request)

{

    // Facebook passes an empty code if the user declined

    string code = request.Params("code");

    if (string.IsNullOrEmpty(code)) throw new FacebookAuthorizationException("You have chosen not to proceed with Facebook integration.");


    // Facebook

    var url = new LinkManager().FacebookOAuthAccessTokenFromFacebookCode(code);

    var webRequest = WebRequest.Create(url);

    var webResponse = webRequest.GetResponse();

    StreamReader sr = null;

    string returnedKeyValuePairs = "";

    try

    {

        sr = new StreamReader(webResponse.GetResponseStream());

        returnedKeyValuePairs= sr.ReadToEnd();

    }finally

    {

        if (sr != null) sr.Close();

    }


    // Get the OAuth token from the returned querystring

    var authToken = returnedKeyValuePairs.GetQueryStringValue("access_token");


}

 

Save the authToken field against your user record – this is what you’ll pass later when you make a wall post.  It will look a little something like this:

108091332590110|a9fa8e86ed521818374c8733-100001367407858|vRR3VgTCPuBwgcsG4Kr2fUiw9A8

Writing to the User’s Wall

Refer: http://developers.facebook.com/docs/reference/api/post

Writing to a user’s wall is a lot more complicated, and the documentation linked above omits a very important point.  Here is what we came up with:

public class PostToWall

{

    public string Message = "";

    public string AccessToken = "";

    public string ArticleTitle = "";

    public string FacebookProfileID = "";


    public string ErrorMessage { get; private set; }

    public string PostID { get; private set; }


    /// <summary>

    /// Perform the post

    /// </summary>

    public void Post()

    {

        if (string.IsNullOrEmpty(this.Message)) return;


        // Append the user's access token to the URL

        var url = "https://graph.facebook.com/me/feed"

            .AppendQueryString("access_token", this.AccessToken);


        // The POST body is just a collection of key=value pairs, the same way a URL GET string might be formatted

        var parameters = ""

            .AppendQueryString("name", "name")

            .AppendQueryString("link", "http://link.com")

            .AppendQueryString("caption", "a test caption")

            .AppendQueryString("description", "a test description")

            .AppendQueryString("source", "http://blackballsoftware.com/images/whitetheme/headerwhite.png")

            .AppendQueryString("actions", "{\"name\": \"View on Rate-It\", \"link\": \"http://www.rate-it.co.nz\"}")

            .AppendQueryString("privacy", "{\"value\": \"EVERYONE\"}")

            .AppendQueryString("message", this.Message);



        // Mark this request as a POST, and write the parameters to the method body (as opposed to the query string for a GET)

        var webRequest = WebRequest.Create(url);

        webRequest.ContentType = "application/x-www-form-urlencoded";

        webRequest.Method = "POST";

        byte[] bytes = System.Text.Encoding.ASCII.GetBytes(parameters);

        webRequest.ContentLength = bytes.Length;

        System.IO.Stream os = webRequest.GetRequestStream();

        os.Write(bytes, 0, bytes.Length);

        os.Close();


        // Send the request to Facebook, and query the result to get the confirmation code

        try

        {

            var webResponse = webRequest.GetResponse();

            StreamReader sr = null;

            try

            {

                sr = new StreamReader(webResponse.GetResponseStream());

                this.PostID = sr.ReadToEnd();

            }

            finally

            {

                if (sr != null) sr.Close();

            }

        }catch(WebException ex)

        {

            // To help with debugging, we grab the exception stream to get full error details

            StreamReader errorStream = null;

            try

            {

                errorStream = new StreamReader(ex.Response.GetResponseStream());

                this.ErrorMessage = errorStream.ReadToEnd();

            }finally

            {

                if (errorStream != null) errorStream.Close();

            }

        }

    }

}

 

 

 

 

 

And to use, simply:

var post = new PostToWall();

post.Message = "Test message from Ben";

post.ArticleTitle = "A new rating has been posted";

post.AccessToken = "108091332590110|a9fa8e86ed521818374c8733-100001367407858|vRR3VgTCPuBwgcsG4Kr2fUiw9A8";

post.Post();

Response.Write("The Facebook post successed with ID: " + post.PostID);

Response.Write("<br/>");

Response.Write("The error message was: " + post.ErrorMessage);

 

Right – hopefully that is useful to somebody, it will be to us when we forget how we did it in a few months.

Apologies for the custom classes etc in the code like AppendQueryString() – I’m sure you can work them out.

About these ads
  1. Michael Murray
    November 3, 2010 at 9:52 am | #1

    Thats awesome Ben! I’ve been struggling with the oAuth stuff with facebook. Are you using this app inside an iframe? My main problem is that you only get to capture the iFrame call (which is the only call that contains the userid) once (when it first loads).

    • November 3, 2010 at 10:29 am | #2

      Nope not using in an iFrame. The entire process just uses the main ‘top’ frame of the website – nothing fancy. If an iFrame is not working for you, a popup might?

  2. heath
    December 1, 2010 at 3:19 pm | #3

    Thank you so much for that bit of code.I was having a problem with 400 bad request until I stumbled on this….many thanks..

  3. Lasantha Samarasekara
    December 17, 2010 at 6:30 am | #4

    Thanks Ben….
    Its a great article.. Even facebook itself does not provide us documentation like this.

    • December 17, 2010 at 7:25 am | #5

      Cheers – let’s hope they don’t change the API again any time soon

  4. vasu
    January 6, 2011 at 9:46 pm | #6

    HI,
    Nice Article,
    Can you please send me the AppendQueryString method code.
    Thanks in advance

    • January 6, 2011 at 10:36 pm | #7

      No problem (excuse the formatting)…

      public static string AppendQueryString(this string url, string key, string value, bool doNotEncrypt)
      {
      var encode = Dependency.Resolve();
      if (url.IndexOf(‘?’) != -1) { url += “&”; } else { url += “?”; }

      // Append
      if (doNotEncrypt) url += key + “=” + value;
      else url += encode.Encode(key) + “=” + encode.Encode(value);

      // Return
      return url;
      }

  5. Pham Hoang
    April 7, 2011 at 5:58 pm | #8

    Hi Ben,

    I wish I could have Dependency.Resolve() method, please help me!

    • April 8, 2011 at 1:29 am | #9

      Hi, the Dependency.Resolve() methods are just calls using Microsoft Unity to get my class names. If it says IPersonService, then it resolves to just PersonService(). My intention isn’t to give you working code, as it is no good to you without the entire source code and all service methods, rather it is to show the general approach. You can stub out those methods to get it to compile.

  6. Da Jona
    April 30, 2011 at 9:10 am | #10

    Hi Ben,

    How can I fix the “Dependency.Resolve()” error in the AppenQueryString method?

    • April 30, 2011 at 9:48 am | #11

      You can see how Dependency.Resolve works at http://blog.blackballsoftware.com/2011/04/26/best-practice-architecture-for-professional-microsoft-net-websites/

      Or, just delete it and rewrite the line, it’s just a fancy way of concatenating a query string

      • Da Jona
        April 30, 2011 at 9:58 am | #12

        Ben… sry but I’m just gettin’ started whit this API.

        Can you explain me about GetQueryStringValue method and an error on request.Params; VS say Params doesn’t allow parameters.

        Thx and sry again. :$

      • Kasper Skov
        January 6, 2012 at 2:27 am | #13

        @Da Jona. For the GetQueryStringValue method I just made a string replace (access_token > empty string). For params, theres I syntax error in the code. Its string code = request.Params["code"];. Notice the []. Havent tested it though.

  7. pavani
    December 23, 2011 at 9:03 pm | #14

    wow it working for me thanks ben .Thnk u so much .I have been struggling with these since last week

  8. Mido
    February 1, 2012 at 11:23 am | #15

    this nice post , thnx alot

  9. jb
    March 3, 2012 at 1:01 pm | #16

    Thank you so much ben for this post!

  10. petersjazz
    March 24, 2012 at 8:03 pm | #17

    Thank you very much. Very good for me. Silly question i guess:
    There do i get the api for c# and is there any problems getting started in vs2010?

    • March 26, 2012 at 8:36 am | #18

      Hi, VS2010 is fine – it’s what I use actually. C# is built in to it, so you can just get typing. If you’re just learning, I recommend searching ‘getting started with visual studio’ tutorial – it will probably be in C#

  11. petersjazz
    March 24, 2012 at 8:05 pm | #19

    Thank you very much

  12. Rohit Sahasrabudhe
    April 2, 2012 at 6:14 am | #20

    Thanks Ben. Saved my day !

  13. May 24, 2012 at 7:14 am | #21

    Ben – you saved me HOURS of time. It would have taken me forever to figure this out. Thank you so much for putting this up.

  14. Sam
    October 15, 2012 at 7:51 pm | #22

    Awesome Ben ! , very clear and good tutorial ! :) Do you have any post that shows how to retrieve user newsfeed , wall using facebook graph api ? as i am struggling with it Thank you :)

    • October 16, 2012 at 8:10 am | #23

      Hey Sam, nah sorry I don’t have anything about the user newsfeed. Hopefully this tutorial gives you the gist of how it all fits together and you can just plug in some newsfeed code from Stack Overflow or something. Good luck

  15. Sam
    October 23, 2012 at 2:35 am | #24

    Hi Ben , may i ask a question please ? i am new to this facebook application.I have managed to post a message to a group wall and able to see my own post in the group. However , my friends is unable to see my post. I used

    Facebook.FacebookAPI api = new Facebook.FacebookAPI(AccessToken);
    Dictionary data = new Dictionary();
    data.Add(“message”, “Test”);
    data.Add(“privacy”, “{\”value\”: \”EVERYONE\”}”);
    api.Post(“/groupid/feed”, data);

    Appreciate any help ! Thanks :)

  16. Soeren
    November 1, 2012 at 10:29 pm | #25

    Hi Ben. Interesting article. Do you have an example that shows exactly how and when the call to ProcessAfterAuthorization(HttpRequest request) is made? I assume that it is after the user has authorized the app?

    • November 5, 2012 at 9:01 am | #26

      Hi, yeah when you set up your app in Facebook, they ask you for the ‘post authorize url’. You can specify anything you like, as long as it falls under your main domain name. So, you might choose http://www.example.com/afterauthorize.aspx. On THAT page, in the Page_Load() method, you make a call to the ProcessAfterAuthorization() function I provided.

  1. April 6, 2011 at 4:16 pm | #1

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: