Het gebruik van het three layered application pattern bij het bouwen van Silverlight web parts in SharePoint
Met behulp van Silverlight kunnen applicaties met een rijke user interface gebouwd worden. Deze applicaties leven in de browser en kunnen bijvoorbeeld in een HTML pagina geplaatst worden. Daarnaast kunnen Silverlight applicaties ook in web parts gebruikt worden. Door het gebruik van Silverlight applicaties in SharePoint web parts krijg je the best of both worlds. Met de rijke user interface mogelijkheden van Silverlight kunnen prachtige, grafische web parts gebouwd worden met bijvoorbeeld mogelijkheden voor 3D en grafieken. Daarnaast zorgt het gebruik van Silverlight ervoor dat er minder pagina refreshes nodig zijn, waardoor het gebruik van de applicatie door de gebruiker prettiger en sneller is. Tegelijkertijd kan gebruik gemaakt worden van bijvoorbeeld de collaboratie- en search-mogelijkheden van SharePoint.
Dit artikel legt uit welke stappen nodig zijn om een Silverlight web part in SharePoint te bouwen en ook op welke manieren data uit de SharePoint omgeving in het Silverlight web part gebruikt kan worden.
Wat is Silverlight?
De meeste mensen zullen inmiddels waarschijnlijk wel weten wat Silverlight is. Voor de zekerheid toch nog even een samenvatting:
- Silverlight is een browser plugin
- De huidige versie van Silverlight is versie 2
- Versie 2 is in oktober 2008 gelanceerd
- Versie 2 biedt ondersteuning voor het gebruik van Managed Code in Silverlight applicaties
- Om een snelle download mogelijk te maken is de plugin minder dan 5MB groot
- Silverlight is cross-browser, cross-platform; het draait bijvoorbeeld in Internet Explorer, Firefox en Apple Safari browsers en het draait op zowel Windows als Apple besturingssystemen
- De Silverlight applicatie draait dus op de client, niet op de server!
Silverlight maakt het mogelijk om visueel sensationele en interactieve oplossingen te bouwen die in de browser draaien. Omdat de code in de browser draait, erft de Silverlight applicatie ook de eigenschappen van de browser. Dit betekent dat de code maar beperkte rechten heeft op de client. De reden hiervoor is dat je natuurlijk niet wilt dat een Silverlight applicatie die je in je browser bekijkt toegang heeft tot bijvoorbeeld je harde schijf.
In Silverlight is het, net als in gewone ASP.NET pagina's en user controls, zo dat de user interface en de styling van een control volledig los staan van het gedrag van het control. Je gebruikt zelfs verschillende programma's voor het ontwikkelen van de logica en de user interface. Developers gebruiken hun vertrouwde Visual Studio 2008 omgeving voor het ontwikkelen van de logica van de Silverlight applicatie. Designers openen vervolgens hetzelfde project in Microsoft Expression Blend en gebruiken Blend voor het creëren van de user interface. Door het gebruik van verschillende tools mogelijk te maken kunnen zowel developers als designers gebruik maken van een omgeving die is afgestemd op hun specifieke wensen en eisen.
In de Silverlight plugin zit het Silverlight .Net Framework. Het Silverlight .Net Framework is een uitgeklede versie van het gewone .Net Framework. Als je ontwikkelt voor Silverlight, heb je dus niet alle classes uit het gewone .Net Framework tot je beschikking.
Aan de ene kant is dit een noodzaak, omdat eindgebruikers anders voor het draaien van een Silverlight applicatie het volledige .Net Framework van ongeveer 200MB zouden moeten downloaden en installeren, in plaats van de 5MB van het Silverlight .Net Framework. Aan de andere kant is het ook logisch, omdat bepaalde classes niet vaak gebruikt zullen worden in applicaties die op de client draaien. Een voorbeeld hiervan is de System.Data.SqlClient namespace die gebruikt wordt voor het benaderen van een SQL Server database. Aangezien de SQL Server database meestal op de server zal draaien en niet op de client, zul je deze namespace niet missen bij het ontwikkelen van een Silverlight applicatie.
Omdat de Silverlight applicatie op de client draait is het niet mogelijk om data of applicaties op de server direct te benaderen
Omdat de Silverlight applicatie op de client draait is het niet mogelijk om data of applicaties op de server direct te benaderen. Je kunt dus het SharePoint Object Model niet direct aanspreken en je kunt data niet direct uit databases op de server lezen. Toch wil je de data uit de database, of een andere externe data bron, natuurlijk wel graag gebruiken in je applicatie. Geen nood, want Silverlight ondersteunt het gebruik van (web) services. Dit kunnen SOAP services zijn die gebouwd zijn met Windows Communication Foundation (WCF), of gewoon HTTP of REST services. Ook RSS feeds kunnen prima gebruikt worden voor het opvragen van data die in Silverlight web parts getoond wordt.
Het voorbeeld: een Silverlight foto web part
Als voorbeeld zullen we een Silverlight foto web part voor SharePoint gaan bouwen. Het web part toont een rij thumbnails met foto’s uit een bepaalde databron. Als je een foto selecteert, dan wordt boven de rij met thumbnails de grote foto getoond. Het mooie aan dit web part is, dat je met dit ene web part foto’s uit meerdere databronnen kunt tonen, terwijl de code van het web part zelf niet verandert. In dit artikel zal ik laten zien hoe je foto’s uit een SharePoint picture library kunt tonen en hoe je foto’s van Flickr kunt tonen.
Voordat we kunnen beginnen met het bouwen van het web part moeten we eerst SharePoint configureren zodat de SharePoint web applicatie het gebruik van Silverlight ondersteunt.
SharePoint configureren voor Silverlight
Ik ga ervan uit dat je een SharePoint omgeving hebt opgezet waarop minimaal SP1 en de December Cumulative Update voor WSS en MOSS geïnstalleerd zijn. Daarna moet je de volgende stappen doorlopen om Silverlight web parts voor SharePoint te kunnen ontwikkelen:
De SharePoint omgeving is nu geschikt voor het gebruik van Silverlight in pagina’s en web parts. Je kunt nu beginnen met het bouwen van het Silverlight foto web part.
Het three layered application pattern
Het three layered application pattern is een software design pattern. Bij het three layered application pattern wordt de code opgebouwd in verschillende lagen, waarbij het idee is dat elk van deze lagen aan te passen is, zonder dat de andere lagen hier last van hebben.
De drie lagen zijn als volgt gedefinieerd:
- Presentation. De presentatielaag levert de user interface van de applicatie. Dit kan zijn in de vorm van een Windows Form voor een smart client applicatie, maar het kan ook een .aspx pagina, een .ascx control of een Silverlight control zijn.
- Business. De businesslaag implementeert de business logica van de applicatie. De businesslaag bestaat vaak uit meerdere componenten, die binnen de businesslaag allemaal hun eigen functie hebben.
- Data. De datalaag geeft toegang tot externe systemen zoals databases en web services.
Figuur 2 geeft een grafische overview van de verschillende lagen en componenten van het three layered application pattern.

