Welcome to Pete Brown's 10rem.net

First time here? If you are a developer or are interested in Microsoft tools and technology, please consider subscribing to the latest posts.

You may also be interested in my blog archives, the articles section, or some of my lab projects such as the C64 emulator written in Silverlight.

(hide this)

How to Build Facebook Applications with Silverlight 2 RTW – Part 2 of 2

Pete Brown - 16 October 2008

In Part 1, we created a Facebook application using ASP.NET. Now, in Part 2, we’ll cover how to add Silverlight into the mix. I’ll assume you have the Part 1 solution working. If not, go to that blog post and download the project files linked at the end of the post.

Install the Silverlight 2 Developer Tools

If you haven’t done so already, install the Silverlight 2 Developer tools from Silverlight.net

Add the Silverlight Project

Add a new Silverlight Application project to the solution.

image

When requested about how to link and test the project, be sure to choose the option to link the Silverlight control to an existing web site. Select the option to make it the test page, but deselect the option to make it the start page. The reason we do that is to make it easy to copy and paste the object instantiation code from the test page to Default.aspx

image

You should now have a solution that looks like this:

image

Copy the asp:Silverlight Control to Default.aspx

Find the ASP.NET test page in your web project and open up the markup. Copy the Register Assembly directive:

<%@ Register Assembly="System.Web.Silverlight" 
    Namespace="System.Web.UI.SilverlightControls"
    TagPrefix="asp" %>

and the ScriptManager and Silverlight control:

<asp:ScriptManager ID="ScriptManager1" runat="server" />
<div  style="height:100%;">
    <asp:Silverlight ID="Xaml1" runat="server" 
        Source="~/ClientBin/GeekSpeakDemo02.xap" 
        MinimumVersion="2.0.31005.0" 
        Width="100%" Height="100%" />
</div>

over to your Default.aspx, so it looks like this:

<%@ Page Language="C#" MasterPageFile="~/Site.master" 
         AutoEventWireup="true" 
         CodeFile="Default.aspx.cs" Debug="true" 
         Inherits="_Default" Title="Untitled" %>

<%@ Register Assembly="System.Web.Silverlight" 
    Namespace="System.Web.UI.SilverlightControls"
    TagPrefix="asp" %>

<%@ Register Assembly="facebook.web" 
             Namespace="facebook.web" TagPrefix="cc1" %>

<asp:Content ID="Content1" 
             ContentPlaceHolderID="MainContentPlaceHolder" 
             runat="Server">
             
        <asp:ScriptManager ID="ScriptManager1" runat="server" />
        <div  style="height:100%;">
            <asp:Silverlight ID="Xaml1" runat="server" 
                Source="~/ClientBin/GeekSpeakDemo02.xap" 
                MinimumVersion="2.0.31005.0" 
                Width="100%" Height="100%" />
        </div>
        
</asp:Content>

Open Default.aspx.cs and remove the code from inside the Page_Load !IsPostBack block. We won’t be needing it anymore.

protected void Page_Load(object sender, EventArgs e)
{
    facebookAPI = ((CanvasIFrameMasterPage)Master).API; 

    if (!IsPostBack)
    {

    }
}

Test Your Application

In Page.xaml, inside the grid, add a textblock:

<TextBlock Text="Hello Facebook, from Silverlight!" />

We’re going to use that just to prove that we’re viewing Silverlight content.

Run the application, and you should see this:

image

We’re halfway there. We now have Silverlight content running inside of Facebook. However, the content isn’t actually interacting with Facebook or using any Facebook data. We’ll fix that in the rest of this post.

A Dilemma – Silverlight is an Island

Remember, a Silverlight app is basically a little desktop application running inside the browser on the client machine. It’s likely not doing postbacks or sharing server-side session state.

Now we have a little dilemma. Facebook is providing some important information to Default.aspx.cs, specifically the session key. That key represents a unique session within Facebook, and is what we need, along with the API key and secret, in order to make any calls to the Facebook API.

Once Silverlight is on the client, any calls it makes back to the web server will not share this same contextual information. Therefore we need to pass these tidbits down to Silverlight so that it can send them back up on the web service calls.

Pass Down the Session Key and Current User

There are a number of ways to pass information down to Silverlight. You could use hidden controls or javascript and access via the HTML bridge; you could include parameters on the querystring; or you could do like I’m going to do and use the initParams. For write-once properties, I find initParams to be pretty easy and reliable.

In the Default.aspx.cs page in the web site, change Page_Load to look like this:

