RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX


SharePoint Applied: SharePoint 2007 with WCF and Silverlight : Page 2

Innovative solutions sometimes require multiple ingredients. Find out how to mix it up with SharePoint, WCF, and Silverlight.


Writing the Silverlight Application

The nice thing about the thin .NET 3.5 development model is that as long as you have a contract ironed out, you can take SharePoint completely out of the picture, along with:

  • The virtual machine
  • The process of attaching to W3WP.exe
  • That pesky GAC DLL version whose breakpoint never seems to get hit
Figure 1. The Silverlight Project Structure: The figure shows the sample files and projects in the Visual Studio Solution Explorer pane.
I'll simply stub out the project on my Vista development machine as shown in Figure 1.

I created the project shown in Figure 1 using the Silverlight tools for Visual Studio 2008 SP1, and a WCF service library that I added to the project. As you can see, the MyServices class library is a WCF service library, which hosts a service in Appointments.cs that implements the contract defined earlier. Because you're not yet running inside SharePoint, you can simply stub out fake appointments as shown below:

   public List<BO.Appointment> GetAppointments()
      List<BO.Appointment> toReturnAppts = 
         new List<BO.Appointment>();
      toReturnAppts.Add(new BO.Appointment { 
         Title = "First Appointment", 
         AppointmentTime = DateTime.Now });
      toReturnAppts.Add(new BO.Appointment { 
         Title = "Second Appointment", 
         AppointmentTime = DateTime.Now });
      toReturnAppts.Add(new BO.Appointment { 
         Title = "Third Appointment", 
         AppointmentTime = DateTime.Now });
      return toReturnAppts;
The preceding code is terse because it uses a concept called "Object and Collection Initializers" introduced with C# 3.0.

Next, I'll start crafting the UI of my Silverlight application. I need a UI to which I can bind the results of the WCF service call. This snippet below shows how to implement it:

   <ListBox x:Name="UserAppointments" 
      ItemTemplate="{StaticResource ShowTime}">
The "ShowTime" static resource is a DataTemplate defined as a resource:

   <DataTemplate x:Key="ShowTime">
     <StackPanel Margin="10">
         Template= "{StaticResource clockTemplate}" 
         Width="120" Height="108" DataContext=
         "{Binding Path=AppointmentTime}"/>
       <TextBlock Text="{Binding Path=Title}"
For the eagle-eyed among you, the ContentControl that points to a StaticResource is another application-level resource—it's just a ControlTemplate that takes a DateTime and renders a good looking Analog Clock. You can download the source code for the clock ControlTemplate.

That's it, the UI is done (and it's really that easy). Now, you need to bring it to life with some data, so you can see it running and in action.

Figure 2. The Silverlight Application: Here's the Silverlight application running in Safari.
The Silverlight UI will get its data from the WCF service using basicHttpBinding. To do that, you need to add a WCF service reference to the Silverlight application.

With the reference added, you can use the WCF service proxy to get Appointments data, and bind the appointments to the Silverlight UI (see Listing 1).

An important thing to note in Listing 1 is that you should always call WCF services from Silverlight UIs asynchronously. Failing to do so could lock up the browser—and your end users won't be happy about that!

When you compile and run the above application above, you'll see a UI similar to Figure 2.

You may have noticed that I haven't even touched SharePoint yet. Technically, this entire application could have been developed by a non-SharePoint developer. But at this point, with the UI and WCF service skeleton done, you can work SharePoint into the picture.

Enter SharePoint: Authoring the WCF Service

Earlier, you saw some stub code that substituted for the WCF service—creating mock objects suitable for testing the UI. To make this work inside SharePoint, you need only two simple steps:

  1. You need to configure SharePoint to support WCF, which you can achieve by activating the feature you will find at www.codeplex.com/SPWCFSupport.
  2. You'll have to edit the WCF service code to extract actual appointments under the security context of the currently logged in user. In other words, you'll need to replace the dummy WCF service you saw earlier with a real WCF service that extracts appointments, obeying the currently logged in user's security context.
Because the first step is self-explanatory if you follow the link, I'll focus on the second in this article. The key phrase here is "obeying the currently logged in user's security context."

Now, you could run the WCF service completely out of SharePoint, and thus on a different domain than your Silverlight application. But in that case you would have to set a cross-domain policy that allowed cross-domain calls to work. If you host the WCF service within SharePoint on the same domain, you don't need to worry about that.

Author's Note: If you're interested in learning more about cross-domain policy, you should watch this video.

WCF, by default, works outside of ASP.NET, and thus outside of SharePoint. That's reasonable, because WCF's scope is much larger than just ASP.NET. But WCF does have an ASP.NET compatibility mode, which allows a WCF service to get a reference to HttpContext.Current, and SPContext.Current. You can read the background and implementation details here.

So let's get this straight: A beautiful Silverlight UI running on MacOS/Safari can now talk to a WCF service that fully participates in the SharePoint object model, uses the current SharePoint context, and the current security context—all with no deployment issues, either! That makes me more excited than a five-year old in a candy store with no parents around to police. The possibilities are clearly immense.

With the current context in hand and a little SPQuery magic, I modified the WCF service implementation code as shown below:

   [AspNetCompatibilityRequirements(RequirementsMode = 
   public class Appointments : IAppointments
   #region IAppointments Members
      public List<BO.Appointment> GetAppointments()
         List<BO.Appointment> toReturnAppts = 
            new List<BO.Appointment>();
         SPWeb web = SPContext.Current.Site.OpenWeb();
         SPList appointmentsList = web.Lists["Appointments"];
         SPListItemCollection items = appointmentsList.GetItems(
            new SPQuery(
         appointmentsList.Views["Current Events"]));
         IEnumerable<BO.Appointment> todaysAppts =
            from item in items.OfType<SPListItem>()
            select new BO.Appointment
               Title = item[3].ToString(),
               AppointmentTime = Convert.ToDateTime(item["Start Time"])
         return toReturnAppts;
I then updated my endpoint address to the relevant SharePoint address and rebuilt the .xap file, which I will then place in my SharePoint .wsp solution package so I can deploy it along with the other files.

Close Icon
Thanks for your registration, follow us on our social networks to keep up-to-date