Archive for the ‘MVC’ Category

The built-in Facebook OWIN provider in ASP.NET MVC can open your website to the benefits of logging in via the social networking behemoth. Still, it’s limited when it comes to pulling in profile details such as photo, birthdate, gender, and so forth. I recently implemented retrieval of those profile properties, and will explain how you can do it, too! I feel the obvious benefit is your users don’t need to manually type in their profile details, should you have similar fields in your system.

I’m assuming you’ve created and configured a Facebook app via Facebook’s Dev center, and won’t be going into that process in this article.

Determine Which Profile Fields You Need

Before we write any code, you need to know to which profile details you desire access. Facebook used to be relatively open. Not anymore! Now you need to ask permission for a ton of items, and many are no longer available. Make sure you check permissions at least every 3 months, otherwise you may find your granted permissions are no longer, well, granted, or even accessible.

Here’s a link to everything you can get: https://developers.facebook.com/docs/facebook-login/permissions/

In my case, to access the Profile photo, name information, and some other basic items, I chose:

  • public_profile
  • email
  • user_photos
  • user_about_me

I probably don’t need all these right now, but I may in the future. I figured I’d ask ahead of time.

Once you have your list, continue to the fun coding part…

Enable the Facebook Provider in Startup.Auth.cs

If you haven’t already, you’ll need to enable the Facebook provider via Startup.Auth.cs. Make sure you do this *after* any cookie authentication, so “normal” username/password logins are serviced before Facebook takes over. This should already be the case, as the default ASP.NET MVC template includes the many optional providers afterwards by default.

I suggest keeping the App ID and Secret in your config file – or at least out of code – so you can swap for differing environments as necessary. The code snippet below enables Facebook authentication, and specifies the profile fields for which we’ll be asking read permission:

You don’t have to use what I chose – it’s just what I needed for my particular case. Facebook *does* change allowed permissions and profile item visibility somewhat often. Stay on top of their developer changes – otherwise your site login may unexpectedly break.

// Enable Facebook authentication with permission grant request.
// Otherwise, you just get the user's name.
var options = new FacebookAuthenticationOptions();
options.AppId = ConfigurationManager.AppSettings["Facebook.AppId"];
options.AppSecret = ConfigurationManager.AppSettings["Facebook.AppSecret"];
options.Scope.Add("public_profile");
options.Scope.Add("email");
options.Scope.Add("user_photos");
options.Scope.Add("user_about_me");
app.UseFacebookAuthentication(options);

Install the Facebook NuGet Package

In order to easily get access to the Facebook data, I used the Facebook.NET library. It’s easy enough to install:

Install-Package Facebook

Note: I used version 7.0.6 in this example. You should be able to find the latest version and changelog at https://www.nuget.org/packages/Facebook/7.0.10-beta

Handle the Facebook External Login Callback in AccountController.cs

Once Facebook has been configured, all requests from your website will direct to Facebook, where it will ask permission, and, if granted, will redirect back to the ExternalLoginCallback action in the Account controller. It is here that I suggest you retrieve the data you’ve requested from Facebook. You’ll then modify the associated ExternalLoginConfirmation View with fields to correct or remove any information from Facebook, then continue with the account creation process on your website. That’s the part where you’ll populate the ApplicationUser entity, or whatever you decided to call it.

It’s relatively simple, as shown in the code below. The steps are as follows:

  1. Get the Facebook OAuth token with a simple HttpClient call
  2. Make the request for Profile details using the Facebook.NET library
  3. Optionally, download the Profile photo and save it somewhere

Yes, I could split this out – refactor as you see fit, and feel free to share any optimizations.

Below is the change to ExternalLoginCallback to grab the data from Facebook after the redirect:

ExternalLoginCallback Code

If you’d like to get the profile image, below is an example:

GetProfileImage Code

 

Moving Forward

I hope this article has helped answer your Facebook integration questions. If you would like additional details, please post in the comments, or message me on Twitter: @Auri

Thank you!

I went back and forth between my code and various Telerik and Stack Overflow demos of how the Kendo grid is supposed to refresh its datasource without reloading the entire grid. Finally, Telerik sent me a code example that included a function that’s not in their API documentation, but darn well should be. So, if you’re having the same issue I did, where you want to call read() on your grid’s datasource, but it simply isn’t working, here’s an example from Telerik that may help you.

The function: getKendoGrid()

Now, I keep my createDataSource() function around so I can swap out the data I’m paging. Their example uses some sample data, but you could simply use their example of creating a datasource to call your back-end JsonResult action in MVC and things can still work magically.

I hope this helps others Smile

<body>
  <div id="grid" />
  <script>
    function createDataSource() {
      return new kendo.data.DataSource({
        transport: {
          read: {
            url: "/echo",
            dataType: "json",
            method: "POST",
           
            // Simulate response
            data: {
              "json": JSON.stringify([{
                firstName: "John",
                lastName: "Smith",
                age: 25
              }])
            }
          }
        },
        pageSize: 10
      });
    }
   
    var ds = createDataSource();
   
    $("#grid").kendoGrid({
      dataSource: ds,
      autobind: false,
      scrollable: false,
      columns: ["firstName", "lastName", "age"]
    });
   
    $("#grid").getKendoGrid().dataSource.read();
  </script>
</body>
</html>

And here’s a colorized version:

image