I might be late, but a few days ago I ran into this problem and I found only a few poor solutions on the Internet. Therefore, I wrote my own solution, and I can publish it only now.
I used the DotNetOpenAuth.AspNet.Clients.OAuth2Client class, which does most of the work. I just expanded this to include scope and additional user data.
public class FacebookExtendedClient : DotNetOpenAuth.AspNet.Clients.OAuth2Client { protected FacebookClient facebookClient; protected string fields; protected string scope; protected Func<string, object, string> fieldTransformer; protected bool emailAsUsername; protected IDictionary<string, string> userData; private string[] splittedFields; private string[] splittedScope; protected const string serviceLoginBaseUrl = "https://www.facebook.com/dialog/oauth"; protected const string serviceMeBaseUrl = "https://graph.facebook.com/me"; protected const string serviceAccessTokenBaseUrl = "https://graph.facebook.com/oauth/access_token";
You can use it, and register it with OAuthWebSecurity, like this (put the RegisterAuth method in Application_Start, just like in the InternetApplication template):
public static class AuthConfig { public static void RegisterAuth() { configuration.LoadFromAppSettings(); OAuthWebSecurity.RegisterClient(new FacebookExtendedClient( "##YOUR_APP_ID##", "##YOUR_APP_SECRET##", "id,first_name,last_name,link,username,gender,email,age_range,picture.height(200)", new Func<string, object, string>(fieldsTransformer), "email")); } private static string fieldsTransformer(string key, object value) { switch (key) { case "picture": var data = (value as IDictionary<string, object>)["data"] as IDictionary<string, object>; return data["url"].ToString(); case "age_range": var min = (value as IDictionary<string, object>)["min"]; return min.ToString(); default: return value.ToString(); } } }
As you can see in the above example, the fieldsTransformer method will get the key and the selected foreach field, in which case it will convert the object received from facebook for the image to the image URL. This is a convenience method, if the Func parameter is set to null, the JSON representation of the value object will be preserved.
Obtaining customer information later, after logging in, can be done as follows:
[Authorize] public class HomeController : Controller { public ActionResult Index() { IDictionary<string, string> userData = (OAuthWebSecurity.GetOAuthClientData("facebook").AuthenticationClient as FacebookExtendedClient).UserData; string email = userData["email"];
Hope you enjoy this code even if it's a little late! :)