protected void Page_Load(object sender, EventArgs e)
{
    facebookAPI = ((CanvasIFrameMasterPage)Master).API; 

    if (!IsPostBack)
    {
        Xaml1.InitParameters = 
            string.Format("uid={0},sessionkey={1}", 
                            facebookAPI.uid, 
                            facebookAPI.SessionKey
                            );

    }
}

Xaml1 is the name of the asp:Silverlight control instance. The format for the InitParameters is the one recognized by silverlight: name-value pairs separated by commas.

Pick the Key Up

Back to the Silverlight project, we’re going to put in just a little code to read the values back. But first, we need some common place to store these values.

First add a class called “FacebookSession”. This class encapsulates the client-side information that makes up a facebook session. We’re going to move this around later, but it will sit here for now.

namespace GeekSpeakDemo02
{
    public class FacebookSession
    {
        public int UserID { get; set; }
        public string SessionKey { get; set; }
    }
}

Add a new class called “ApplicationState”. This is a singleton class which will contain the values we’re interested in. While we could have made FacebookSession a singleton and just used that, I use the ApplicationState class for a lot more in my own projects, and don’t like the idea of having a bunch of free-floating singletons I need to keep track of.

The class itself is a regular old singleton with a property to hold the FacebookSession information.

namespace GeekSpeakDemo02
{
    public class ApplicationState
    {
        private static ApplicationState _currentInstance;

        private FacebookSession _facebookSession;

        private ApplicationState() {}

        public static ApplicationState Current
        {
            get
            {
                if (_currentInstance == null)
                {
                    _currentInstance = new ApplicationState();
                }

                return _currentInstance;
            }
        }


        public FacebookSession CurrentFacebookSession
        {
            get
            {
                if (_facebookSession == null)
                    _facebookSession = new FacebookSession();

                return _facebookSession;
            }
        }

    }
}

Next, we need to add the code to App.xaml.cs to pull the initparam values. The initparams are made available to Silverlight in the Application_Startup in much the same way that command-line arguments are made available to console applications in the constructor (or at least they used to be back when I wrote DOS programs in C …)

In your Silverlight project, in App.xaml.cs, change the Application_Startup event handler to look like this.

private void Application_Startup(object sender, StartupEventArgs e)
{
    this.RootVisual = new Page();

    if (e.InitParams != null && e.InitParams.Count != 0)
    {
        ApplicationState.Current.CurrentFacebookSession.SessionKey =
            e.InitParams["sessionkey"];

        ApplicationState.Current.CurrentFacebookSession.UserID =
            int.Parse(e.InitParams["uid"]);

    }
}

The code here isn’t forgiving of missing or misspelled InitParams. In a real app, you’ll want to take some appropriate action if they are missing. What the action is depends on what your app does and what you want to do.

Create the Web Service

Now that our Silverlight application has the required session information, we need to provide a server-side interface to get at Facebook. In theory, you could also pass down the apikey and secret (but that would not be very secure) and call the Facebook API directly from Silverlight. I haven’t tried that myself as I don’t think it is a good model to follow in most cases.

Add a Silverlight-enabled WCF service to your web site, and call it FacebookService.svc. I like to put services in a separate folder if they aren’t in a separate domain. In this case, I just stuck it un a “Services” folder.

image

You’ll end up with FacebookService.cs in your App_Code folder, FacebookService.svc in your Services folder, and some changes to your web.config. The entry for the service in web.config will specify basicHttpBinding, which means a SOAP 1.1 web service. Silverlight cannot currently talk to other variants of SOAP, or to other types of WCF bindings (other than duplex and REST)

At this point, I realized this may be slightly confusing for folks new to Silverlight or Facebook development, so let me summarize what we’re doing in this sequence diagram:

image

It’s not 100% architecturally correct as I mince the Silverlight Client with the asp:Silverlight control, but you get the idea. We’ve already handled everything up to “Get Some Data”, so let’s get that piece wrapped up now.

We’re going to do this as simply as possible, with all the code inside the service method itself. In real projects I do, web services are rarely anything more than a wrapper around other code. In MSDN East Coast News, for example, I have a FacebookInterface class that wraps calls to the Facebook API (and actually implements a generic interface so we can plug in other social platforms), and a server-side ApplicationData class that caches data as appropriate.

First, remember that FacebookSession class we stuck in the Silverlight client? Well, turns out we’ll need that server-side as well. So just drag it into the App_Code folder and remove the namespace and the System.Windows.* usings. Finally, tag the fields as WCF serializable:

using System;
using System.Runtime.Serialization;

