This is the first article in a small series on Silverlight and SharePoint. In this post I will describe what I have built in Silverlight on top of SharePoint. It is not meant to be something extremely useful, but as a study project to get started with Silverlight development for SharePoint. So this series is not about XAML or how you can create a slick UI, but it will show you how to get SharePoint data displayed in Silverlight, used in a SharePoint web part. In this first article I will describe the solution and how you get your SharePoint server prepared.
Part 1 - Introduction and preparation
Part 2 - Create the WCF News service
Part 3 - Create the Silverlight web part
Part 4 - Create the Silverlight application
Introduction of Silverlight News v1.0
What I have created is a SharePoint web part that aggregates announcements. Just like the Content By Type web part, but now they are displayed in a Silverlight grid. Which looks nicer and users have more options to group and sort, re-arrange columns etc. Here is a screenshot of the web part:
When users click on one of the rows, more information about the news item and a preview of the content are displayed:
The Silverlight News web part queries for items that have the “Announcement” content type. In the web part properties you can select the scope for this query. It has 3 options; the current site, the current site and all it’s sub sites and the current site collection. Antoher way to restrict the number of items in the view is to use a SharePoint filter web part. The Silverlight News web part is a filter consumer and therefore you can use any filter web part (also the List Item Filter of Web Context Filter) to filter news items. The screenshot below shows the toolpane of the web part and a filter web part that is sending the filter value to our news web part.
Preparing your SharePoint farm(s)
The first step to start working on this is to get your SharePoint server(s) and your development server up to date. On my development machine I went through these installation and configuration steps:
After configuring the development server, I have setup a test server. On that server I installed and configured this:
- Install MOSS SP1, including the Infrastructure update
- Install .NET Framework 3.5 SP1
- Install the Silverlight client
- Add System.Web.Silverlight.dll to the Global Assembly Cache
- Modify the web.config file(s)
- Register MIME type
Preparing for WCF support
My Silverlight client is getting the news items from a WCF service. To be able to run WCF services on SharePoint you need to create and register a virtual path provider. The excellent series on SharePoint and WCF by Sahil Malik has more information on this. First you create the virtual path provider:
public class WCFVirtualPathProvider: VirtualPathProvider
{
public override bool FileExists(string virtualPath)
{
string fixedPath = virtualPath;
if (fixedPath.StartsWith("~", StringComparison.Ordinal) && fixedPath.EndsWith(".svc", StringComparison.InvariantCultureIgnoreCase))
{
fixedPath = fixedPath.Remove(0, 1);
}
return Previous.FileExists(fixedPath);
}
public override string CombineVirtualPaths(string basePath, string relativePath)
{
return Previous.CombineVirtualPaths(basePath, relativePath);
}
public override System.Runtime.Remoting.ObjRef CreateObjRef(Type requestedType)
{
return Previous.CreateObjRef(requestedType);
}
public override bool DirectoryExists(string virtualDir)
{
return Previous.DirectoryExists(virtualDir);
}
public override System.Web.Caching.CacheDependency GetCacheDependency(string virtualPath, System.Collections.IEnumerable virtualPathDependencies, DateTime utcStart)
{
return Previous.GetCacheDependency(virtualPath, virtualPathDependencies, utcStart);
}
public override string GetCacheKey(string virtualPath)
{
return Previous.GetCacheKey(virtualPath);
}
public override VirtualDirectory GetDirectory(string virtualDir)
{
return Previous.GetDirectory(virtualDir);
}
public override VirtualFile GetFile(string virtualPath)
{
return Previous.GetFile(virtualPath);
}
public override string GetFileHash(string virtualPath, System.Collections.IEnumerable virtualPathDependencies)
{
return Previous.GetFileHash(virtualPath, virtualPathDependencies);
}
protected override void Initialize()
{
base.Initialize();
}
}
The base class VirtualPathProvider can be found in the System.Web.Hosting namespace. You need to override all methods and make the change to the FileExists method as in the snippet above. This function removes the ‘~’ and passes the new virtualpath to the other provider(s). This prevents SharePoint from crashing on a WCF request. The SharePoint virtual path provider does not know how to handle request that start with a ‘~’, and you will get an error message.
The second step is to register your new provider. To do this, you need to create a new Http module:
public class WCFVirtualPathProviderRegistration : IHttpModule
{
static bool _initialized = false;
static object _locker = new object();
public void Init(HttpApplication context)
{
if (!_initialized)
{
lock (_locker)
{
if (!_initialized)
{
WCFVirtualPathProvider provider = new WCFVirtualPathProvider();
HostingEnvironment.RegisterVirtualPathProvider(provider);
_initialized = true;
}
}
}
}
public void Dispose()
{
}
}
The last thing to do is to register your http module in the web.config. Add the snippet below to the hhtpModules element in the web.config. You need to add it after the other httModules that are registered here.
<add name="WCFVirtualPathProviderRegistration"
type="TST.WCFServices.WCFVirtualPathProviderRegistration, TST.WCFServices, Version=1.0.0.0, Culture=neutral, PublicKeyToken=28ec3cd925274d6c">
</add>
That’s it for the first part. Our SharePoint server(s) are now ready to build the Silverlight News web part. In the next article I will start to describe the WCF News service that aggregates the news items and returns them to the silverlight client.