Silverlight 1.1 on Facebook Canvas Page using ASP.NET and Facebook Developer Toolkit
A couple weeks ago, working with Microsoft we delivered the facebook developer toolkit to help developers write Facebook applications using .net. Since then, we created a codeplex project to help keep the toolkit up to date and relevant. It has been fun, and the response/involvement from the community has been great.
Yesterday, I spent some time working on how to build canvas pages leveraging the toolkit. A canvas page is a page that is accessed directly within facebook.com and the result is integrated into the user experience on facebook. These canvas pages were a major part of the new F8 facebook platform. For more information, check out the Facebook Developer documentation. Anyway, after struggling with the flow of authentication and application adding, I finally got it working and created 2 new canvas base pages (one for FBML type and one for IFrame). I posted on codeplex about the changes here. I also posted some very simple Canvas page examples for both FBML and IFrame.
Now that I had a good framework in place for building the canvas page, I wanted to see if I could get a Silverlight control with Facebook context showing up in my IFrame canvas page. From past experience, I knew there were some major obstacles.
- Some namespaces used in the Facebook.dll (wrapper to the API) are not supported in Silverlight namespace. Most notably: System.XML, System.Web.
- Silverlight 1.1 Alpha does not support cross domain posts.
- It will be tough to manage the facebook login process from the Silverlight control, since we can not show the facebook hosted login page.
With this in mind, I had a plan. And after a frustrating day, just got a Silverlight control showing on a canvas page with some facebook context. Here's how.
- Added a new webservice (SilverlightService.asmx) to my ASPNETPlatformSamples web site. This webservice is a proxy used by the silverlight application to call facebook
- Updated the ASPNETPlatformSamples web.config to support the web service.
- Added a ScriptService attribute to SilverlightService to enable it to support JSON calls
- Added WebMethod GetFriends wrapping the FacebookService.GetFriends(), this method needs to take the 4 parameters that comprise a facebook session, so that calls can maintain context.
[System.Web.Script.Services.ScriptService]
public class SilverlightService : System.Web.Services.WebService
{
Facebook.Components.FacebookService _fbService = new Facebook.Components.FacebookService();
[WebMethod]
public UserJSON[] GetFriends(string api, string secret, string session, string userid)
{
- Created a stripped down version of the Facebook.Entity.User class that is serializiable by JSON. JSON can't serialize enums or subclasses. So, for this I just stripped them out. This is called UserJSON and is currently just a member of my ASPNETPlatformSamples web site.
- In the GetFriends WebMethod, converted Collection of Users returned from Facebook call to Array of JSON compatible users.
Collection<Facebook.Entity.User> friends = _fbService.GetFriends();
UserJSON[] x = UserJSON.ConvertFacebookUserArray(friends);
return x;
- Created a new Canvas page (IFrame\Silverlight.aspx), alongside to my other IFrame canvas samples
- Added a placeholder for the Silverlight control and 4 hidden fields to store the facebook context.
<head>
<title>Silverlight Project Test Page </title>
<script type="text/javascript" src="Silverlight.js"></script>
<script type="text/javascript" src="CreateSilverlight.js"></script>
</head>
<body>
<form id="Form1" runat="server">
<asp:HiddenField ID="hidAPI" runat="server" />
<asp:HiddenField ID="hidSecret" runat="server" />
<asp:HiddenField ID="hidSession" runat="server" />
<asp:HiddenField ID="hidUser" runat="server" />
<div id="SilverlightControlHost" >
<script type="text/javascript">
createSilverlight();
</script>
</div>
</form>
- Added code in code-behind to populate hidden fields (so they can be accessed by silverlight control).
public partial class _Default : CanvasIFrameBasePage
{
private const string FACEBOOK_API_KEY = "c559128010f3edee33796fd4205361c2";
private const string FACEBOOK_SECRET = "85887d1c9a8334e5059742468a5400ee";
new protected void Page_Load(object sender, EventArgs e)
{
base.Api = FACEBOOK_API_KEY;
base.Secret = FACEBOOK_SECRET;
base.Page_Load(sender, e);
hidAPI.Value = this.FBService.ApplicationKey;
hidSecret.Value = this.FBService.Secret;
hidSession.Value = this.FBService.SessionKey;
hidUser.Value = this.FBService.UserId;
}
}
- Created a new silverlight project using Orcas called SilverlightWebServiceClient
- Added a web reference to the above WebService
- Added code in page_loaded event handler of xaml code behind to call the GetFriends method on the WebService to retrieve an array of friends.
- Then simply wrote text to a textblock with the count that was found.
- I then needed to add a Silverlight Reference into the ASPNETPlatformSamples. This essentially copies the .xaml from the Silverproject, and the compiled .xaml.cs into a ClientBin folder of the web site project so they can be accessed from within the website.
- You can see it in action, by going to my IFrame canvas sample. After logging in and adding the application, you should have a Silverlight demo link which will show the Silverlight page.
I checked the updated c# code for ASPNETPlatformSamples and a new project for the Silverlight Control into the codeplex site.
Now we need to build some cool Silverlight canvas apps. If anyone has better ways to do this, I'd be interested in learning about them.
Next up, Silverlight in FBML Canvas page.