[DataContract]
public class FacebookSession
{
    [DataMember]
    public int UserID { get; set; }

    [DataMember]
    public string SessionKey { get; set; }
}

Remove the old FacebookSession class from the Silverlight client.

The end result should be a FacebookSession server-side, with none client-side. One thing I love about Silverlight development is I can easily refactor my code this way because we’re using the same language and tools on both the client and server. I did this a couple times in MSDN East Coast News, primarily around RSS parsing and feed grabbing. Originally that was all client-side, then I moved it to the server without any code changes. Sweet!

Next we need to add a class to hold the information we’re going to return from our service method. In this case, the service method is simply going to return some information from the profile of the currently logged-in user.

using System;
using System.Collections.Generic;
using System.Runtime.Serialization;

[DataContract]
public class FacebookProfileInformation
{
    [DataMember]
    public string FirstName { get; set; }
    
    [DataMember]
    public string LastName { get; set; }
    
    [DataMember]
    public string HomeTown { get; set; }

    [DataMember]
    public Uri PictureUrl { get; set; }

    [DataMember]
    public List<string> FriendNames { get; set; }
}

At this point, your App_Code folder should look like this:

image

Finally we’re set to add the service method itself.

using System;
using System.Configuration;
using System.ServiceModel;
using System.ServiceModel.Activation;
using facebook;
using facebook.Schema;

[ServiceContract(Namespace = "uri:com.irritatedvowel.facebook.demo")]
[AspNetCompatibilityRequirements(RequirementsMode = 
    AspNetCompatibilityRequirementsMode.Required)]
public class FacebookService
{
    [OperationContract]
    public FacebookProfileInformation GetProfileInformation(
        FacebookSession session)
    {
        API api = new API();

        // get our app's keys from the web.config shared with the site
        api.ApplicationKey = ConfigurationManager.AppSettings["appkey"];
        api.Secret = ConfigurationManager.AppSettings["secret"];

        // provide the information sent up from Silverlight
        api.uid = session.UserID;
        api.SessionKey = session.SessionKey;

        // get information about the current user
        user userInfo = api.users.getInfo(session.UserID);

        if (userInfo != null)
        {
            FacebookProfileInformation profileInfo = 
                new FacebookProfileInformation();

            profileInfo.LastName = userInfo.last_name;
            profileInfo.FirstName = userInfo.first_name;
            profileInfo.HomeTown = userInfo.hometown_location.city;
            profileInfo.PictureUrl = new Uri(userInfo.pic);

            return profileInfo;

        }
        else
        {
            return null;
        }
        
    }


}

The method simply provides a few key bits of information about the currently logged-in user. We’ll skip the friend list for the moment.

Wire Up the Silverlight Client

Right-click the Silverlight project and add a service reference to our FacebookService on the web site. Rename the namespace to Services:

image

You’ll see a new file added to the client: ServiceReferences.ClientConfig. This is the file you’ll need to change when you move from development to test or production, as it has the URL to our service (on localhost) in the config.

If all went well, you should have only one error in your client: it can’t resolve the FacebookSession inside ApplicationState.cs. To remedy that, simply add the following to ApplicationState.cs:

using GeekSpeakDemo02.Services;

If you run the app, it still won’t do anything interesting, as we neither call nor display the results from the service.

Build the UI

We’re going to stay simple with the UI. Styles have been well-covered by other folks.

Open up Page.xaml and modify it to have the following contents:

<UserControl x:Class="GeekSpeakDemo02.Page"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Width="400" Height="300">
    <Grid x:Name="LayoutRoot" Background="White">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="150"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        
        <Image x:Name="ProfilePicture" Grid.Column="0" 
               Stretch="None"
               VerticalAlignment="Top"
               />
        
        <StackPanel Grid.Column="1" Orientation="Vertical">
            <TextBlock Text="Last Name" FontSize="10" />
            <TextBlock Text="{Binding LastName}" FontSize="14" 
                       Margin="0 0 0 10" />
            
            <TextBlock Text="First Name" FontSize="10" />
            <TextBlock Text="{Binding FirstName}" FontSize="14" 
                       Margin="0 0 0 10" />
            
            <TextBlock Text="Home Town" FontSize="10" />
            <TextBlock Text="{Binding HomeTown}" FontSize="14" 
                       Margin="0 0 0 10" />
            
            <Button x:Name="LoadData" Content="Load Data" 
                    Width="75" 
                    HorizontalAlignment="Left"/>
        </StackPanel>
        
    </Grid>
</UserControl>

 

