Quantcast
Channel: ASP.NET MVC / Web API / Web Pages
Viewing all articles
Browse latest Browse all 7925

New Post: Microsoft.AspNet.Mvc.Facebook.Controllers approach

$
0
0

Hi Erik

The project template does certainly seem like a good quick start for a Canvas Application. (I'll admit I mainly used and looked around the Nuget package of the code and Codeplex, rather than the VS installer.) Some general feedback is below.

- the typical model objects on the Canvas Application home route are Signed Request, Request Ids, Facebook Source if the native facebook flow is used; this seems a little hidden
- would normally associate Canvas homepage route with an AccountController type control logic, accessing user and friends list from an FacebookService rather than model binders
- we use an attribute IframeCookieSupportAttribute to allow forms authentication cookies cross browser within an iframe
- nearly all apps have a companion Tab Application; and adding a MobileController would create a good placeholder
- no common access to Signed Request and Access Token from within a controller; shame adding access token in ViewBag rather than an IPrincipal
- canvas authentication redirect results is very userful so a seperate ActionResult would be good for reuse
- the template should add Terms and Privacy actions to remined developers that these are required for Canvas Applications
- there is quite a variety in recent App Settings naming conventions in frameworks "facebook:AppSecret" would be my preference, as with Razor
- wonder whether getting full friends list is a good sample, as this can be a very long list; would be more explicit using async controllers
- worry that most apps now use javascript Facebook Auth Dialog, as Canvas homepage normally has to promote and invite new users
Pseudo code
public class CanvasController : Controller {
     [FacebookAuthorize(Permissions="email")]
     [IframeCookieSupport]
     public async Task<ActionResult> Index(FacebookSignedRequest signedRequest, FacebookSource facebookSource, string[] requestIds) {
         if(!string.IsNullOrEmpty(signedRequest.UserId)) {
              FacebookAuthentication.SetAuthCookie(signedRequest.UserId, signedRequest.AccessToken);
         }
         var me = FacebookService.GetMeAsync(signedRequest.AccessToken);
         var appFriends = FacebookService.GetAppFriendsAsync(signedRequest.AccessToken);
         await Task.WhenAll(me, appFriends);
         ViewBag.Me = me.Result;
         ViewBag.AppFields = appFriends.Result;
         return View();
     }
     public ActionResult TermsAndConditions() {
         return View();
     } 
     public ActionResult PrivacyPolicy() {
         return View();
     }
}
public class TabController : Controller {
     public ActionResult Index(FacebookSignedRequest signedRequest) {
         if(!signedRequest.Page.Liked) {
              return View("LikeGate");
} else {
              return View();
         }
     }
}
public class MobileController : Controller {
     [FacebookAuthorize(Permissions="email")]
     public ActionResult Index(string[] requestIds) {
          return View();
     }
}
public class FacebookAuthorizeRedirectResult : ActionResult {
    ....
}
public class FacebookUser : IPrincipal {
    public string FacebookId { get; }
    public string AccessToken { get; }
    ....
}
public static class FacebookPrincipalExtension {
    public static FacebookPrincipal AsFacebookUser(this IPrincipal user) {
        ....
    }
public class IframeCookieSupportAttribute : ActionFilterAttribute
{
    public override void OnResultExecuted(ResultExecutedContext filterContext)
    {
        var response = filterContext.HttpContext.Response;
        if (!filterContext.IsChildAction && !response.IsRequestBeingRedirected)
        {
                response.AddHeader("p3p", "CP=\"CAO PSA OUR\"");
        }
    }
}
Cheers.
Andy

Viewing all articles
Browse latest Browse all 7925

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>