Facebook Posts From Your Mvc App
May 19
.Net, Development Asp.Net Mvc, Facebook 5 Comments
In this post you will find a complete example of posting to a Facebook wall from an Asp.Net Mvc application. In addition to posting to a Facebook wall this post will show you how to display pages from your web site inside Facebook. We will be using the Facebook C# sdk found on Codeplex.
Create A Facebook Application
The first thing we want to do is create our Facebook application. Open your favorite browser and navigate to http://www.facebook.com/developers. Click the button in the upper right corner labeled “+ Set Up New App”.
Enter the name of your Facebook application, agree to the terms, and then click Create App.
Next enter the Security Check code.
Now you will enter the information about your Facebook application. In the image below you can see the information I have entered. Note that I will be running this application from localhost during development. Once I have finished developing the application I can either create a new Facebook application with the appropriate domain information or I can update this application with the production web site information. Also note the port number used for the application. I have chosen to use port 8761. You can change this to a port number of your choosing. My application will display a policy and a terms of service page.
Make sure you copy the Application ID and the Application Secret values. They will be required later. For this application, Facebook will load a specific page from my web site (http://localhost:8761/AutoPost). Make sure each of your URLs end with a slash (/).
Now that we’ve entered the necessary information for our Facebook application, it’s time to create our Mvc application.
Create Your Mvc Application
I will be using Visual Studio 2010 and Mvc3 for this example. You can use VS 2008 and Mvc2 if you wish. So create a Mvc Web Application.
The screen shots show the name of the solution as Facebook. Do not use the name Facebook. Instead use FacebookDemo or something similar. Using Facebook will cause a conflict with a dll named Facebook that gets added to the solution.
Open the project properties and select the Web tab. You will want to specify the port number. Use the same port number that was specified when we setup the Facebook application.
Next open the Package Manager Console and run the command “install-package FacebookWebMvc”. Soon you should see the output from NuGet as it installs the FacebookWebMvc package.
Open web.config and go the bottom of the file. You should see a line that looks like the following. This is where you will place your Application ID and Application Secret.
<facebookSettings appId="{app id}" appSecret="{app secret}" />
I prefer to have a view model for every view in my Mvc application. Create a folder named ViewModels at the top level of the project. Next create a subfolder for each controller. We know there will be a privacy page and a terms of service page, so create a view model for each page, plus the index page. Build the solution so Visual Studio will discover our newly created view models.
IndexViewModel.cs
PrivacyViewModel.cs
namespace FacebookDemo.ViewModels.AutoPost
{
public class PrivacyViewModel
{
public string Text { get; set; }
}
}
TOSViewModel.cs
namespace FacebookDemo.ViewModels.AutoPost
{
public class TOSViewModel
{
public string Text { get; set; }
}
}
Now, create the AutoPost controller and add actions for Privacy and TOS. The Privacy and TOS pages need some text so for now use a Lorem Ipsum generator to generate some random text. If you already have verbiage for your privacy or TOS then use it.
AutoPostController.cs
using System.Collections.Generic;
using System.Web.Mvc;
using FacebookDemo.ViewModels.AutoPost;
namespace FacebookDemo.Controllers
{
public class AutoPostController : Controller
{
//
// GET: /AutoPost/
public ActionResult Index()
{
IndexViewModel model = new IndexViewModel();
model.Text = @"This Facebook Application demonstrates how to post to a Facebook wall from an Asp.Net Mvc application. Find out more information by visiting <a>http://erictopia.com</a>.";
return View(model);
}
//
// GET: /AutoPost/Privacy
public ActionResult Privacy()
{
PrivacyViewModel model = new PrivacyViewModel();
model.Text = "Vestibulum id augue vel augue molestie sagittis et non odio. Quisque nec nulla tincidunt orci lacinia porta."
+ " Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas."
+ " Donec mattis ligula a nisi porta quis luctus neque vehicula."
+ " Proin vestibulum feugiat quam ac pretium."
+ " Proin venenatis neque nec nulla viverra sit amet convallis leo porttitor."
+ " Nunc sagittis orci ac metus consectetur aliquet."
+ " Curabitur luctus, dui eu blandit consequat, felis erat tincidunt dolor, ac viverra mauris dolor in urna."
+ " Nullam tincidunt lectus at ipsum sollicitudin bibendum."
+ " Praesent in lorem quis libero commodo dictum mollis quis ipsum."
+ " Phasellus ultrices bibendum vehicula."
+ " Duis gravida, orci sit amet semper mollis, eros mauris imperdiet ligula, eget placerat mi mauris mollis leo."
+ " Pellentesque mi libero, suscipit eget imperdiet pellentesque, consequat eget elit."
+ " Suspendisse viverra libero vitae eros tincidunt quis rutrum tortor tempus."
+ " Proin ac porttitor tellus.";
return View(model);
}
//
// GET: /AutoPost/TOS
public ActionResult TOS()
{
TOSViewModel model = new TOSViewModel();
model.Text = "Duis ullamcorper vestibulum neque quis lacinia."
+ " Sed tempor sagittis dui eget tempor."
+ " Proin tempor fermentum massa quis euismod."
+ " In convallis mauris quis nunc euismod bibendum."
+ " Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos."
+ " Duis porttitor, libero vel sodales porttitor, erat dolor hendrerit odio, id hendrerit nisl tellus eget leo."
+ " Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas."
+ " Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos."
+ " Fusce et velit sapien, a adipiscing elit. Morbi egestas vulputate euismod."
+ " Pellentesque mollis, orci hendrerit lobortis fringilla, ante massa semper nisl, eget dignissim turpis nibh et enim."
+ " Mauris dapibus mi a neque consectetur mollis."
+ " Fusce et est eget velit scelerisque molestie et ac elit."
+ " Quisque adipiscing euismod augue sit amet vestibulum."
+ " Vestibulum a erat id libero aliquet congue."
+ " Mauris semper imperdiet arcu ut pulvinar.";
return View(model);
}
} // End Class
} // End Namespace
Since these pages will be showing inside Facebook, lets create a new master page just for Facebook. We’ll copy the code from _Layout.cshtml and modify it for our needs.
_Facebook.cshtml
@ViewBag.Title
<script src="@Url.Content(" type="text/javascript"><!--mce:0--></script>
<div class="page">
<div id="header">
<div id="title">
<h1>Erictopia's AutoPost Facebook Example</h1>
</div>
<div id="logindisplay"></div>
<div id="menucontainer">
<ul id="menu">
<li>@Html.ActionLink("Home", "Index", "AutoPost")</li>
<li>@Html.ActionLink("Privacy", "Privacy", "AutoPost")</li>
<li>@Html.ActionLink("Terms of Service", "TOS", "AutoPost")</li>
</ul>
</div>
</div>
<div id="main">
@RenderBody()</div>
<div id="footer"></div>
</div>
Next create strongly typed views for the Index, Privacy, and TOS actions using the AutoPost view models we created earlier.
Index.cshtml
@model FacebookDemo.ViewModels.AutoPost.IndexViewModel
@{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Facebook.cshtml";
}
<h2>Index</h2>
@Html.Raw(@Model.Text)
Privacy.cshtml
@model FacebookDemo.ViewModels.AutoPost.PrivacyViewModel
@{
ViewBag.Title = "Privacy";
Layout = "~/Views/Shared/_Facebook.cshtml";
}
<h2>Privacy</h2>
@Model.Text
TOS.cshtml
@model FacebookDemo.ViewModels.AutoPost.TOSViewModel
@{
ViewBag.Title = "TOS";
Layout = "~/Views/Shared/_Facebook.cshtml";
}
<h2>TOS</h2>
@Model.Text
Your Solution should look like the following:
Run the solution and navigate to your Facebook application url. In this example the url is http://apps.facebook.com/erictopia. You will have to log into Facebook using the account that created the Facebook application. You should see something like the image below. When you click the tabs you see only the pages in the from the AutoPost controller. The alignment of the tabs isn’t quite right, but for an example application, this will work for now.
One last item to take care of before we move on to the wall posting code. Expand the References node in the Solution Explorer and remove Facebook, Facebook.Web, and Facebook.Web.Mvc. These references will not be necessary for the main project. You can also remove the reference to Entity Framework unless you need it. It gets added to the solution when you install the FacebookWebMvc package.
Facebook Service
Add a new Class Library project to your solution. I named mine Service.Facebook. Use whatever naming convention you follow. I prefer to use prefixes (Service.Logging, Service.Email, etc) for all of my additional projects so they are grouped together. This service will be our interface to Facebook. Everything we need to communicate with Facebook will be placed in this project. Add references to Facebook, Facebook.Web, and Facebook.Web.Mvc to this project. You will find them in the packages folder, which is a subfolder of your solution folder.
Delete the class1.cs file. Create an interface file named IFacebookService.cs with the code shown below. We will start with five methods.
- Login – this will be used to log the user into Facebook
- Logout – will log the user out of Facebook (not used in this example)
- Authorize – allows the user to authorize your Facebook application access to certain pieces of information
- GetProfile – retrieves profile information for the user (Not used in this example)
- PostMessage – allows the user to post a message to a wall
IFacebookService.cs
using System;
using System.Collections.Generic;
using Service.Facebook.Models;
namespace Service.Facebook
{
public interface IFacebookService
{
string LoginUrl(string callbackUrl, List extendedPermissions);
string LogoutUrl(string logoffUrl);
FacebookToken Authorize(string callbackUrl, List extendedPermissions, Uri requestUrl, string code);
FacebookProfile GetProfile(FacebookToken token);
void PostMessage(string wallId, FacebookToken token, FacebookMessage message);
} // End Interface
} // End Namespace
Now create a class file named FacebookService and it will need to implement the IFacebookService interface. The code is shown below.
FacebookService .cs
using System;
using System.Collections.Generic;
using System.Dynamic;
using Facebook;
using Service.Facebook.Models;
namespace Service.Facebook
{
public class FacebookService : IFacebookService
{
public string LoginUrl(string callbackUrl, List extendedPermissions)
{
FacebookOAuthClient oAuthClient = new FacebookOAuthClient(FacebookApplication.Current);
oAuthClient.RedirectUri = new Uri(callbackUrl);
Dictionary parameters = new Dictionary();
parameters.Add("display", "popup");
parameters.Add("response_type", "code");
parameters.Add("scope", string.Join(",", extendedPermissions));
Uri loginUrl = oAuthClient.GetLoginUrl(parameters);
// Calling code needs to call Redirect(loginUri);
return loginUrl.AbsoluteUri;
}
public string LogoutUrl(string logoffUrl)
{
FacebookOAuthClient oAuthClient = new FacebookOAuthClient();
oAuthClient.RedirectUri = new Uri(logoffUrl);
Uri logoutUrl = oAuthClient.GetLogoutUrl();
return logoutUrl.AbsoluteUri;
}
public FacebookToken Authorize(string callbackUrl, List extendedPermissions, Uri requestUrl, string code)
{
FacebookOAuthResult oauthResult;
FacebookToken token = null;
if (FacebookOAuthResult.TryParse(requestUrl, out oauthResult))
{
if (oauthResult.IsSuccess)
{
Dictionary exParameters = new Dictionary();
FacebookOAuthClient oAuthClient = new FacebookOAuthClient(FacebookApplication.Current);
oAuthClient.RedirectUri = new Uri(callbackUrl);
exParameters.Add("permissions", string.Join(",", extendedPermissions));
dynamic tokenResult = oAuthClient.ExchangeCodeForAccessToken(code, exParameters);
FacebookClient fbClient = new FacebookClient(tokenResult.access_token);
dynamic me = fbClient.Get("me?fields=id,name");
token = new FacebookToken(me.id.ToString(), tokenResult.access_token);
if (tokenResult.ContainsKey("expires"))
{
token.ExpiresOn = DateTimeConvertor.FromUnixTime(tokenResult.expires);
}
}
}
return token;
}
public FacebookProfile GetProfile(FacebookToken token)
{
FacebookProfile profile = new FacebookProfile();
// Todo: Check to see if the token has expired
FacebookClient client = new FacebookClient(token.AccessToken);
// Get user information
dynamic me = client.Get("/me");
profile.FullName = me.name;
profile.FirstName = me.first_name;
profile.LastName = me.last_name;
// Get their accounts
dynamic accounts = client.Get("/me/accounts");
foreach (var data in accounts.data)
{
FacebookAccount acct = new FacebookAccount();
acct.Category = data.category;
acct.Id = data.id;
acct.Name = data.name;
acct.Token = data.access_token;
profile.Accounts.Add(acct);
}
return profile;
}
public void PostMessage(string wallId, FacebookToken token, FacebookMessage message)
{
// Todo: Check to see if the AccessToken has expired
var client = new FacebookClient(token.AccessToken);
dynamic parameters = new ExpandoObject();
parameters.message = message.Message;
parameters.link = message.ArticleLink;
parameters.picture = message.PhotoLink;
parameters.name = message.Title;
parameters.caption = message.ArticleCaption;
parameters.description = message.Description;
parameters.from = token.UserId;
if (string.IsNullOrEmpty(message.ActionLabel) == false && string.IsNullOrEmpty(message.ActionLink) == false)
{
parameters.actions = new
{
name = message.ActionLabel,
link = message.ActionLink
};
}
parameters.targeting = new
{
countries = "US",
//regions = "6,53",
//locales = "6"
};
dynamic result = client.Post("/" + wallId + "/feed", parameters);
}
} // End Class
} // End Namespace
Add a new folder named Models to the Service.Facebook project. Then add the code below for our four data models, FacebookAccount, FacebookMessage, FacebookProfile, and FacebookToken.
FacebookAccount.cs
namespace Service.Facebook.Models
{
public class FacebookAccount
{
public string Id { get; set; }
public string Name { get; set; }
public string Token { get; set; }
public string Category { get; set; }
} // End Class
} // End Namespace
FacebookMessage.cs
namespace Service.Facebook.Models
{
public class FacebookMessage
{
public string Message { get; set; }
public string ArticleCaption { get; set; }
public string ArticleLink { get; set; }
public string PhotoLink { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public string ActionLabel { get; set; }
public string ActionLink { get; set; }
} // End Class
} // End Namespace
FacebookProfile.cs
using System.Collections.Generic;
namespace Service.Facebook.Models
{
public class FacebookProfile
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string FullName { get; set; }
public List Accounts { get; set; }
public FacebookProfile()
{
Accounts = new List();
}
} // End Class
} // End Namespace
FacebookToken.cs
using System;
namespace Service.Facebook.Models
{
public class FacebookToken
{
public string UserId { get; private set; }
public string AccessToken { get; private set; }
public DateTime ExpiresOn { get; set; }
public FacebookToken()
{
ExpiresOn = DateTime.MaxValue;
}
public FacebookToken(string userId, string accessToken)
:this()
{
UserId = userId;
AccessToken = accessToken;
}
} // End Class
} // End Namespace
Your Service.Facebook project should look like the following.
Posting to the Wall
Ok, lets go back to the main project and add a reference to Service.Facebook. Now crack open AutoPostController.cs. Since we setup our Facebook App to point to http://localhost:8761/AutoPost, then our actions for login and authorization will have to be in this controller as well. The complete source for AutoPostController is shown below.
Notice that Service.Facebook returns a FacebookToken when the user has authorized the application. For this example I am storing that token in Session. For your application, the information in the token should be stored in your database tied to the user’s ID. You should also add error detection code to your pages, which is not shown here.
AutoPostController.cs
using System.Collections.Generic;
using System.Web.Mvc;
using FacebookDemo.ViewModels.AutoPost;
using Service.Facebook;
using Service.Facebook.Models;
using IndexViewModel = FacebookDemo.ViewModels.AutoPost.IndexViewModel;
namespace FacebookDemo.Controllers
{
public class AutoPostController : Controller
{
private List ExtendedPermissions = new List() { "publish_stream", "offline_access", "user_about_me" /*, "manage_pages"*/ };
private const string LogoffUrl = "http://localhost:8761/";
private const string CallbackUrl = "http://localhost:8761/AutoPost/AuthorizeCallback";
private const string WallId = "Your WallID Goes Here";
//
// GET: /AutoPost/
public ActionResult Index()
{
IndexViewModel model = new IndexViewModel();
model.Text = @"This Facebook Application demonstrates how to post to a Facebook wall from an Asp.Net Mvc application. Find out more information by visiting <a>http://erictopia.com</a>.";
return View(model);
}
//
// GET: /AutoPost/Privacy
public ActionResult Privacy()
{
PrivacyViewModel model = new PrivacyViewModel();
model.Text = "Vestibulum id augue vel augue molestie sagittis et non odio. Quisque nec nulla tincidunt orci lacinia porta."
+ " Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas."
+ " Donec mattis ligula a nisi porta quis luctus neque vehicula."
+ " Proin vestibulum feugiat quam ac pretium."
+ " Proin venenatis neque nec nulla viverra sit amet convallis leo porttitor."
+ " Nunc sagittis orci ac metus consectetur aliquet."
+ " Curabitur luctus, dui eu blandit consequat, felis erat tincidunt dolor, ac viverra mauris dolor in urna."
+ " Nullam tincidunt lectus at ipsum sollicitudin bibendum."
+ " Praesent in lorem quis libero commodo dictum mollis quis ipsum."
+ " Phasellus ultrices bibendum vehicula."
+ " Duis gravida, orci sit amet semper mollis, eros mauris imperdiet ligula, eget placerat mi mauris mollis leo."
+ " Pellentesque mi libero, suscipit eget imperdiet pellentesque, consequat eget elit."
+ " Suspendisse viverra libero vitae eros tincidunt quis rutrum tortor tempus."
+ " Proin ac porttitor tellus.";
return View(model);
}
//
// GET: /AutoPost/TOS
public ActionResult TOS()
{
TOSViewModel model = new TOSViewModel();
model.Text = "Duis ullamcorper vestibulum neque quis lacinia."
+ " Sed tempor sagittis dui eget tempor."
+ " Proin tempor fermentum massa quis euismod."
+ " In convallis mauris quis nunc euismod bibendum."
+ " Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos."
+ " Duis porttitor, libero vel sodales porttitor, erat dolor hendrerit odio, id hendrerit nisl tellus eget leo."
+ " Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas."
+ " Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos."
+ " Fusce et velit sapien, a adipiscing elit. Morbi egestas vulputate euismod."
+ " Pellentesque mollis, orci hendrerit lobortis fringilla, ante massa semper nisl, eget dignissim turpis nibh et enim."
+ " Mauris dapibus mi a neque consectetur mollis."
+ " Fusce et est eget velit scelerisque molestie et ac elit."
+ " Quisque adipiscing euismod augue sit amet vestibulum."
+ " Vestibulum a erat id libero aliquet congue."
+ " Mauris semper imperdiet arcu ut pulvinar.";
return View(model);
}
//
// GET: /AutoPost/Authorize
public ActionResult Authorize()
{
IFacebookService svc = new FacebookService();
return Redirect(svc.LoginUrl(CallbackUrl, ExtendedPermissions));
}
//
// GET: /AutoPost/AuthorizeCallback
public ActionResult AuthorizeCallback(string code, string state)
{
IFacebookService svc = new FacebookService();
FacebookToken token = svc.Authorize(CallbackUrl, ExtendedPermissions, Request.Url, code);
// prevent open redirection attack by checking if the url is local.
if (Url.IsLocalUrl(state))
{
return Redirect(state);
}
if (token != null)
{
SaveToken(token);
}
return RedirectToAction("Post");
}
//
// GET: /AutoPost/Post
[HttpGet]
public ActionResult Post()
{
if (IsAuthorized() == false)
{
return RedirectToAction("Authorize");
}
PostViewModel model = new PostViewModel();
return View(model);
}
//
// POST: /AutoPost/Post
[HttpPost]
public ActionResult Post(PostViewModel model)
{
if (ModelState.IsValid)
{
IFacebookService svc = new FacebookService();
FacebookMessage message = new FacebookMessage();
message.ActionLabel = model.ActionLabel;
message.ActionLink = model.ActionLink;
message.ArticleCaption = model.ArticleCaption;
message.ArticleLink = model.ArticleLink;
message.Description = model.Description;
message.Message = model.Message;
message.PhotoLink = model.PhotoLink;
message.Title = model.Title;
svc.PostMessage(WallId, GetToken(), message);
model.PostMessage = "Succesful post to Facebook wall";
}
return View(model);
}
#region - Helper Methods -
private bool IsAuthorized()
{
return (Session["FacebookToken"] != null);
}
private void SaveToken(FacebookToken token)
{
Session.Add("FacebookToken", token);
}
private FacebookToken GetToken()
{
if (IsAuthorized() == false)
return null;
return (FacebookToken)Session["FacebookToken"];
}
#endregion
} // End Class
} // End Namespace
One item you will need to set is the WallId. You can use your own account or create a page. To find the ID, edit your profile. The ID will be appended to the url. In the case of a page, it will be in the url whenever you navigate to the page.
We need to create a new ViewModel for the Post view. That class is listed below and should be placed into the AutoPost folder.
PostViewModel.cs.
using System.ComponentModel.DataAnnotations;
namespace FacebookDemo.ViewModels.AutoPost
{
public class PostViewModel
{
public string PostMessage { get; set; }
[Required]
[StringLength(420)]
[Display(Name = "Your Message")]
public string Message { get; set; }
[StringLength(255)]
[Display(Name = "Article Title")]
public string Title { get; set; }
[StringLength(255)]
[Display(Name = "Article Link")]
public string ArticleLink { get; set; }
[StringLength(255)]
[Display(Name = "Photo Link")]
public string PhotoLink { get; set; }
[StringLength(255)]
[Display(Name = "Link Caption")]
public string ArticleCaption { get; set; }
[StringLength(255)]
[Display(Name = "Description")]
public string Description { get; set; }
[StringLength(255)]
[Display(Name = "Action Label")]
public string ActionLabel { get; set; }
[StringLength(255)]
[Display(Name = "Action Link")]
public string ActionLink { get; set; }
} // End Class
} // End Namespace
Now create a strongly typed view named Post using the PostViewModel class.
Post.cshtml
@model FacebookDemo.ViewModels.AutoPost.PostViewModel
@{
ViewBag.Title = "Post";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Post</h2>
<script src="@Url.Content(" type="text/javascript"><!--mce:1--></script>
<script src="@Url.Content(" type="text/javascript"><!--mce:2--></script>
@if (string.IsNullOrEmpty(Model.PostMessage) == false)
{
@Model.PostMessage
}
@using (Html.BeginForm()) {
@Html.ValidationSummary(true)
<fieldset>
<div class="editor-label">
@Html.LabelFor(model => model.Message)</div>
<div class="editor-field">
@Html.TextAreaFor(model => model.Message, new { cols=60, rows=4 })
@Html.ValidationMessageFor(model => model.Message)</div>
<div class="editor-label">
@Html.LabelFor(model => model.ArticleCaption)</div>
<div class="editor-field">
@Html.EditorFor(model => model.ArticleCaption)
@Html.ValidationMessageFor(model => model.ArticleCaption)</div>
<div class="editor-label">
@Html.LabelFor(model => model.ArticleLink)</div>
<div class="editor-field">
@Html.EditorFor(model => model.ArticleLink)
@Html.ValidationMessageFor(model => model.ArticleLink)</div>
<div class="editor-label">
@Html.LabelFor(model => model.PhotoLink)</div>
<div class="editor-field">
@Html.EditorFor(model => model.PhotoLink)
@Html.ValidationMessageFor(model => model.PhotoLink)</div>
<div class="editor-label">
@Html.LabelFor(model => model.Title)</div>
<div class="editor-field">
@Html.EditorFor(model => model.Title)
@Html.ValidationMessageFor(model => model.Title)</div>
<div class="editor-label">
@Html.LabelFor(model => model.Description)</div>
<div class="editor-field">
@Html.EditorFor(model => model.Description)
@Html.ValidationMessageFor(model => model.Description)</div>
<div class="editor-label">
@Html.LabelFor(model => model.ActionLabel)</div>
<div class="editor-field">
@Html.EditorFor(model => model.ActionLabel)
@Html.ValidationMessageFor(model => model.ActionLabel)</div>
<div class="editor-label">
@Html.LabelFor(model => model.ActionLink)</div>
<div class="editor-field">
@Html.EditorFor(model => model.ActionLink)
@Html.ValidationMessageFor(model => model.ActionLink)</div>
<input type="submit" value="Post" /></fieldset>
}
Now run the solution. Click the “Post to Wall” tab and complete the form. You can choose to enter just a message or you can provide a link and a photo. Try posting messages with various fields completed to see what gets posted to the wall.
Now open Facebook and view your wall or the page’s wall. You will see your message.
Enjoy and let me know how you are integrating this code into your own projects.













May 26, 2011 @ 12:43:32
Hi,
How do you renew the authorization token?
I am having a few issues with it.
You have got it commented in your code:
// Todo: Check to see if the AccessToken has expired
Cheers
May 29, 2011 @ 13:49:02
You will need to call the Authorize method again, if the token has expired. If you use an extended permission of “offline_access”, then the token should not expire.
The example code has “offline_access” in the ExtendedPermissions property. So the token that gets returned does not expire.
Aug 05, 2011 @ 09:29:12
ericü dont you have a download link?
))
Mar 30, 2012 @ 03:22:13
hi eric, is there any download link for the following.
Apr 21, 2012 @ 03:37:59
Hi Eric,
Thanks for your efforts. This is really what I need in my project but I am getting errors in building the app.
Could you please mail the entire project to me, that would be highly appreciated.
Regards,
Amit Raj