Call the Service and Display the Results

The next part is typical Silverlight service wireup and UI binding. The code from Page.xaml.cs is below.

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media.Imaging;

using GeekSpeakDemo02.Services;

namespace GeekSpeakDemo02
{
    public partial class Page : UserControl
    {
        public Page()
        {
            InitializeComponent();

            LoadData.Click += new RoutedEventHandler(LoadData_Click);
        }

        void LoadData_Click(object sender, RoutedEventArgs e)
        {
            FacebookServiceClient client = new FacebookServiceClient();

            client.GetProfileInformationCompleted += 
                new EventHandler<GetProfileInformationCompletedEventArgs>(
                    client_GetProfileInformationCompleted);

            client.GetProfileInformationAsync(
                ApplicationState.Current.CurrentFacebookSession);
        }

        void client_GetProfileInformationCompleted(object sender, 
            GetProfileInformationCompletedEventArgs e)
        {
            if (e.Result != null)
            {
                LayoutRoot.DataContext = e.Result;

                // have to do this because Images don't 
                // bind well in Silverlight 2
                ProfilePicture.Source = 
                    new BitmapImage(e.Result.PictureUrl);
            }
            else
            {
                // here's where you'd display some sort of message
                // saying the call failed. Check e.Error
            }


        }
    }
}

If you run it at this point, and click the “Load Data” button, you’ll see something like this (only with your profile):

image

Pretty cool. Now your app is pulling data from Facebook. It’s pretty easy to see how you can expand on this, but I’ll take us one step further before we call this sample quits.

Modify the Service to Return Your Facebook Friends

Update the service method to add the following (gray text is for context):

profileInfo.HomeTown = userInfo.hometown_location.city;
profileInfo.PictureUrl = new Uri(userInfo.pic);

// get the friends

IList<user> friends = api.friends.getUserObjects();

if (friends != null)
{
    profileInfo.FriendNames = new List<string>();

    foreach (user friend in friends)
    {
        profileInfo.FriendNames.Add(
            string.Format("{0}, {1}",
            friend.last_name, friend.first_name));
    }
}

return profileInfo;

That code simply calls another Facebook API method to get the friend objects for all the friends of the currently logged-in user. Remember it knows who is logged in because we set the session key and user id earlier in the code.

Update the UI

We need a place to put the friends, so we’ll add a simple listbox. Add this in the Page.xaml file right before the LoadData button:

            <ListBox ItemsSource="{Binding FriendNames}"
                     Height="250"/>

At the same time, in the xaml, set the control height to be 500, or else the listbox will get clipped by the bounds of the Page. We could also use a grid for layout, but the root issue is the size of the control and the size of the html div. In the current facebook profile, you can have a Silverlight control that is about 760 x 600 without running into clipping by Facebook (the height can be almost anything, but 600 works well on most displays)

Another thing you need to do to avoid clipping is to modify the application settings for sizing. I’ve found the smart-size to be a bit buggy in trying to figure out the size of your iframe, especially if you resize your page while your app is up. For that reason, I suggest changing it to the less interesting but functional Resizable option

Open the Facebook developer application and select “Edit Settings” for your app:

image

Now scroll down to “Default IFrame Canvas Size Option” and change it from Smart size to Resizable and save your application.

image

Finally, go into your Default.aspx and change the div height from 100% to 500px (or whatever you set your Silverlight page to be):

        <div  style="height:500px;">
            <asp:Silverlight ID="Xaml1" runat="server" 
                Source="~/ClientBin/GeekSpeakDemo02.xap" 
                MinimumVersion="2.0.31005.0" 
                Width="100%" Height="100%" />
        </div>

In theory, you shouldn’t have to do that. However, more browsers have problems with Height:100% than not. FireFox always had issues with that, and IE8 does as well.

Now when you run the app, you’ll see your full Facebook application. Note that Resizable is not perfect either, so be sure to test your app out at multiple resolutions. Note that unless you run Silverlight in Windowless mode (which can take a significant performance hit) your app will overlay other things on the canvas page such as the Facebook toolbar at the bottom. You can see a little of that in the screenshot below.

image

Conclusion

There are lots more things a Facebook application can do. Some of those things (like posting updates to all users, updating all profile FBML etc) require background jobs and purpose-built databases. Expect to do a fair amount of server-side coding separate from your custom Silverlight experience.

I’m looking forward to a great crop of Silverlight apps on Facebook. If you create one, or know of a good one, drop me a note in the comments to this post.

Further Reading and Related Links