Fig. 2: Het three layered application pattern
Een groot voordeel van het three layered application pattern, dat ook bij het bouwen van Silverlight controls erg duidelijk naar voren komt, is dat een developer de logica van de business- en de datalaag kan ontwikkelen, terwijl een designer vervolgens het design van de presentatielaag kan implementeren. Omdat ik absoluut geen designer ben, zal ik bij het bouwen van het Silverlight Foto web part nauwelijks design toevoegen, maar ik zal wel gebruik maken van het three layered application pattern. Hierdoor kan een designer later het design van de user interface aanpassen en verfraaien, zonder dat daarvoor de logica van het web part aangepast hoeft te worden.
Meer informatie over het three layered application pattern kun je nalezen op http://msdn.microsoft.com/en-us/library/ms978689.aspx.
Het aanmaken van de Visual Studio solution
De eerste stap in de implementatie van het web part is het aanmaken van het web part zelf. Maak hiervoor een project aan in Visual Studio 2008 op basis van het ASP.NET Web Application project type. Ik noem het project Presentation.WebPartUI. Omdat we meerdere projecten aan de solution toe zullen voegen, krijgt de solution de naam SilverlightFotoWebPart.

Fig. 3: Het aanmaken van de solution en het Presentation.WebPartUI project
Visual Studio maakt zelf bij het aanmaken van een web application project een App_Data folder, een default.aspx file en een web.config file aan. Deze zijn niet nodig voor het bouwen van een web part en kunnen dus uit het project verwijderd worden.
De tweede stap in het realiseren van het Silverlight foto web part is het aanmaken van een Silverlight Applicatie project waarin de Silverlight Control zal worden opgeslagen. De naam van dit project kan Presentation.SilverlightUI zijn. Bij het aanmaken van dit project zal je gevraagd worden waar je de HTML pagina wilt hosten waarin je de Silverlight applicatie kunt testen. Kies hierbij voor de derde optie “Link this Silverlight control into an existing Web site” en voeg het toe aan het Presentation.WebPartUI project. Dit zal het testen en deployen van de Silverlight applicatie straks vergemakkelijken.
Vink bij het aanmaken van je Silverlight project aan dat je het wilt testen in een bestaande website. Dit zal het testen en het deployen van de Silverlight applicatie vergemakkelijken

