Gal Ratner
Gal Ratner is a Techie who lives and works in Los Angeles. Follow galratner on Twitter Google
Use MVC 4 and OAuthWebSecurity to post into your users Facebook timeline

ASP.NET 4.5 and ASP.NET MVC 4 took an important step forward with the release of Visual Studio 2012.

In addition to the new features and improved performance, the main direction seems to be bundling less namespaces in the core framework and more official libraries on NuGet.

The main benefit of the new approach is the ability to update more code in an out-of-band release without being tied into the bi yearly .NET core release cycle.

In other words: Microsoft and third party vendors can update releases on weekly basis, developers can then update the dedicated NuGet package and use the most current version of the library.

Started writing an application with jQuery 1.6 and want to update? Just use the NuGet package manager to update to the latest jQuery version without manually replacing references.
This new direction opened the door to try and integrate with some of the more popular platforms today. Facebook, Twitter, Yahoo, Google and Bing.

All now have direct OAuth/OpenID integration from within .NET. If an API changes, an updated NuGet package can be released immediately.
One of the components to add the new OAuth/OpenID integration is the membership provider, adding the most requested feature: “Log in With”. Developers can now add a “Login with Facebook” button to a site and use the native .NET OAuthWebSecurity.RegisterFacebookClient method to specify a Facebook application to use.
Both MVC and Web Forms support the new functionality, however, they both go about it in different ways. Web Forms use the familiar membership provider classes and table scheme with the addition of the open source library DotNetOpenAuth and MVC is using a simpler and more flexible provider called SimpleMembershipProvider. For OAuth integration MVC 4 adds a class called OAuthWebSecurity and this class invokes DotNetOpenAuth. In fact if you create a new internet application and navigate into the AccountController, you can see the new classes in action.


 
There are many blog posts on how to use external clients in the login view so today I am going to take the integration one step forward.

I am going to post actions of users that are logged into my site using Facebook into their wall. The site I am going to use is a live site and is located here: http://yardsale-finder.com the idea being users list a yard sale, it shows up on the site and a post is showed on their Facebook timeline indicating they have just listed a new yard sale.


Let begin by adding our new application in Facebook


 
Now that we registered our application and received an appId and an appSecret we can register the new login with our RegisterAuth

 

public static void RegisterAuth()
        {
            Dictionary<stringobject> FacebooksocialData = new Dictionary<stringobject>();
 
            FacebooksocialData.Add("Icon""/Images/fb.png");
 
            OAuthWebSecurity.RegisterFacebookClient(
                appId: FacebookHelper.appId,
                appSecret: FacebookHelper.appSecret,
                displayName: "Facebook", 
                extraData: FacebooksocialData);
        }

 


Notice we also added an image in order to replace the default login button with a nice Facebook icon.


 
Next let’s navigate to ExternalLoginCallback in AccountController. This method uses the OAuthWebSecurity and will generate all of the underlying pluming of OAuth. In this method I added two lines of code:

 

 AuthenticationResult result = OAuthWebSecurity.VerifyAuthentication(Url.Action("ExternalLoginCallback"new { ReturnUrl = returnUrl }));
            if (!result.IsSuccessful)
            {
                return RedirectToAction("ExternalLoginFailure");
            }
 
            // Save the accesstoken into session
            Session["accesstoken"] = result.ExtraData["accesstoken"];
            Session["id"] = result.ExtraData["id"];

 


Since the default OAuth process returns information in the provider redirect, we simply collect it into a session. We will need the id and accesstoken in order to further communicate with Facebook’s API.
As a user creates a new yard sale listing we can give then a choice: if they have logged in using their Facebook account, let’s ask them if they wish to publish the new listing into Facebook:

@if (Session["accesstoken"] != null){
        <div class="editor-label">
            <label for="addToFacebook">Submit to Facebook?</label>
        </div>
        <div class="editor-field">
            @Html.CheckBox("addToFacebook"new { data_val = "true" })
        </div>
        }

 


If they have checked the “Submit to Facebook” button we can call the Facebook API using the accesstoken we collected into the session

 

[HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Create(UserYardsale useryardsale, double longitude, double latitude, bool addToFacebook = false)
        {
            useryardsale.UserId = WebSecurity.CurrentUserId;
            var newYardsaleLocation = DbGeography.PointFromText(String.Format("POINT({0} {1})", longitude, latitude), DbGeography.DefaultCoordinateSystemId);
 
            if (!newYardsaleLocation.IsEmpty && ModelState.IsValid)
            {
                useryardsale.Location = newYardsaleLocation;
                db.UserYardsales.Add(useryardsale);
                db.SaveChanges();
                if (addToFacebook)
                {
                    FacebookHelper facebook = new FacebookHelper();
                    facebook.PostToFacebook();
                }
                return RedirectToAction("Index");
            }
 
            return View(useryardsale);
        }

 


As we make a call to graph.facebook.com, the new status will show up on the user’s wall.

 

public async void PostToFacebook()
        {
            try
            {
                Dictionary<stringstring> properties = new Dictionary<stringstring>
            {
                { "access_token", (string)HttpContext.Current.Session["accesstoken"] },
                { "message",  WebSecurity.CurrentUserName + " Have listed a new Yardsale on http://yardsale-finder.com" }
            };
 
                FormUrlEncodedContent authentication = new FormUrlEncodedContent(properties);
                HttpClient client = new HttpClient();
                HttpResponseMessage response = await client.PostAsync(String.Format("https://graph.facebook.com/{0}/feed", HttpContext.Current.Session["id"]), authentication);
                response.EnsureSuccessStatusCode();
                dynamic result = await response.Content.ReadAsAsync<dynamic>();
            }
            catch (Exception)
            {
 
            }
        }


 
Conclusion


.NET 4.5 is indeed a very large step forward in incorporating more parts of the eco system we currently use online. The extensive use of NuGet allows developers to update applications in a rate that was until now reserved for open source libraries and in house development.


In a few simple steps, we managed to set up deep integration with Facebook that is surly to benefit our users and add to the viral value of our application.


Posted 27 Sep 2012 1:52 AM by Gal Ratner
Filed under: , ,

Powered by Community Server (Non-Commercial Edition), by Telligent Systems