Source code for this walkthrough may be found here.

       
posted by Pete Brown on Thursday, October 16, 2008
filed under:        

31 comments for “How to Build Facebook Applications with Silverlight 2 RTW – Part 2 of 2”

  1. Devin Rosesays:
    Hi Pete!

    I just finished the second half of the tutorial here, and everything worked quite well!

    One problem I had initially on the first Test Your Application part: The application didn't come up in Firefox. The localhost page came up, redirected to the facebook ap page, but then it must have timed out or been wedged or something because the Hello world text never showed up.

    I launched Internet Explorer, made it the default browser, relaunched the web site via Dev Studio, and it worked: I could see the text.

    So I just completed the rest of the tutorial, made sure it worked in IE, then I closed Firefox and Visual Studio, relaunched them both, made Firefox the default browser, ran the website, and it worked!

    One question: In this line of code, what should I changed the namespace to:
    [ServiceContract(Namespace = "uri:com.irritatedvowel.facebook.demo")]

    Does it matter? Can I leave it blank?

    Thanks a ton once again--you probably saved 2 weeks of fiddling and head-scratching if I had had to figure this all out by myself.
  2. Pete Brownsays:
    @Devin

    Cool, glad it worked for you :)

    the namespace can be pretty much any URI you want; just make it unique to your app. In a dev environment, it doesn't really matter.

    As an aside, it looks like Clarity is abandoning their facebook toolkit (I have some choice words to say about that). However, since it is open source, if they didn't implement something you need, in theory, you can implement it and add it in.

    Pete
  3. Devin Rosesays:
    Hi Pete,

    I completed the app and got it running in debug mode with the localhost server on my computer, but I have not gotten it to work completely on my actual ASP.NET server.

    I changed the ServiceReferences.ClientConfig file to point to my actual internet server folder instead of localhost:portnumber; I changed the Callback URL in the facebook app settings page to point to the right folder on my server as well.

    Then I built release configuration of the solution, right-clicked on the web site project, and did Publish Web Site, entering in my server info, and it copies all the files to the folder on my server.

    I went to the facebook app page, and the error I got was that Site.master could not be found, so I looked that problem up and found out I needed to mark my folder as a "virtual directory" or "Web Application" via my server's control panel. I did that, and then voila! I saw the Silverlight app with the Load Data button and everything.

    BUT when I clicked Load Data, nothing happened. In Internet Explorer, I saw at the bottom it said Error on Page, and the details said that the silverlight 2 application had an unhandled error.

    The error is "An endpoint configuration section for contract "Services.FacebookService" could not be loaded because more than one endpoint configuration for that contract was found. Please indicate the preferred endpoint configuration section by name at System.ServiceModel.Description.ConfigLoader.LookupChannel(...)

    The one thing that I think might be a problem is that, when I search the solution for localhost:2285 (my port number), I still get 20 references found, all related to the Service Reference: configuration.svcinfo, FacebookService.disco, .wsdl, .xsd, Reference.svcmap.

    Could these references to localhost:2285 be causing the problem? I right-clicked on the Services item underneath the Service References item in my Silverlight Project items list of Solution Explorer, and selected Configure Service Reference..., and I found it was referencing http://localhost:2285/SilverTower/FacebookService.svc there, but when I changed the localhost:2285 part to my actual internet address and said OK, it gave me an error and said "there was an error downloading the FacebookService.svc file from my internet folder because this collection already contains an address with schema http:. There can be at most one address per schema in this collection."

    Please know I am not asking you to debug my web server but just wanted to know if you had any clue about what is wrong. I think others might run into the same problem when publishing their silverlight/facebook app potentially. How do I get rid of that localhost:2285 stuff? Replace in files?
  4. Pete Brownsays:
    @Devin

    I don't get why other folks's posts get the paragraph breaks nuked. Anyway...

    I haven't run into that problem. However, the places to look would be:
    1. Your servicereferences.clientconfig (you know that)
    2. The settings for your app inside Facebook (I think you get that too)

    Most of the files you pointed out are temp files. The only one used at runtime is the clientconfig.

    When I move from dev to production (I have two facebook apps, one is dev, the other is prod), I simply change the clientconfig and I'm good to go.

    Is your production service at the same root url as your silverlight app? Just want to make sure this isn't some odd twist on a cross-domain issue.

    Pete
  5. Devin Rosesays:
    Hi Pete,
    <br/><br/>
    I solved the problem!
    <br/><br/>
    Weirdly, my ServiceReference.ClientConfig file had TWO binding entries and two endpoint entries, one with the name BasicHttpBinding_FacebookService and the other BasicHttpBinding_FacebookService1 (a "1" on the end). I don't know how this happened as this was generated for me, but I commented out the "1" binding and endpoint, then went to configure the web service reference, changed the localhost to my real server name, this time with no error, and all worked!
    <br/><br/>
    This blog post had good information about some of the other errors I was getting: http://www.wpflearningexperience.com/?cat=12
    <br/><br/>
    For example, my server is a shared ASP.NET host using IIS 6 (not 7), so the xap mime type may not have been registered (I added it as a custom type) and the shared host part can mess with the service base addresses.
    <br/><br/>
    Thanks again! (P.S. I tried to add in line break html entries--maybe community server render the page breaks).
  6. Maddie Reddysays:
    Hi Pete,
    Thanks for putting out such a great tutorial.
    I was successful in replicating part 1, but I am having a problem with part2. I am at the printing "hello facebook, this is silverlight". But when I run the app, I get to the facebook page but nothing gets printed. Its just a blank page. However, when I run your code, I can see the correct result. Can you or anyone reading this help me with this problem?
  7. Pete Brownsays:
    @Maddy

    It could be a couple things:
    1. You didn't copy the silverlight object tag stuff over to default.aspx (the <asp:silverlight> and related bits

    or

    2. You have an error in your silverlight app, typically a typo in the xaml, which is making silverlight barf and go white.

    There are other possibilities, but those are the most likely culprits.

    Pete
  8. Maddie Reddysays:
    Thanks for the prompt response.
    I copy-and-pasted the default.aspx and the page.xaml headers from your code and ran the application and it works! I thought the code looked exactly the same as yours but...
    Anyway, it works and I will continue with rest of the tutorial.
    Thanks for your help!
  9. Pete Brownsays:
    @Danny

    One of their previous posts said they were just going to release the toolkit in its incomplete form to the community. I see now there was just a post on 10/23 that didn't have a timeline, or even a strong commitment, but at least said they will probably release something:
    http://www.codeplex.com/FacebookToolkit/Thread/View.aspx?ThreadId=38365

    "We've got a few people between projects, so we're going to resume work on version 2.0. No timeline yet, but we're going to concentrate on resolving bugs in the Release Candidate before considering any new features." ...

    "Clarity does a lot of developer community-focused events/projects, and we’re certainly proud of the Toolkit’s success. But, we’re not a software vendor. We’re a consulting firm. We do most of the Facebook Toolkit development and support “pro bono” and, generally, in addition to – and not in place of - our “regular” consulting work. Microsoft funded a portion of the initial Toolkit development and portions of the 1.7 release, but we’ve funded all other releases and support including the 2.0 Release Candidate. Because of this, work on the Toolkit often takes a backseat to consulting work."

    There's a lot of good functionality in there, but it is missing whole chunks of the API. I wish they were clear up-front in what their intentions were for 2.0. 1.7 doesn't work well with the 2008 profile changes despite the comments from the developer.

    That said, there's nothing out there anywhere near as complete (in .NET) as this toolkit.

    Pete
  10. Hocsays:
    I got the same error as Maddie: Blank page. I checked the aspx and xaml. They are all the same as yours.

    Where should I check? I feel as if the xaml isnt attached right in the project. Or some dll is wrong.
  11. Hocsays:
    I was trying this tutorial:

    http://community.irritatedvowel.com/blogs/pete_browns_blog/archive/2008/10/16/How-to-Build-Facebook-Applications-with-Silverlight-2-RTW-_1320_-Part-2-of-2.aspx



    But I downloaded the new Facebook template and Toolkit and that seems to cause problem. Here is my code: http://www.innovie.com/Projects.zip

    It showed blank page when I ran the project (Default.aspx)

    Can someone help to figure out why and how to fix it?



    Thanks
  12. Pete Brownsays:
    @Hoc from a quick look, nothing jumps out at me.

    Are you viewing in IE or in Firefox? If FF, you may be running into the 100% height div problem.

    Have you tried putting a breakpoint in your Silverlight app and seeing if it gets hit?

    If you right-click the white area on the page, does it pop up the Silverlight menu? If not, you can rule your Silverlight app out of the problem.

    Did you properly configure your facebook app (in facebook) to be an iframe app?

    Pete
  13. Daniel Gimenezsays:
    I'll be coming out with a FaceBook app soon, so much thanks for this blog. At first I thought this implementation was a bit riggy because it just seemed like a needless proxy, but in actuallity it isn't bad. I'd like to share why I feel this way.

    First, one thing I'd recommend for anybody developing a Facebook app is to STAY AWAY from the DataStore API. It is only good for something really, really light weight. I'll spare the rant, but think NO JOINS, one request per object type, funky method of creating associations that will probably nessitate redundant data in objects.

    That's leads to just one reason (and the main one for me) why the described method works. Because if you have custom data, you probably will already have to access that data via a web service in your Silverlight app. So in that web service you can do all the work of getting the Facebook data and combining it with your own data and sending back a singular response to the user. Less chance of things going wrong and a nice clean design.

    Speaking about things go wrong, does anybody have a good way of handling exceptions? When an error happens in the Facebook ToolKit I don't know how to handle it.
  14. Pete Brownsays:
    @Daniel. That's definitely one reason to use this approach. Another is if you want to do anything to update a profile box: that needs to happen from a background job if you want the profile box to update without user intervention. Can't do that from a single-user client app; it has to happen on the server. Then, once you have your API calls on the server, it's a no brainer to keep them there and just expose a subset to Silverlight.

    Pete
  15. Daniel Gimenezsays:
    I'm definitly happy with having a web service that uses the fb toolkit and integrates with my data, and then having a webservice that my app accesses.

    Question. Have you been able to get this to work as a FBML page? I keep getting Error 500.
  16. Pete Brownsays:
    @Daniel

    You need to make a number of changes for it to work as an FBML page. For one, you need to use all FBML for the markup, and change the iframe element to be an fb:iframe. You'll then need to post the application someplace where Facebook can pull it. It resolves the url for fb:iframe server-side, so having it at localhost won't work (that's why debugging using FBML is so hard)

    You'll also need to change your master page to use the fbml-based base classes provided by the toolkit.

    Pete
  17. Daniel Gimenezsays:
    Hey Pete, thanks for your blog! It was a real big help. It stinks that the fb:Silverlight tag doesn't work... makes me want to do OpenSocial (I might just do both).

    Anyways, if you're interested, here's the Facebook app I did:
    http://www.facebook.com/towerofbabble
  18. Steve Johnsonsays:
    Hi Pete,
    I know I'm so close, but I'm getting the following when I press the Load Data button

    An error occurred while trying to make a request to URI 'http://localhost:59874/myfacebookapp/Services/FacebookService.svc'. This could be due to attempting to access a service in a cross-domain way without a proper cross-domain policy in place, or a policy that is unsuitable for SOAP services. You may need to contact the owner of the service to publish a cross-domain policy file and to ensure it allows SOAP-related HTTP headers to be sent. This error may also be caused by using internal types in the web service proxy without using the InternalsVisibleToAttribute attribute. Please see the inner exception for more details.

    I checked my ServiceReferences.ClientConfig and found it referenced customBinding instead of basicHttpBinding...

    <configuration>
    <system.serviceModel>
    <bindings>
    <customBinding>
    <binding name="CustomBinding_FacebookService">
    <binaryMessageEncoding />
    <httpTransport maxReceivedMessageSize="2147483647" maxBufferSize="2147483647" />
    </binding>
    </customBinding>
    </bindings>
    <client>
    <endpoint address="http://localhost:59874/myfacebookapp/Services/FacebookService.svc"
    binding="customBinding" bindingConfiguration="CustomBinding_FacebookService"
    contract="Services.FacebookService" name="CustomBinding_FacebookService" />
    </client>
    </system.serviceModel>
    </configuration>

    I'm stumped. Any thoughts?

    Thanks,
    Steve
    sbj@sbjcat.com
  19. Steve Johnsonsays:
    Hi Pete,
    I was staring at the problem the whole time. Facebook no longer supports http://locahost, and the ServiceReferences.ClientConfig needed to be updated to reference my psuedo name for it.
    Thanks for the great article,
    Steve
  20. Steve Johnsonsays:
    I had the same problem with the Starter Kit until I saw this on the Starter Kit site (it still allows debugging)....



    Facebook has recently stopped supporting localhost as a valid callback URL. To workaround this problem you can add an alias to your %SystemRoot\System32\drivers\etc\hosts file that refers to localhost as suggested here. Using localhost makes it easy for you to debug locally, note that the port number (nnnn) will be the port you use to debug your application locally using Microsoft's development web server. You can get that port number once you download and run the application below. Also according to this post these URL's should be all lowercase.


    Best,
    Steve
  21. Ruellsays:
    Hi Pete,

    Thanks for your tutorial, this is really helpfull,
    anyways i have just 1 question;
    Is it posible to developed a silverlight application that uses facebook API without uaing/embeding it to ASP.NET page? just plain XAP on plain HTML?

    See ive got game developed in WPF(desktop) for windows and connects to Linux as server, my plan is to
    convert this WPF desktop game to Silverlight (since convertion is plainly easy) and use facebook API and im planning to deploy the XAP-embedded HTML web page into a linux-based webserver.

    Is this possible? If so can you give me some idea on how to do this?

    Thanks in advance.
  22. Petesays:
    @Ruell

    At the time, it wasn’t easy (or wasn’t possible, I don’t recall). These days, you can use the current version of the facebook SDK for .net to eliminate any additional server-side requirements.
    http://msdn.microsoft.com/en-us/windows/ee388574.aspx

    There are some great tutorials right on that page.

    Pete
  23. gurusays:
    Hey Pete, I have implemented FB app based on FBML. I host an iframe and insert silverlight there. I get the quesrystrings and able to communicate to FB server using APIs.

    But now i am stuck as i want to use FBML publish stream function. which i can call only from my parent frame. I wanted to write a javascript method in parent frame and call from my iframe. But FB is not allowing me to do so.

    Do you know of any workaround for this?
  24. oldwhlzfouhglsays:
    Unsere Erfahrungen vom 8 Februar 2003

    demat

    Sie lieben Schönheits OPs?

    Erfahrungen Femmestyle Schönheitsklinik
    Niemand operiert besser Nasenkorrektur

    Warum also noch immer suchen?

    Laden Sie die Femmestyle Webseite und bekommen Sie alle Infos über
    [url=http://www.femmestyle.name/]Brustvergrößerung München Risiken[/url]

    Ein toller Tip von tortenfischmiifemmename
    Brustvergrößerung ist nach der Brustverkleinerung Forum aber noch vor der Bruststraffung Forum eine der häufigsten Operationen, dann kommt erst Fettabsaugung Forum und etwas später Facelift Risiken und auch Nasenkorrektur Finanzierung.
    Bis bald

Comment on this Post

Remember me

12 trackbacks for “How to Build Facebook Applications with Silverlight 2 RTW – Part 2 of 2”

  1. How to Build Facebook Applications with Silverlight 2 RTW ??? Part 2 of 2 | Silverlight Guidesays:
    PingBack from http://www.silverlightguide.com/news/how-to-build-facebook-applications-with-silverlight-2-rtw-%e2%80%93-part-2-of-2
  2. Silverlight news for October 17, 2008 says:
    PingBack from http://www.silverlightshow.net/news/Silverlight-news-for-October-17-2008.aspx
  3. Silverlight and Facebook | DavideZordan.netsays:
    PingBack from http://www.davidezordan.net/blog/?p=470
  4. Dew Drop - October 17, 2008 | Alvin Ashcraft's Morning Dewsays:
    PingBack from http://www.alvinashcraft.com/2008/10/17/dew-drop-october-17-2008/
  5. POKE 53280,0: Pete Brown's Blogsays:
    Be sure to join me, Glen Gordon and Andrew Duthie on October 22 for our MSDN geekSpeak . We’ll be covering
  6. Community Blogssays:
    In this issue: Tim Heuer, Pete Brown, Mike Taulty, NikhilKothari, Dan Wahlin, Laurence Moroney, Arturo
  7. Khurram Azizsays:
    Announcements http://weblogs.asp.net/scottgu/archive/2008/10/14/silverlight-2-released.aspx http://www.hanselman.com/blog/Silverlight2IsOut.aspx
  8. Khurram Azizsays:
    It is a Wiki-Like-Page listing Silverlight Resources for beginners (like me), I will keep it updated as more such resources are discovered or told by community, peers and buddies
  9. Dr. Z's Blogsays:
    Pete Brown has put together a two-part series ( Part I & Part II ) on how to create Facebook Silverlight
  10. Dr. Z's Blogsays:
    Pete Brown has put together a two-part series on how to create Facebook Silverlight applications. You
  11. I Can't Believe That Workedsays:
    In a past post ( Facebook Connect Post ) I showed everyone how to set up an application in Facebook and how to use Facebook Connect with Silverlight to create a simple login screen. That was a trivial proof of concept to show how one might implement such
  12. I Can't Believe That Workedsays:
    In a past post ( Facebook Connect Post ) I showed everyone how to set up an application in Facebook and how to use Facebook Connect with Silverlight to create a simple login screen. That was a trivial proof of concept to show how one might implement such