Fig. 4: Het aanmaken van het Presentation.SilverlightUI project

Fig. 5: Het aanmaken van een Silverlight test pagina in het Presentation.WebPartUI project
De derde stap is het aanmaken van het project dat zorgt voor het ophalen van de data uit de Flickr website en de SharePoint picture library. Dit project zal geen specifieke Silverlight componenten bevatten. Het project zal echter wel ‘gereferenced’ worden vanuit het Presentation.SilverlightUI project. Daarom zal het project toch aangemaakt worden als een Silverlight Application project. Je kunt namelijk vanuit een Silverlight project alleen maar referencen naar andere Silverlight projecten. Het Silverlight project wordt immers op de client uitgevoerd en heeft alleen de beschikking over de Silverlight runtime. Je kunt dus niet referencen naar een project dat gebruik maakt van de volledige .NET runtime.
De naam van het project zal Data.ServiceAgents zijn. Ook voor dit project geldt dat er een testpagina aangemaakt moet worden in het Presentation.WebPartUI project. Na het aanmaken van het project kunnen zowel de Page.xaml als de App.xaml files uit het project verwijderd worden, omdat dit project alleen data access zal verzorgen.
Het vierde en laatste project dat aangemaakt moet worden is wederom een Silverlight Application project met de naam Business.Entities. Dit project zal alleen de assembly file als deliverable hebben en er hoeft voor dit project dan ook geen testpagina aangemaakt te worden. Dit heeft te maken met het feit dat er geen .XAP package gedeployed hoeft te worden, maar alleen maar een .DLL file die gereferenced wordt door het Presentation.SilverlightUI project. Ook in dit project kunnen dus de Page.xaml en de App.xaml files na het aanmaken weer verwijderd worden.
Hiermee is de volledige structuur in Visual Studio opgezet. De projecten zijn als volgt over de drie lagen van het three layered application pattern verdeeld:
- Presentation => Presentation.WebPartUI en Presentation.SilverlightUI
- Business => Business.Entities
- Data => Data.ServiceAgents
De volgende stap is het schrijven van de code!
De code
Presentation.WebPartUI
We beginnen met het schrijven van de code voor het web part. Hiervoor maken we in het Presentation.WebPartUI project een nieuwe class aan met de naam SilverlightWebPart.cs. De class zal overerven van System.Web.UI.WebControls.WebParts.WebPart.
In de OnLoad functie wordt de ScriptManager aan de pagina toegevoegd.
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
// Script manager instance may appear only once on a page
ScriptManager scriptManager =
ScriptManager.GetCurrent(Page);
if (scriptManager == null)
{
scriptManager = new ScriptManager();
Controls.Add(scriptManager);
}
}
Listing 1: Toevoegen van de ScriptManager aan de pagina
Maak een property DataSource aan die gebruikt wordt om aan te geven of het web part foto’s moet tonen uit een SharePoint picture library of van Flickr.
private string _dataSource = "SharePoint";
/// <summary>
/// Wwebpart property to determine data source of pictures
/// </summary>
/// <value>The datasource</value>
[WebBrowsable(true)]
[Category("Web Part Settings")]
[WebDisplayName("Data Source")]
[WebDescription("The data source of the pictures.")]
[Personalizable(PersonalizationScope.Shared)]
public string DataSource
{
get { return _dataSource; }
set { _dataSource = value; }
}
Listing 2: DataSource Web Part property
Gebruik vervolgens de CreateChildControls functie om het Silverlight control te laden. De _dataSource property wordt meegegeven aan het Silverlight control met behulp van de InitParameters property van het Silverlight control.
Hiermee is de code voor het Presentation.WebPartUI project al klaar!
protected override void CreateChildControls()
{
// instantiation of the silverlight control
Silverlight silverlightControl = new Silverlight();
silverlightControl.ID = "SilverlightWebpart";
silverlightControl.Source =
“/wpresources/Macaw.IWS.Moss2007.SilverlightDemo.
Presentation.WebPartUI/WebPart-
Macaw.IWS.Moss2007.SilverlightDemo/ClientBin/
Silverlight.UI.xap";
silverlightControl.Width =
new System.Web.UI.WebControls.Unit(100,
System.Web.UI.WebControls.UnitType.Percentage);
silverlightControl.Height =
new System.Web.UI.WebControls.Unit(600);
silverlightControl.InitParameters =
String.Format("DS={0}", _dataSource);
Controls.Add(silverlightControl);
}
Listing 3: Het laden van het Silverlight control
Business.Entities
De volgende stap is het aanmaken van een class MyPhoto in het Business.Entities project. In deze class creeeren we één entity met twee properties: Url en ThumbUrl. Doordat de class gebruik maakt van het .NET Framework 3.5 kunnen we hier gebruik maken van de automatic properties mogelijkheden van C# 3.0. Hierdoor kan deze code in twee regels geschreven worden.
public string Url {get; set;}
public string ThumbUrl {get; set;}
Listing 4: MyPhoto entity
Presentation.SilverlightUI
In het Presentation.SilverlightUI project moeten we nog een klein stukje ondersteunende logica schrijven. Open hiervoor App.xaml.cs. Deze file wordt aangemaakt op het moment dat het Silverlight Application project wordt aangemaakt en bevat logica voor bijvoorbeeld het starten van de Silverlight applicatie. In de Application_StartUp functie voegen we wat code toe voor het initialiseren van de DataSource parameter die we meegegeven hebben vanuit het Presentation.WebPartUI project.
Deze functie zorgt er nu voor dat de constructor van de Page.xaml.cs pagina wordt aangeroepen met de datasource als parameter.
private void Application_Startup(
object sender, StartupEventArgs e)
{
string dataSource = null;
if (e.InitParams != null && e.InitParams.Count > 0)
{
dataSource = e.InitParams["DS"];
}
this.RootVisual = new Page(dataSource);
}
Listing 5: Het initialiseren van de datasource parameter
Ga nu naar de Page.xaml control in het Presentation.SilverlightUI project. Hierin staat standaard al een grid gedefinieerd. Deze kunnen we gewoon laten staan, we halen alleen de breedte en de hoogte van de grid weg. Vervolgens voegen we twee rijen toe aan de grid, de onderste rij is 110 pixels hoog, de bovenste rij zal zo hoog zijn als dat nodig is. Vervolgens voegen we aan de onderste rij een ListBox toe waarin we de collectie van thumbnails horizontaal weergeven.
Aan de bovenste rij voegen we een Image toe voor het weergeven van een grote foto. De hoogte van de Image is 350 pixels, dus de bovenste rij zal een hoogte van ongeveer 350 pixels krijgen.
Figuur 6 is een schematische weergave van de opbouw van het web part. De bedoeling is dat als je op één van de thumbnails in de onderste listbox klikt, deze vergroot weergeven wordt in de bovenste rij.

