In this tutorial I am going to show you how you can easily
integrate your MVC app with facebook graph API and directly post to
user's wall.
This is part 4 of Facebook API integration in ASP.NET series. In
order to complete this tutorial, you need to have facebook login
button integrated in your app. Please check out Part 1 -
Integrating Facebook Login button in ASP.NET MVC 4
application for insturctions on how to do so and
working solution that you need for this tutorial.
So, the plan is... - firstly we'll add some helpers for cross
domain communication, create facebook wall message model and
finally add a controler that will connect all the parts together
and talk to facebook server.
Communication infrastructure
Facebook API is no different than any other API service I've
come accros so far. For this tutorial, I don't want to use any 3rd
party communication plugins for 3 simple reasons:
- It won't save us a lot of time
- We'll have full control over the code
- You'll be able to apply this knowledge and reuse my code for
pretty much any other API integration
Let's start from creating MethodResult class. This will be our
standard method return object that we'll use troughout this
project. Right click on Models folder and select Add -> New Item
-> Class. Name it MethodResult.cs. Paste in
following code:
namespace FacebookLoginButton.Models
{
public class MethodResult
{
public string errorMessage;
public ReturnCode returnCode;
public enum ReturnCode
{
Unknown = 0,
Success = 1,
Failure
}
}
}
We also need some helper methods in our project. Add new
Helper.cs file in the root of our app.
and paste in following code:
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text;
using FacebookLoginButton.Models;
namespace FacebookLoginButton
{
public class Helper
{
public static MethodResult SubmitPost(string url, string postValues, out string response)
{
MethodResult result = new MethodResult();
response = string.Empty;
try
{
ASCIIEncoding encoding = new ASCIIEncoding();
byte[] data = encoding.GetBytes(postValues);
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url);
webRequest.Method = "POST";
webRequest.ContentType = "application/x-www-form-urlencoded";
webRequest.Timeout = System.Threading.Timeout.Infinite;
webRequest.ContentLength = data.Length;
Stream requestStream = webRequest.GetRequestStream();
requestStream.Write(data, 0, data.Length);
requestStream.Close();
requestStream.Flush();
WebResponse webResponse = webRequest.GetResponse();
StreamReader reader = new StreamReader(webResponse.GetResponseStream());
var dataReceived = reader.ReadToEnd();
webResponse.Close();
reader.Close();
webRequest.Abort();
result.returnCode = MethodResult.ReturnCode.Success;
response = dataReceived;
}
catch (Exception ex)
{
result.returnCode = MethodResult.ReturnCode.Failure;
result.errorMessage = ex.Message;
}
return result;
}
public static string BuildPostString(Dictionary<string, string> postValues)
{
StringBuilder sb = new StringBuilder();
foreach (KeyValuePair<string, string> value in postValues)
{
if (sb.Length > 0) sb.Append("&");
sb.Append(string.Format("{0}={1}", value.Key, value.Value));
}
return sb.ToString();
}
}
}
Helper.cs contains 2 handy methods. SubmitPost makes a post
request to given address and BuildPostString builds correct url
including all get parameters that we want to pass.
Wall message model
Before we can create our wall message controller, we need the
model that will represent message properties. Once we've got that,
we'll get Visual Studio to generate controller and input form for
us.
Right click on Models folder and select Add -> New Item ->
Class and name it WallMessageModel.cs and paste in
following code:
namespace FacebookLoginButton.Models
{
public class WallMessageModel
{
public string name { get; set; }
public string link { get; set; }
public string caption { get; set; }
public string description { get; set; }
public string source { get; set; }
public string actions { get; set; }
public string privacy { get; set; }
public string message { get; set; }
}
}
Rebuild your solution!
Wall message controller
Now, right click on Controllers folder and select Add ->
Controller. Make sure you've got Controller with empty read/wrtite
actions selected in Scaffolding options -> Template dropdown as
shown below:
VisualStudio will prepopulate our controller with several
methods. The only 2 we need are public ActionResult
Index() and public ActionResult Create(FormCollection
collection). Remove all methods except these 2.
Message form
View() in Index() method should be highlighted in red indicating
that there is no view file (.cshtml) associated with this method.
Right click on View() and select add view. Now, be carefull, since
we're passing an object to it, it needs to be a strongly-typed
view. This will make all object properties accessible via @Model
variable. Also, we want Visual Studio to generate create form for
us, so make sure we've got Create selected in Scaffold template
dropdown. Before clicking OK, make sure all properties in the
window are set as on following screen:
You can obviously modify the model to make some of its
properties required etc and then on form creation Visual Studio
will generate neccessary validation login for you.
You'll find html for the form in Views -> WallMessage ->
Index.cshtml file. For time being, let's remove all the fields
except message leaving following markup:
@model FacebookLoginButton.Models.WallMessageModel
@{
ViewBag.Title = "Part 4 - Facebook Wall Message";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Part 4 - Facebook Wall Message</h2>
<script src="@Url.Content("~/Scripts/jquery.validate.min.js")"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")"></script>
@using (Html.BeginForm("Create", "WallMessage")) {
@Html.ValidationSummary(true)
<fieldset>
<legend>Create new wall message</legend>
<div class="editor-label">
@Html.LabelFor(model => model.message)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.message)
@Html.ValidationMessageFor(model => model.message)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
Now, let's come back to our controller and add some logic to
process our request.
Before we do any more coding, we need to install
Newtonsoft.Json.dll that will helps us with Json string -> C#
object conversion. Below, in article attachments section, there is
Newtonsoft.dll download available. Unzip it and
drop folder content into /bin folder inside your
app. Once you've done that, in Visual Studio, right click
References folder, and add reference to
Newtonsoft.dll file that you've just dropped into /bin. If
you've completed any other of my facebook tutorials (except part 1
- login button), this dlls should already be found in /bin
directory.
In WallMessageController.cs file, replace public
ActionResult Create(FormCollection collection) method with
following code:
[HttpPost]
public ActionResult Create(WallMessageModel model)
{
try
{
var postValues = new Dictionary<string, string>();
// list of available parameters available @ http://developers.facebook.com/docs/reference/api/post
postValues.Add("access_token", Session["accessToken"].ToString());
postValues.Add("message", model.message);
string facebookWallMsgId = string.Empty;
string response;
MethodResult header = Helper.SubmitPost(string.Format("https://graph.facebook.com/{0}/feed", Session["uid"].ToString()),
Helper.BuildPostString(postValues),
out response);
if (header.returnCode == MethodResult.ReturnCode.Success)
{
var deserialised =
Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary<string, string>>(response);
facebookWallMsgId = deserialised["id"];
return RedirectToAction("CreatedSuccessfully");
}
}
catch
{
}
return RedirectToAction("WallMessageError");
}
We also need to add 2 missing actions that we redirect to in the
code above. Add following code below Create() method:
public ActionResult CreatedSuccessfully()
{
return View();
}
public ActionResult WallMessageError()
{
return View();
}
Make sure WallMessageController has got all methods and
properties as on this screen:
Note that, we are not using facebookWallMsgId variable at all. I
added it in case you want to return and present it to user.
Last thing we need to do is to create success and error view.
Right click on return View(); statement and add .cshtml views for
success/failed attempt notification pages.
Now, rebuild your solution, make sure you dont have any errors
on build, press F5 (unless you have it configured as a host), login
to facebook using facebook button and go to
/WallMessage url. If you've done everything right,
you should see following screen:
and when you click Create it should go straiiiiiiiiiight to your
facebook wall!
Good luck!
Btw. You may also consider extending session timeout to keep
facebook access token in the memory for a little bit longer. Also,
it'd be worth to add try/catch login to UserDetails() method in
case accessToken variable in nor present in Session object.
Feel free to check out my other facebook tutorials! Aaaand leave a comment if
you found it helpful. I love getting comments :)
Tagged: .NET 4
ASP.NET MVC
C#
Facebook Graph Api
Facebook Wall
JSON
MVC 4