{"id":234,"date":"2014-09-09T14:38:53","date_gmt":"2014-09-09T14:38:53","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/webdev\/2014\/09\/09\/announcing-microsoft-aspnet-facebook-1-1-beta\/"},"modified":"2022-08-08T04:05:46","modified_gmt":"2022-08-08T11:05:46","slug":"announcing-microsoft-aspnet-facebook-1-1-beta","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/dotnet\/announcing-microsoft-aspnet-facebook-1-1-beta\/","title":{"rendered":"Announcing Microsoft.AspNet.Facebook 1.1 beta"},"content":{"rendered":"<p>This past June we released the first version of the <b>Microsoft.AspNet.Facebook <\/b>NuGet package and the corresponding Visual Studio template. Today we released an update to this package: <strong>Microsoft.AspNet.Facebook<\/strong> <a href=\"https:\/\/www.nuget.org\/packages\/Microsoft.AspNet.Facebook\/1.1.0-beta\">1.1 beta<\/a>. In this release, we enabled better support for the Safari browser and added a new feature that gives developers the ability to add custom logic for browsers that do not have cookies enabled. The Visual Studio template that uses this updated package will be released soon. To read more about the features in the 1.0 package, please see the <a href=\"http:\/\/blogs.msdn.com\/b\/webdev\/archive\/2014\/06\/10\/updating-the-mvc-facebook-api.aspx\">blog post<\/a> from the initial announcement. The Visual Studio 1.0 template can be found <a href=\"http:\/\/go.microsoft.com\/fwlink\/?LinkID=509965&amp;clcid=0x409\">here<\/a>.<\/p>\n<p>The <b>Microsoft.AspNet.Facebook <\/b>package tracks permissions requested of the user in a cookie to determine skipped permissions. Prior to this update, skipping optional permissions for ASP.NET Facebook Applications resulted in infinite loops when run in Safari. This was happening because Safari blocked cookies that the <b>Microsoft.AspNet.Facebook <\/b>package attempted to create. Because cookies were not created, the package did not have a way to determine which permissions were skipped so the permissions dialog would repeat infinitely. Also, there was no error message that could inform the user what was happening. We made this experience much better in this release. Developers can now redirect to an error page when cookies are not enabled.<\/p>\n<h3>Features added in this release<\/h3>\n<h4>CannotCreateCookieRedirectPath Configuration<\/h4>\n<p>You can set the <i>CannotCreateCookieRedirectPath <\/i>in web.config to control where users are redirected when the framework cannot create cookies. If the configuration value is set, the framework redirects the user to the error page; otherwise, it redirects to https:\/\/www.facebook.com.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/aspnet\/wp-content\/uploads\/sites\/16\/2014\/09\/0763.clip_image0013_thumb_325753EE.png\"><img decoding=\"async\" title=\"clip_image001[3]\" style=\"border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px\" border=\"0\" alt=\"clip_image001[3]\" src=\"https:\/\/devblogs.microsoft.com\/aspnet\/wp-content\/uploads\/sites\/16\/2014\/09\/0763.clip_image0013_thumb_325753EE.png\" width=\"551\" height=\"36\" \/><\/a><\/p>\n<h4>OnCannotCreateCookies Hook<\/h4>\n<p>As the name suggests, this hook gets called if the <b>Microsoft.AspNet.Facebook<\/b> package cannot create cookies due to browser restrictions or the user\u2019s settings. By default, it looks for a redirect path provided by the <i>CannotCreateCookieRedirectPath<\/i> in <i>FacebookConfiguration<\/i>. <\/p>\n<p><b>NOTE: <\/b>Once this hook gets called NO other prompts are triggered unless the default <i>OnCannotCreateCookies<\/i> logic is overridden.<\/p>\n<p>Developers can override this hook to add their custom logic if needed.<\/p>\n<p>A few examples are mentioned below.<\/p>\n<h5>Set permissionContext.Result to null<\/h5>\n<p>Instead of redirecting to an error page or https:\/\/www.facebook.com, this takes the user directly to the app without prompting for permissions.<\/p>\n<div id=\"scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:114d8794-9141-4994-beca-fd1fae11be9e\" class=\"wlWriterEditableSmartContent\" style=\"float: none;padding-bottom: 0px;padding-top: 0px;padding-left: 0px;margin: 0px;padding-right: 0px\">\n<div class=\"le-pavsc-container\">\n<div style=\"background-color: #ffffff;max-height: 300px;overflow: auto;padding: 2px 5px\"><span style=\"background:#ffffff;color:#0000ff\">protected<\/span><span style=\"background:#ffffff;color:#000000\"> <\/span><span style=\"background:#ffffff;color:#0000ff\">override<\/span><span style=\"background:#ffffff;color:#000000\"> <\/span><span style=\"background:#ffffff;color:#0000ff\">void<\/span><span style=\"background:#ffffff;color:#000000\"> OnCannotCreateCookies(<\/span><span style=\"background:#ffffff;color:#2b91af\">PermissionContext<\/span><span style=\"background:#ffffff;color:#000000\"> permissionContext)<\/span><br> <span style=\"background:#ffffff;color:#000000\">{<\/span><br> <span style=\"background:#ffffff;color:#000000\">\u00a0\u00a0\u00a0\u00a0permissionContext.Result = <\/span><span style=\"background:#ffffff;color:#0000ff\">null<\/span><span style=\"background:#ffffff;color:#000000\">;<\/span><br> <span style=\"background:#ffffff;color:#000000\">}<\/span><\/div>\n<\/p><\/div>\n<\/p><\/div>\n<h5>Redirect to an action<\/h5>\n<p>The developer can redirect to an action when this hook gets called.<\/p>\n<div id=\"scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:35f24ce9-a5d7-4454-aa28-a3a97c9a5975\" class=\"wlWriterEditableSmartContent\" style=\"float: none;padding-bottom: 0px;padding-top: 0px;padding-left: 0px;margin: 0px;padding-right: 0px\">\n<div class=\"le-pavsc-container\">\n<div style=\"background-color: #ffffff;max-height: 300px;overflow: auto;padding: 2px 5px\"><span style=\"background:#ffffff;color:#0000ff\">protected<\/span><span style=\"background:#ffffff;color:#000000\"> <\/span><span style=\"background:#ffffff;color:#0000ff\">override<\/span><span style=\"background:#ffffff;color:#000000\"> <\/span><span style=\"background:#ffffff;color:#0000ff\">void<\/span><span style=\"background:#ffffff;color:#000000\"> OnCannotCreateCookies(<\/span><span style=\"background:#ffffff;color:#2b91af\">PermissionContext<\/span><span style=\"background:#ffffff;color:#000000\"> permissionContext)<\/span><br> <span style=\"background:#ffffff;color:#000000\">{<\/span><br> <span style=\"background:#ffffff;color:#000000\">\u00a0\u00a0\u00a0\u00a0permissionContext.Result = <\/span><span style=\"background:#ffffff;color:#0000ff\">new<\/span><span style=\"background:#ffffff;color:#000000\"> <\/span><span style=\"background:#ffffff;color:#2b91af\">RedirectToRouteResult<\/span><span style=\"background:#ffffff;color:#000000\">(<\/span><br> <span style=\"background:#ffffff;color:#000000\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"background:#ffffff;color:#0000ff\">new<\/span><span style=\"background:#ffffff;color:#000000\"> <\/span><span style=\"background:#ffffff;color:#2b91af\">RouteValueDictionary<\/span><br> <span style=\"background:#ffffff;color:#000000\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{<\/span><br> <span style=\"background:#ffffff;color:#000000\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{ <\/span><span style=\"background:#ffffff;color:#a31515\">&quot;controller&quot;<\/span><span style=\"background:#ffffff;color:#000000\">, <\/span><span style=\"background:#ffffff;color:#a31515\">&quot;home&quot;<\/span><span style=\"background:#ffffff;color:#000000\"> },<\/span><br> <span style=\"background:#ffffff;color:#000000\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{ <\/span><span style=\"background:#ffffff;color:#a31515\">&quot;action&quot;<\/span><span style=\"background:#ffffff;color:#000000\">, <\/span><span style=\"background:#ffffff;color:#a31515\">&quot;foo&quot;<\/span><span style=\"background:#ffffff;color:#000000\"> }<\/span><br> <span style=\"background:#ffffff;color:#000000\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0});<\/span><br> <span style=\"background:#ffffff;color:#000000\">}<\/span><\/div>\n<\/p><\/div>\n<\/p><\/div>\n<h5>Do NOT set permissionContext.Result to ShowPrompt<\/h5>\n<p>Setting permissionContext.Result to <i>ShowPrompt<\/i> within the <i>OnCannotCreateCookies<\/i> hook causes infinite prompt loops.<\/p>\n<h5>Enabling consistent behavior with cookie enabled browsers<\/h5>\n<p>The <i>OnPermissionPrompt<\/i> and <i>OnCannotCreateCookies<\/i> methods can be overridden to enable consistent behavior between cookie and non-cookie enabled browsers. In such cases, the requested permissions (that would normally be stored in a cookie) should be persisted to a database. Here is one way to do that.<\/p>\n<p>This example uses <b>EntityFramework<\/b> to access the database. It creates a class called <em>FacebookPermission<\/em> to store permissions and a class called <em>FacebookPermissionDbContext<\/em> for storing permissions in a database.<\/p>\n<p>To get started, open Visual Studio 2013, create a new ASP.NET Facebook application. Then, add the following classes to the project:<\/p>\n<div id=\"scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:6c2f9f5e-24bf-4419-8690-a22c52864c3f\" class=\"wlWriterEditableSmartContent\" style=\"float: none;padding-bottom: 0px;padding-top: 0px;padding-left: 0px;margin: 0px;padding-right: 0px\">\n<div class=\"le-pavsc-container\">\n<div style=\"background-color: #ffffff;max-height: 300px;overflow: auto;padding: 2px 5px\"><span style=\"background:#ffffff;color:#0000ff\">public<\/span><span style=\"background:#ffffff;color:#000000\"> <\/span><span style=\"background:#ffffff;color:#0000ff\">class<\/span><span style=\"background:#ffffff;color:#000000\"> <\/span><span style=\"background:#ffffff;color:#2b91af\">FacebookPermission<\/span><br> <span style=\"background:#ffffff;color:#000000\">{<\/span><br> <span style=\"background:#ffffff;color:#000000\">\u00a0\u00a0\u00a0\u00a0[<\/span><span style=\"background:#ffffff;color:#2b91af\">Key<\/span><span style=\"background:#ffffff;color:#000000\">]<\/span><br> <span style=\"background:#ffffff;color:#000000\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"background:#ffffff;color:#0000ff\">public<\/span><span style=\"background:#ffffff;color:#000000\"> <\/span><span style=\"background:#ffffff;color:#0000ff\">int<\/span><span style=\"background:#ffffff;color:#000000\"> FacebookPermissionId { <\/span><span style=\"background:#ffffff;color:#0000ff\">get<\/span><span style=\"background:#ffffff;color:#000000\">; <\/span><span style=\"background:#ffffff;color:#0000ff\">set<\/span><span style=\"background:#ffffff;color:#000000\">; }<\/span><br> <span style=\"background:#ffffff;color:#000000\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"background:#ffffff;color:#0000ff\">public<\/span><span style=\"background:#ffffff;color:#000000\"> <\/span><span style=\"background:#ffffff;color:#0000ff\">string<\/span><span style=\"background:#ffffff;color:#000000\"> User { <\/span><span style=\"background:#ffffff;color:#0000ff\">get<\/span><span style=\"background:#ffffff;color:#000000\">; <\/span><span style=\"background:#ffffff;color:#0000ff\">set<\/span><span style=\"background:#ffffff;color:#000000\">; }<\/span><br> <span style=\"background:#ffffff;color:#000000\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"background:#ffffff;color:#0000ff\">public<\/span><span style=\"background:#ffffff;color:#000000\"> <\/span><span style=\"background:#ffffff;color:#0000ff\">string<\/span><span style=\"background:#ffffff;color:#000000\"> RequestedPermissions { <\/span><span style=\"background:#ffffff;color:#0000ff\">get<\/span><span style=\"background:#ffffff;color:#000000\">; <\/span><span style=\"background:#ffffff;color:#0000ff\">set<\/span><span style=\"background:#ffffff;color:#000000\">; }<\/span><br> <span style=\"background:#ffffff;color:#000000\">}<\/span><\/div>\n<\/p><\/div>\n<\/p><\/div>\n<div id=\"scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:9ddafe27-3de9-41c2-aed6-6e95203e1d26\" class=\"wlWriterEditableSmartContent\" style=\"float: none;padding-bottom: 0px;padding-top: 0px;padding-left: 0px;margin: 0px;padding-right: 0px\">\n<div class=\"le-pavsc-container\">\n<div style=\"background-color: #ffffff;max-height: 300px;overflow: auto;padding: 2px 5px\"><span style=\"background:#ffffff;color:#0000ff\">public<\/span><span style=\"background:#ffffff;color:#000000\"> <\/span><span style=\"background:#ffffff;color:#0000ff\">class<\/span><span style=\"background:#ffffff;color:#000000\"> <\/span><span style=\"background:#ffffff;color:#2b91af\">FacebookPermissionDbContext<\/span><span style=\"background:#ffffff;color:#000000\"> : <\/span><span style=\"background:#ffffff;color:#2b91af\">DbContext<\/span><br> <span style=\"background:#ffffff;color:#000000\">{<\/span><br> <span style=\"background:#ffffff;color:#000000\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"background:#ffffff;color:#0000ff\">public<\/span><span style=\"background:#ffffff;color:#000000\"> FacebookPermissionDbContext()<\/span><br> <span style=\"background:#ffffff;color:#000000\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0: <\/span><span style=\"background:#ffffff;color:#0000ff\">base<\/span><span style=\"background:#ffffff;color:#000000\">(<\/span><span style=\"background:#ffffff;color:#a31515\">&quot;DefaultConnection&quot;<\/span><span style=\"background:#ffffff;color:#000000\">)<\/span><br> <span style=\"background:#ffffff;color:#000000\">\u00a0\u00a0\u00a0\u00a0{<\/span><br> <span style=\"background:#ffffff;color:#000000\">\u00a0\u00a0\u00a0\u00a0}<\/span><\/p>\n<p> <span style=\"background:#ffffff;color:#000000\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"background:#ffffff;color:#0000ff\">protected<\/span><span style=\"background:#ffffff;color:#000000\"> <\/span><span style=\"background:#ffffff;color:#0000ff\">override<\/span><span style=\"background:#ffffff;color:#000000\"> <\/span><span style=\"background:#ffffff;color:#0000ff\">void<\/span><span style=\"background:#ffffff;color:#000000\"> OnModelCreating(<\/span><span style=\"background:#ffffff;color:#2b91af\">DbModelBuilder<\/span><span style=\"background:#ffffff;color:#000000\"> modelBuilder)<\/span><br> <span style=\"background:#ffffff;color:#000000\">\u00a0\u00a0\u00a0\u00a0{<\/span><br> <span style=\"background:#ffffff;color:#000000\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"background:#ffffff;color:#0000ff\">base<\/span><span style=\"background:#ffffff;color:#000000\">.OnModelCreating(modelBuilder);<\/span><br> <span style=\"background:#ffffff;color:#000000\">\u00a0\u00a0\u00a0\u00a0}<\/span><\/p>\n<p> <span style=\"background:#ffffff;color:#000000\">\u00a0\u00a0\u00a0<\/span><span style=\"background:#ffffff;color:#0000ff\">public<\/span><span style=\"background:#ffffff;color:#000000\"> <\/span><span style=\"background:#ffffff;color:#0000ff\">virtual<\/span><span style=\"background:#ffffff;color:#000000\"> <\/span><span style=\"background:#ffffff;color:#2b91af\">DbSet<\/span><span style=\"background:#ffffff;color:#000000\">&lt;<\/span><span style=\"background:#ffffff;color:#2b91af\">FacebookPermission<\/span><span style=\"background:#ffffff;color:#000000\">&gt; FacebookPermissions { <\/span><span style=\"background:#ffffff;color:#0000ff\">get<\/span><span style=\"background:#ffffff;color:#000000\">; <\/span><span style=\"background:#ffffff;color:#0000ff\">set<\/span><span style=\"background:#ffffff;color:#000000\">; }<\/span><br> <span style=\"background:#ffffff;color:#000000\">}<\/span><\/div>\n<\/p><\/div>\n<\/p><\/div>\n<p>Next, create a custom authorization filter that derives from <i>FacebookAuthorizeFilte<\/i>r and override the <i>OnPermissionPrompt<\/i> and <i>OnCannotCreateCookies<\/i> methods.<\/p>\n<p><i>OnPermissionPrompt<\/i> reads RequestedPermissions from the database and derives skipped permissions. Based on these permissions either <i>OnDeniedPermissionPrompt<\/i> or <i>OnPermissionPrompt <\/i>will be invoked.<\/p>\n<p>The <i>OnCannotCreateCookies<\/i> method persists the requested permissions to the database and calls <i>OnDeniedPermissionPromt<\/i> on the base class<\/p>\n<div id=\"scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:92baf8b0-a3fa-4566-abf7-6d75aed149d0\" class=\"wlWriterEditableSmartContent\" style=\"float: none;padding-bottom: 0px;padding-top: 0px;padding-left: 0px;margin: 0px;padding-right: 0px\">\n<div class=\"le-pavsc-container\">\n<div style=\"background-color: #ffffff;max-height: 300px;overflow: auto;padding: 2px 5px\"><span style=\"background:#ffffff;color:#0000ff\">public<\/span><span style=\"background:#ffffff;color:#000000\"> <\/span><span style=\"background:#ffffff;color:#0000ff\">class<\/span><span style=\"background:#ffffff;color:#000000\"> <\/span><span style=\"background:#ffffff;color:#2b91af\">CustomAuthorizeFilter<\/span><span style=\"background:#ffffff;color:#000000\"> : <\/span><span style=\"background:#ffffff;color:#2b91af\">FacebookAuthorizeFilter<\/span><br> <span style=\"background:#ffffff;color:#000000\">{<\/span><br> <span style=\"background:#ffffff;color:#000000\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"background:#ffffff;color:#0000ff\">private<\/span><span style=\"background:#ffffff;color:#000000\"> <\/span><span style=\"background:#ffffff;color:#0000ff\">static<\/span><span style=\"background:#ffffff;color:#000000\"> <\/span><span style=\"background:#ffffff;color:#2b91af\">FacebookPermissionDbContext<\/span><span style=\"background:#ffffff;color:#000000\"> db = <\/span><span style=\"background:#ffffff;color:#0000ff\">new<\/span><span style=\"background:#ffffff;color:#000000\"> <\/span><span style=\"background:#ffffff;color:#2b91af\">FacebookPermissionDbContext<\/span><span style=\"background:#ffffff;color:#000000\">();<\/span><\/p>\n<p> <span style=\"background:#ffffff;color:#000000\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"background:#ffffff;color:#0000ff\">public<\/span><span style=\"background:#ffffff;color:#000000\"> CustomAuthorizeFilter(<\/span><span style=\"background:#ffffff;color:#2b91af\">FacebookConfiguration<\/span><span style=\"background:#ffffff;color:#000000\"> config)<\/span><br> <span style=\"background:#ffffff;color:#000000\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0: <\/span><span style=\"background:#ffffff;color:#0000ff\">base<\/span><span style=\"background:#ffffff;color:#000000\">(config)<\/span><br> <span style=\"background:#ffffff;color:#000000\">\u00a0\u00a0\u00a0\u00a0{<\/span><\/p>\n<p> <span style=\"background:#ffffff;color:#000000\">\u00a0\u00a0\u00a0\u00a0}<\/span><\/p>\n<p> <span style=\"background:#ffffff;color:#000000\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"background:#ffffff;color:#0000ff\">protected<\/span><span style=\"background:#ffffff;color:#000000\"> <\/span><span style=\"background:#ffffff;color:#0000ff\">override<\/span><span style=\"background:#ffffff;color:#000000\"> <\/span><span style=\"background:#ffffff;color:#0000ff\">void<\/span><span style=\"background:#ffffff;color:#000000\"> OnPermissionPrompt(<\/span><span style=\"background:#ffffff;color:#2b91af\">PermissionContext<\/span><span style=\"background:#ffffff;color:#000000\"> context)<\/span><br> <span style=\"background:#ffffff;color:#000000\">\u00a0\u00a0\u00a0\u00a0{<\/span><br> <span style=\"background:#ffffff;color:#000000\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"background:#ffffff;color:#2b91af\">FacebookPermission<\/span><span style=\"background:#ffffff;color:#000000\"> storedPermission = db.FacebookPermissions.Where(p =&gt; p.User == context.FacebookContext.UserId).FirstOrDefault();<\/span><br> <span style=\"background:#ffffff;color:#000000\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"background:#ffffff;color:#0000ff\">if<\/span><span style=\"background:#ffffff;color:#000000\"> (storedPermission == <\/span><span style=\"background:#ffffff;color:#0000ff\">null<\/span><span style=\"background:#ffffff;color:#000000\">)<\/span><br> <span style=\"background:#ffffff;color:#000000\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{<\/span><br> <span style=\"background:#ffffff;color:#000000\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"background:#ffffff;color:#008000\">\/\/ This calls into base implementation, you can replace this with your own logic.<\/span><br> <span style=\"background:#ffffff;color:#000000\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"background:#ffffff;color:#0000ff\">base<\/span><span style=\"background:#ffffff;color:#000000\">.OnPermissionPrompt(context);<\/span><br> <span style=\"background:#ffffff;color:#000000\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span><br> <span style=\"background:#ffffff;color:#000000\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"background:#ffffff;color:#0000ff\">else<\/span><br> <span style=\"background:#ffffff;color:#000000\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{<\/span><br> <span style=\"background:#ffffff;color:#000000\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"background:#ffffff;color:#2b91af\">IEnumerable<\/span><span style=\"background:#ffffff;color:#000000\">&lt;<\/span><span style=\"background:#ffffff;color:#0000ff\">string<\/span><span style=\"background:#ffffff;color:#000000\">&gt; requestedPermissions = storedPermission.RequestedPermissions.Split(<\/span><span style=\"background:#ffffff;color:#a31515\">&#039;,&#039;<\/span><span style=\"background:#ffffff;color:#000000\">);<\/span><br> <span style=\"background:#ffffff;color:#000000\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"background:#ffffff;color:#2b91af\">IEnumerable<\/span><span style=\"background:#ffffff;color:#000000\">&lt;<\/span><span style=\"background:#ffffff;color:#0000ff\">string<\/span><span style=\"background:#ffffff;color:#000000\">&gt; declinedPermissions = context.DeclinedPermissions;<\/span><br> <span style=\"background:#ffffff;color:#000000\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0context.SkippedPermissions = requestedPermissions.Except(context.DeclinedPermissions);<\/span><br> <span style=\"background:#ffffff;color:#000000\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"background:#ffffff;color:#0000ff\">bool<\/span><span style=\"background:#ffffff;color:#000000\"> deniedPermissions = context.MissingPermissions.Where(<\/span><br> <span style=\"background:#ffffff;color:#000000\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0permission =&gt; context.DeclinedPermissions.Contains(permission) ||<\/span><br> <span style=\"background:#ffffff;color:#000000\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0context.SkippedPermissions.Contains(permission)).Any();<\/span><\/p>\n<p> <span style=\"background:#ffffff;color:#000000\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"background:#ffffff;color:#0000ff\">if<\/span><span style=\"background:#ffffff;color:#000000\"> (deniedPermissions)<\/span><br> <span style=\"background:#ffffff;color:#000000\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{<\/span><br> <span style=\"background:#ffffff;color:#000000\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"background:#ffffff;color:#008000\">\/\/ This calls into base implementation, you can replace this with your own logic.<\/span><br> <span style=\"background:#ffffff;color:#000000\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"background:#ffffff;color:#0000ff\">base<\/span><span style=\"background:#ffffff;color:#000000\">.OnDeniedPermissionPrompt(context);<\/span><br> <span style=\"background:#ffffff;color:#000000\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span><br> <span style=\"background:#ffffff;color:#000000\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"background:#ffffff;color:#0000ff\">else<\/span><br> <span style=\"background:#ffffff;color:#000000\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{<\/span><br> <span style=\"background:#ffffff;color:#000000\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"background:#ffffff;color:#008000\">\/\/ This calls into base implementation, you can replace this with your own logic.<\/span><br> <span style=\"background:#ffffff;color:#000000\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"background:#ffffff;color:#0000ff\">base<\/span><span style=\"background:#ffffff;color:#000000\">.OnPermissionPrompt(context);<\/span><br> <span style=\"background:#ffffff;color:#000000\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span><\/p>\n<p> <span style=\"background:#ffffff;color:#000000\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span><br> <span style=\"background:#ffffff;color:#000000\">\u00a0\u00a0\u00a0\u00a0}<\/span><\/p>\n<p> <span style=\"background:#ffffff;color:#000000\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"background:#ffffff;color:#0000ff\">protected<\/span><span style=\"background:#ffffff;color:#000000\"> <\/span><span style=\"background:#ffffff;color:#0000ff\">override<\/span><span style=\"background:#ffffff;color:#000000\"> <\/span><span style=\"background:#ffffff;color:#0000ff\">void<\/span><span style=\"background:#ffffff;color:#000000\"> OnCannotCreateCookies(<\/span><span style=\"background:#ffffff;color:#2b91af\">PermissionContext<\/span><span style=\"background:#ffffff;color:#000000\"> context)<\/span><br> <span style=\"background:#ffffff;color:#000000\">\u00a0\u00a0\u00a0\u00a0{<\/span><br> <span style=\"background:#ffffff;color:#000000\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"background:#ffffff;color:#2b91af\">FacebookPermission<\/span><span style=\"background:#ffffff;color:#000000\"> storedPermission = db.FacebookPermissions.Where(p =&gt; p.User == context.FacebookContext.UserId).FirstOrDefault();<\/span><br> <span style=\"background:#ffffff;color:#000000\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"background:#ffffff;color:#2b91af\">IEnumerable<\/span><span style=\"background:#ffffff;color:#000000\">&lt;<\/span><span style=\"background:#ffffff;color:#0000ff\">string<\/span><span style=\"background:#ffffff;color:#000000\">&gt; requestedPermissions = context.RequiredPermissions;<\/span><br> <span style=\"background:#ffffff;color:#000000\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"background:#ffffff;color:#0000ff\">string<\/span><span style=\"background:#ffffff;color:#000000\"> permissionString = <\/span><span style=\"background:#ffffff;color:#2b91af\">String<\/span><span style=\"background:#ffffff;color:#000000\">.Join(<\/span><span style=\"background:#ffffff;color:#a31515\">&quot;,&quot;<\/span><span style=\"background:#ffffff;color:#000000\">, requestedPermissions);<\/span><br> <span style=\"background:#ffffff;color:#000000\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"background:#ffffff;color:#0000ff\">if<\/span><span style=\"background:#ffffff;color:#000000\"> (storedPermission == <\/span><span style=\"background:#ffffff;color:#0000ff\">null<\/span><span style=\"background:#ffffff;color:#000000\">)<\/span><br> <span style=\"background:#ffffff;color:#000000\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{<\/span><br> <span style=\"background:#ffffff;color:#000000\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0db.FacebookPermissions.Add(<\/span><span style=\"background:#ffffff;color:#0000ff\">new<\/span><span style=\"background:#ffffff;color:#000000\"> <\/span><span style=\"background:#ffffff;color:#2b91af\">FacebookPermission<\/span><br> <span style=\"background:#ffffff;color:#000000\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{<\/span><br> <span style=\"background:#ffffff;color:#000000\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0User = context.FacebookContext.UserId,<\/span><br> <span style=\"background:#ffffff;color:#000000\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0RequestedPermissions = permissionString<\/span><br> <span style=\"background:#ffffff;color:#000000\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0});<\/span><br> <span style=\"background:#ffffff;color:#000000\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span><br> <span style=\"background:#ffffff;color:#000000\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"background:#ffffff;color:#0000ff\">else<\/span><br> <span style=\"background:#ffffff;color:#000000\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{<\/span><br> <span style=\"background:#ffffff;color:#000000\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"background:#ffffff;color:#0000ff\">if<\/span><span style=\"background:#ffffff;color:#000000\"> (<\/span><span style=\"background:#ffffff;color:#2b91af\">String<\/span><span style=\"background:#ffffff;color:#000000\">.IsNullOrEmpty(storedPermission.RequestedPermissions))<\/span><br> <span style=\"background:#ffffff;color:#000000\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{<\/span><br> <span style=\"background:#ffffff;color:#000000\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0storedPermission.RequestedPermissions = permissionString;<\/span><br> <span style=\"background:#ffffff;color:#000000\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span><br> <span style=\"background:#ffffff;color:#000000\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"background:#ffffff;color:#0000ff\">else<\/span><br> <span style=\"background:#ffffff;color:#000000\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{<\/span><br> <span style=\"background:#ffffff;color:#000000\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"background:#ffffff;color:#2b91af\">IEnumerable<\/span><span style=\"background:#ffffff;color:#000000\">&lt;<\/span><span style=\"background:#ffffff;color:#0000ff\">string<\/span><span style=\"background:#ffffff;color:#000000\">&gt; unPersistedPermissions = requestedPermissions.Except(storedPermission.RequestedPermissions.Split(<\/span><span style=\"background:#ffffff;color:#a31515\">&#039;,&#039;<\/span><span style=\"background:#ffffff;color:#000000\">));<\/span><\/p>\n<p> <span style=\"background:#ffffff;color:#000000\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"background:#ffffff;color:#0000ff\">foreach<\/span><span style=\"background:#ffffff;color:#000000\"> (<\/span><span style=\"background:#ffffff;color:#0000ff\">string<\/span><span style=\"background:#ffffff;color:#000000\"> p <\/span><span style=\"background:#ffffff;color:#0000ff\">in<\/span><span style=\"background:#ffffff;color:#000000\"> unPersistedPermissions)<\/span><br> <span style=\"background:#ffffff;color:#000000\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{<\/span><br> <span style=\"background:#ffffff;color:#000000\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0db.Entry(storedPermission).State = <\/span><span style=\"background:#ffffff;color:#2b91af\">EntityState<\/span><span style=\"background:#ffffff;color:#000000\">.Modified;<\/span><br> <span style=\"background:#ffffff;color:#000000\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0storedPermission.RequestedPermissions = <\/span><span style=\"background:#ffffff;color:#2b91af\">String<\/span><span style=\"background:#ffffff;color:#000000\">.Join(<\/span><span style=\"background:#ffffff;color:#a31515\">&quot;,&quot;<\/span><span style=\"background:#ffffff;color:#000000\">, storedPermission.RequestedPermissions, p);<\/span><br> <span style=\"background:#ffffff;color:#000000\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span><br> <span style=\"background:#ffffff;color:#000000\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span><br> <span style=\"background:#ffffff;color:#000000\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span><br> <span style=\"background:#ffffff;color:#000000\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0db.SaveChanges();<\/span><\/p>\n<p> <span style=\"background:#ffffff;color:#000000\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"background:#ffffff;color:#008000\">\/\/ This calls into base implementation, you can replace this with your own logic.<\/span><br> <span style=\"background:#ffffff;color:#000000\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"background:#ffffff;color:#0000ff\">base<\/span><span style=\"background:#ffffff;color:#000000\">.OnDeniedPermissionPrompt(context);<\/span><br> <span style=\"background:#ffffff;color:#000000\">\u00a0\u00a0\u00a0\u00a0}<\/span><br> <span style=\"background:#ffffff;color:#000000\">}<\/span><\/div>\n<\/p><\/div>\n<\/p><\/div>\n<p>Open <em>FacebookConfig.cs<\/em> and replace <\/p>\n<div id=\"scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:4c6f5e95-2f66-4b4e-bd01-fb3d441f484c\" class=\"wlWriterEditableSmartContent\" style=\"float: none;padding-bottom: 0px;padding-top: 0px;padding-left: 0px;margin: 0px;padding-right: 0px\">\n<div class=\"le-pavsc-container\">\n<div style=\"background-color: #ffffff;max-height: 300px;overflow: auto;padding: 2px 5px\"><span style=\"background:#ffffff;color:#2b91af\">GlobalFilters<\/span><span style=\"background:#ffffff;color:#000000\">.Filters.Add(<\/span><span style=\"background:#ffffff;color:#0000ff\">new<\/span><span style=\"background:#ffffff;color:#000000\"> <\/span><span style=\"background:#ffffff;color:#2b91af\">FacebookAuthorizeFilter<\/span><span style=\"background:#ffffff;color:#000000\">(configuration));<\/span><\/div>\n<\/p><\/div>\n<\/p><\/div>\n<p>with <\/p>\n<div id=\"scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:5592d12d-3d2c-427c-b93a-4db733e3f96e\" class=\"wlWriterEditableSmartContent\" style=\"float: none;padding-bottom: 0px;padding-top: 0px;padding-left: 0px;margin: 0px;padding-right: 0px\">\n<div class=\"le-pavsc-container\">\n<div style=\"background-color: #ffffff;max-height: 300px;overflow: auto;padding: 2px 5px\"><span style=\"background:#ffffff;color:#2b91af\">GlobalFilters<\/span><span style=\"background:#ffffff;color:#000000\">.Filters.Add(<\/span><span style=\"background:#ffffff;color:#0000ff\">new<\/span><span style=\"background:#ffffff;color:#000000\"> <\/span><span style=\"background:#ffffff;color:#2b91af\">CustomAuthorizeFilter<\/span><span style=\"background:#ffffff;color:#000000\">(configuration));<\/span><\/div>\n<\/p><\/div>\n<\/p><\/div>\n<p>You can find the complete solution <a href=\"http:\/\/code.msdn.microsoft.com\/Facebook-NoCookie-e607ce63\">here<\/a>.<\/p>\n<p><b>NOTE<\/b>: This is a guidance sample for simple one page Facebook application. For multi-page Facebook applications, you may have to add additional logic.<\/p>\n<h3>Conclusion<\/h3>\n<p>Please try this feature and let us know what you think. To find or file issues do so <a href=\"https:\/\/aspnetwebstack.codeplex.com\/workitem\/list\/advanced?keyword=&amp;status=All&amp;type=All&amp;priority=All&amp;release=All&amp;assignedTo=All&amp;component=Facebook&amp;reasonClosed=All&amp;sortField=LastUpdatedDate&amp;sortDirection=Descending&amp;page=0\">here<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This past June we released the first version of the Microsoft.AspNet.Facebook NuGet package and the corresponding Visual Studio template. Today we released an update to this package: Microsoft.AspNet.Facebook 1.1 beta. In this release, we enabled better support for the Safari browser and added a new feature that gives developers the ability to add custom logic [&hellip;]<\/p>\n","protected":false},"author":411,"featured_media":58792,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[197],"tags":[7333,7470,7471,7472,7286],"class_list":["post-234","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-aspnet","tag-asp-net-mvc","tag-asp-net-mvc-facebook","tag-microsoft-aspnet-facebook","tag-microsoft-aspnet-mvc-facebook","tag-mvc"],"acf":[],"blog_post_summary":"<p>This past June we released the first version of the Microsoft.AspNet.Facebook NuGet package and the corresponding Visual Studio template. Today we released an update to this package: Microsoft.AspNet.Facebook 1.1 beta. In this release, we enabled better support for the Safari browser and added a new feature that gives developers the ability to add custom logic [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts\/234","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/users\/411"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/comments?post=234"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts\/234\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/media\/58792"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/media?parent=234"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/categories?post=234"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/tags?post=234"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}