Fig. 6: Schematische weergave van het web part
<UserControl x:Class="Presentation.SilverlightUI.Page"
xmlns="http://schemas.microsoft.com/winfx/2006/
xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid x:Name="LayoutRoot" Background="White">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="110"/>
</Grid.RowDefinitions>
<ListBox x:Name="listPhotos" Grid.Row="1"
SelectionChanged="listPhotos_SelectionChanged">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Source="{Binding ThumbUrl}"
Width="120" Height="80" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
<Image x:Name="detailImage" Grid.Row="0" Height="350" />
</Grid>
</UserControl>
Listing 6: Page.xaml
In de Page.xaml.cs wordt getest of de datasource die gebruikt moet worden voor het laden van de foto’s SharePoint of Flickr is en aan de hand daarvan wordt bepaald waar de foto’s opgehaald moeten worden.
De parameter die meegegeven wordt aan de functies GetListItemsFromSharePoint en GetItemsFromFlickrProfile is een Lambda expressie. Een Lambda expressie is een functie die geen naam heeft, oftewel een anonieme functie, die wordt toegekend aan een variabele. Via deze variabele is de Lambda expressie dan aan te roepen. In dit geval wordt de functie GetListItemsFromSharePoint aangeroepen met de Lambda expressie, maar als je naar de definitie van GetListItemsFromSharePoint gaat zie je dat de parameter een Action delegate is die als argument een IEnumerable van MyPhotos mee krijgt. Meer informatie hierover vind je bij de uitleg van de code uit het Data.ServiceAgents project.
Tenslotte bevat deze class een eventhandler die ervoor zorgt dat de thumbnail die geselecteerd wordt als grote foto weergegeven zal worden.
public Page(string dataSource)
{
InitializeComponent();
if (dataSource == "SharePoint")
{
GetItemsFromSharePointList sharePointProxy =
new GetItemsFromSharePointList();
sharePointProxy.GetListItemsFromSharePoint(photos =>
listPhotos.ItemsSource = photos);
}
else if (dataSource == "Flickr")
{
GetItemsFromFlickr flickrProxy =
new GetItemsFromFlickr();
flickrProxy.GetItemsFromFlickrProfile(photos =>
listPhotos.ItemsSource = photos);
}
}
private void listPhotos_SelectionChanged(object sender,
SelectionChangedEventArgs e)
{
MyPhoto photo = (MyPhoto)listPhotos.SelectedItem;
BitmapImage bmi = new BitmapImage(new Uri(photo.Url));
detailImage.Source = bmi;
}
Listing 7: Page.xaml.cs logica
Data.ServiceAgents
In het Data.ServiceAgents project voegen we een Service Reference toe die verwijst naar de SharePoint list web service. Om deze reference toe te kunnen voegen moeten we tijdelijk Anonymous Access op de web applicatie toestaan. Dit is in te stellen in IIS door rechts te klikken op de web site van de SharePoint web applicatie en vervolgens naar het tabje Directory Security te browsen. Hier klik je op de Edit button onder Authentication and access control. Check vervolgens de Enable anonymous access checkbox.
Nu kun je de service reference naar http://<webapplicatie>/_vti_bin/lists.asmx aanmaken. Visual Studio zal nu een proxy class genereren die de functies van de web services beschikbaar stelt.

Fig. 7: Het toevoegen van de referentie naar de SharePoint list web service
De volgende stap is het toevoegen van de class GetItemsFromSharePointList aan het Data.ServiceAgents project. In deze class maken we een private Action delegate aan en een functie voor het ophalen van de data uit SharePoint met behulp van de list web service.
Omdat het web part de foto’s ophaalt met behulp van een call naar een web service zal het ophalen van de foto’s asynchroon zijn. Met behulp van de Action delegate _processPhotos specificeren we wat er moet gebeuren nadat de foto’s opgehaald zijn.
Omdat het web part de foto’s ophaalt met behulp van een call naar een web service zal het ophalen van de foto’s asynchroon zijn
Een delegate in C# is ongeveer hetzelfde als een pointer in C of C++. Een delegate houdt een referentie naar een functie vast. Als de delegate wordt meegegeven als parameter van een functie kan de vanuit die functie door de delegate onthouden functie aangeroepen worden.
Een Action delegate is een soort void functie die geen return waarde heeft, maar die alleen een actie uitvoert. De actie kan gedefinieerd worden als een functie die aangeroepen wordt, maar ook als een Lambda expressie. In dit geval roepen we de functie GetListItemsFromSharePoint in de Page.xaml.cs van het Presentation.SilverlightUI project aan met een Lambda expressie als parameter. We hebben deze variabele nodig om tijdens het uitvoeren van de asynchrone actie te onthouden welke code er uitgevoerd moet worden als de asynchrone actie klaar is.
private Action<IEnumerable<MyPhoto>> _processPhotos;
/// <summary>
/// Start an asynchronous service call to get my photos
/// and register a callback method to process the result
/// when it comes in.
/// </summary>
/// <param name="processPhotos">A method that takes
/// one parameter - a collection of MyPhoto - and no result
///</param>
public void GetListItemsFromSharePoint(
Action<IEnumerable<MyPhoto>> processPhotos)
{
_processPhotos = processPhotos;
ListsSoapClient proxy = new ListsSoapClient();
proxy.GetListItemsCompleted +=
proxy_GetListItemsCompleted;
// Build XML elements for querying SharePoint list
XElement fieldRef = new XElement("FieldRef");
fieldRef.SetAttributeValue("Name", "Created");
fieldRef.SetAttributeValue("Ascending", "FALSE");
XElement orderBy = new XElement("OrderBy", fieldRef);
XElement query = new XElement("Query", orderBy);
XElement viewFields = new XElement("ViewFields");
XElement queryOptions = new XElement("QueryOptions");
proxy.GetListItemsAsync(
"Barcelona", "", query, viewFields, "10",
queryOptions, "");
}
Listing 8: Asynchroon ophalen van data uit de SharePoint picture library
De list items worden opgehaald met behulp van de GetListItemsAsync methode. In de parameters wordt de naam van de lijst (in mijn geval Barcelona), de sortering (in het Query element) en het maximum aantal records dat er teruggegeven moet worden (10) meegegeven.
Op het moment dat alle list items zijn opgehaald zal de eventhandler GetListItemsCompleted afgevuurd worden. Hiermee wordt de functie proxy_GetListItemsCompleted aangeroepen. In deze functie worden met behulp van een eenvoudige LINQ query de juiste waarden aan de velden in de MyPhoto entity toegewezen. Bij een SharePoint picture library geldt dat de url van de foto is opgeslagen in het ows_EncodedAbsWebImgUrl veld en dat de url van de thumbnail is opgeslagen in het ows_EncodedAbsThumbnailUrl veld. Vervolgens wordt de Action delegate uitgevoerd met als paramater de IEnumerable van de MyPhoto entities om de binnen gekomen foto’s te gaan verwerken. Dit houdt in dat op dit moment de ItemSource van de listPhotos uit de Page.xaml.cs in het Presentation.SilverlightUI project zijn waarde krijgt toegekend.
Ik zal in dit artikel niet de volledige code voor het ophalen van de data van Flickr weergeven. De manier waarop het ophalen van data van de Flickr site werkt is vrijwel gelijk aan de manier waarop je data uit een SharePoint picture library ophaalt. Het belangrijkste verschil zit hem in het feit dat je een andere web service aanroept (namelijk die van Flickr en niet de SharePoint list web service) en dat de XML die de web service terug geeft er iets anders uit ziet. De volledige solution is te downloaden op de SDN web site.
private void proxy_GetListItemsCompleted(
object sender, GetListItemsCompletedEventArgs e)
{
if (e.Error != null)
{
MessageBox.Show(e.Error.ToString());
}
else
{
XElement result = e.Result;
var photos =
from x in result.Elements().First().Elements()
select new MyPhoto
{
Url = x.Attribute("ows_EncodedAbsWebImgUrl").Value,
ThumbUrl = x.Attribute(
"ows_EncodedAbsThumbnailUrl").Value
};
_processPhotos(photos);
}
}
Listing 9: LINQ query om de foto en thumbnail urls uit de resultaten te halen
Deployment
Als je al deze stappen hebt uitgevoerd is je code klaar om gedeployed te worden. Het gaat voor dit artikel te ver om uitgebreid te beschrijven hoe deze componenten in een SharePoint Solution package verpakt kunnen worden. Meer informatie hierover is te vinden online te vinden:
Wel zal ik aangeven welke files er gedeployed moeten worden en waar deze dan terecht zouden moeten komen.
- De web part assembly, Presentation.WebPartUI.dll, moet gedeployed worden naar de bin directory van de web applicatie. In mijn geval is het path C:\Inetpub\wwwroot\wss\VirtualDirectories\moss2007dev\bin. De assembly kan ook naar de GAC gedeployed worden, maar dat is geen best practice.
- De Silverlight controls moeten naar de ClientBin gedeployed worden. Deze zou op diverse plekken kunnen staan, maar ik zal hem uitrollen naar de wpresources folder van de web applicatie C:\Inetpub\wwwroot\wss\VirtualDirectories\moss2007dev\wpresources\SilverlightFotoWebPart\ClientBin. De Silverlight controls zijn ingepakt in de Presentation.SilverlightUI.xap file. Dit is eigenlijk een zip file, als je de file hernoemt naar.zip kun je de inhoud ervan bekijken. Als een gebruiker een pagina opvraagt met een Silverlight control zal het .xap bestand gedownload worden naar de computer van de gebruiker. Vervolgens zal de Silverlight plug in die op de computer van de gebruiker geinstalleerd is de .xap file uitpakken. Voor het SilverlightFotoWebPart hebben we alleen de Presentation.SilverlightUI.xap file nodig, deze bevat
- Business.Entities.dll
- Data.ServiceAgents.dll
- Presentation.SilverlightUI.dll
- Tenslotte moet alleen nog de automatisch aangemaakte Silverlight.js file gedeployed worden. Deze wordt uitgerold naar de wpresources folder van de web applicatie, dus naar C:\Inetpub\wwwroot\wss\VirtualDirectories\moss2007dev\wpresources\SilverlightFotoWebPart.
Als de files naar de juiste locatie gedeployed zijn kun je het web part toevoegen aan een pagina in de SharePoint omgeving en het resultaat uit figuur 8 bewonderen!

Fig. 8: Het resultaat, het Silverlight foto web part
De sources die bij dit artikel horen kun je downloaden via olst_silverlightwebpartsinSP_SRC.zip.