Building an interactive dashboard with SharePoint 2010 RESTful Services

REST (or Representational State Transfer) is an easy way to easily get or post items to a server-side web service.  It is used in situations where you would use a web service but do not want the overhead and tightly-coupled nature of SOAP.   Technically, REST is not a protocol, but an architectural style. It complies to Open Data Protocol (OData), a Web protocol for querying and updating data that provides a way to unlock your data and free it from silos that exist in applications today.

SharePoint 2010, being based on WCF in the .NET 3.5 Framework, has built-in RESTful web services which allow us to take advantage of this simplicity in custom applications we write..

The RESTful service can be accessed via  http://<site collection url>_vti_bin/ListData.svc

This blog post is based on my Demo #2 last week at MOSSIG user group meeting in Melbourne.

 

uuo

 

The Data for this dashboard is sourced from 2 custom lists “Products” and “Sales”  The two lists has parent-child relationship.

aas

 

Sales List

aas2

Edit Sale Item.

aas5

 

Any given list can be accessed via the RESTFul service. This demo application is using  WCF Data Services to read/write to sharepoint  list Data, then, WCF Data Services  was the first Microsoft technology to support the Open Data Protocol. It provides developers with client libraries for .NET, Silverlight, AJAX etc..

image

Once the service proxy is created from ListData.svc you will have typed access to all the list data with LINQ support.  The following code segment in the ViewModel  shows how sales data is obtained from the service along with corresponding product details and register for Unit of Work tracking when property change.

 

private void GetSalesData() { // Set up the data context if it hasn't been done already if (_dataContext ==null) { _dataContext = new HomeDataContext( new Uri("http://spdemo/_vti_bin/ListData.svc")); } Sales = new ObservableCollection<SalesItem>(); //Prepare REST service request var query = (from s in _dataContext.Sales.Expand("ProductCode") select s ) as DataServiceQuery<SalesItem>; query.BeginExecute( (ar) => { IEnumerable<SalesItem> _salesItems = query.EndExecute(ar); foreach (SalesItem item in _salesItems) { item.PropertyChanged += ((sender, e) => { var entity = (SalesItem)sender; //track changes to entities _dataContext.UpdateObject(entity); }); Sales.Add(item); } NotifyPropertyChanged("LineValue"); }, null) ; }

The viewModel implements INotifyPropertyChanged event for the purpose of Notifying the view of Data changes and visa versa. The ViewModel exposes two properties LineValue (bound to the slider) and ObservableCollection of SalesItems. These 2 properties are declaratively bound to both chart types (bar and pie). I am using few charting controls  from Silverlight Toolkit (http://silverlight.codeplex.com/)  with XAML Declarative bindings as shown below.  

 

            <TextBlock x:Name="ScoreTextBlock" Text="{Binding LineValue}" />
            <chart:Chart Height="200" LegendTitle="Item" Title="No of Units Sold By Product" 
                         x:Name="MyBarChart" Width="562" DataContext="{Binding}">
            <chart:ColumnSeries x:Name="MySalesChartData" Title="Sales of Products" 
                    ItemsSource="{Binding Sales}"
                    IndependentValueBinding="{Binding ProductCode.ProductName}"
                    DependentValueBinding="{Binding NoofUnits}"/>
            </chart:Chart>
            <chart:Chart Height="230" Title="Sales Distribution" x:Name="MyPieChart" Width="562" Margin="4,0">
                <chart:PieSeries ItemsSource="{Binding Sales}" 
                    IndependentValueBinding="{Binding ProductCode.ProductName}"
                    DependentValueBinding="{Binding NoofUnits}" Background="#FF2B1515" />
            </chart:Chart>

The VS2010  solution that contains source code for this demo is uploaded here.

Enjoy!


SharePoint 2010 Live Image Capturing WebPart packaged as a Sandbox solution

It was great speaking and networking with fellow members at MOSSIG July meeting in Melbourne last week. I presented a session on Effective use of SilverLight 4 with SharePoint 2010.  The Slide deck is uploaded here. I demoed a SilverLight 4 WebPart  taking a snapshot on demand and with the help of  client object model  automatically save the captured snapshot to SharePoint picture library.

This demo solution was created to showcase effective use of SilverLight 4  in SharePoint 2010 as well as to show how MVVM (Model-View-ViewModel)  pattern pattern is used in designed and developing maintainable and testable SilverLight applications with powerful declarative Data binding capabilities

I thought of writing a little elaborative blog post about this solution and here we go…

First lets have a look at the outcome.

Final Result:

Untitled3

By the way this is my little boy Bryan. He enjoyed this a lot  🙂

The picture library to be used for storing the captured images can be configured by the user as shown below as a WebPart property.

Untitled1

 

Solution Type:

This  is sandbox solution. Therefore as site collection administrator you can add this solution to your solution gallery and try out its functionality with minimal impact on your farm as compared to a classic farm solution. SharePoint perform resource monitoring of your sand box solutions  as shown below. If it doesn’t behave properly it will be kicked out by SharePoint before you even know about it at times . How cool is that ?

This is a great model for ISV’s to distribute their apps and Farm/Site Collection Administrators to trial out third-party solutions with minimum risk.

image

 

Solution architecture:

The basic solution archtecture is shown below.  The viewmodel is decorating the model/Repository  and sits between your model(domain objects) and the view.  MVVM is targeted at modern UI development platforms (WPF and Silverlight). You can read more about this simple pattern  here

Untitled44

The VS2010 solution structure for this application is as follows.

Untitled4 

SandBox WebPart properties:

One of the limitation with running in the sandbox is that all web parts must inherit from “System.Web.UI.WebControls.WebParts.WebPart” instead of “Microsoft.SharePoint.WebPartPages” (which is not allowed)  when running in the sandbox.  This means the traditional means of creating custom Web Part Properties using the ToolPart object in SharePoint is not available.  Thus one must now rely on how these custom properties are created when dealing with ASP.Net Web parts.  Which by the way (as is obvious in the sandbox restriction) is now the preferred way to create web parts.  ASP.Net Web Parts have an equivalent class to the “ToolPart” class called the “EditorPart”. So I’ve created my webpart property editor inheriting from EditorPart as shown below.

// Create a custom EditorPart to edit the WebPart control.
 [AspNetHostingPermission(SecurityAction.Demand,
     Level = AspNetHostingPermissionLevel.Minimal)]
 public class SLWebCamEditorPart : EditorPart
 {
     private DropDownList _partTargetLibrary;

     public SLWebCamEditorPart()
     {
         Title = "Image capture webpart settings";
     }

     private DropDownList PartTargetLibrary
     {
         get
         {
             EnsureChildControls();
             return _partTargetLibrary;
         }
     }

 
 
Passing initialize parameters into Silverlight from Sharepoint:
 
The CreateChildControls Method in the hosting webpart injects SilverLight host control  into the WebPart as shown below.  In this case we are injecting the current site URL and target picture library name as ‘initparams’ into the SilverLight host control.
NOTE: It is important to inject the current site URL in order to guarantee the ClientContext (in SharePoint client OM ) is not NULL during  runtime execution.
[Personalizable, WebBrowsable(false)]
public String PictureLibraryName { get; set; }

protected override void CreateChildControls() { var width = "400"; var height = "600"; base.CreateChildControls(); string source = SPContext.Current.Site.Url + "/_catalogs/masterpage/SLWebCam.xap"; Controls.Add(new LiteralControl( "<div>" + " <object data=\"data:application/x-silverlight-2,\" type=\"application/x-silverlight-2\" width=\"" + width + "\" height=\"" + height + "\">" + " <param name=\"source\" value=\"" + source + "\"/>" + " <param name=\"onerror\" value=\"onSilverlightError\" />" + " <param name=\"background\" value=\"white\" />" + " <param name=\"minRuntimeVersion\" value=\"4.0.50401.0\" />" + " <param name=\"autoUpgrade\" value=\"true\" />" + " <param name=\"initParams\" value=\"MS.SP.url=" + SPContext.Current.Site.Url + ",PictureLibraryName=" + PictureLibraryName +     

…..Continue..

The injected initparam  values in the serverside can be extracted from the client side and stored as application resource as shown below.

private void Application_Startup(object sender, StartupEventArgs e)
{   // Extract init params and inject into application resource dictionary
    foreach (var resource in e.InitParams)
    {
        Application.Current.Resources.Add(resource.Key,resource.Value);
    }
    this.RootVisual = new MainPage();
}

Declarative DataBinding:

The XAML based view was created using VS2010 enhanced UI designer. The ViewModel exposes the necessary bindable properties and bindable commands (using command pattern). In other words ViewModel is the datacontext for the View

ie: XAML markup for showing the live web cam video uses a Rectangle bound to a property named VideoBrush in the ViewModel as shown below.

<Rectangle Fill="{Binding VideoBrush}" Height="138" Width="170" />

private VideoBrush videoBrush;
public VideoBrush VideoBrush
{
    get { return videoBrush; }
    set
    {
        videoBrush = value;
        FirePropertyChanged("VideoBrush");
    }
}

The view Model implements INotifyPropertyChange interface. Notifies clients that a property value has changed. The snapshots taken are exposed as a ObservableCollection of Writable bitmaps from the ViewModel and bound to a ListBox with  a DataTemplate as shown below. ObservableCollection  Represents a dynamic data collection that provides notifications when items get added, removed, or when the whole list is refreshed.

public ObservableCollection<WriteableBitmap> Images { get; set; }
   public ICommand StartCaptureCommand { get; set; }
   public ICommand StopCaptureCommand { get; set; }
   public ICommand TakeSnapshotCommand { get; set; }
   public ICommand SaveSnapshotCommand { get; set; }

<ListBox x:Name="Snapshots" ItemTemplate="{StaticResource SnapshotDataTemplate}" ItemsPanel="{StaticResource SnapshotItemsPanelTemplate}" ItemsSource="{Binding Images}" SelectedItem="{Binding SelectedSnapshot, Mode=TwoWay}" Height="123"

Width="356" />

Saving the Captured Image to the Sharepoint picture Library:
In order to use sharepoint client OM all you need is referencing the following 2 assemblies from SP root folder. Web Server Extensions\14\TEMPLATE\LAYOUTS\ClientBin  and use the following namespace from silveright.

image
using Microsoft.SharePoint.Client;
I am also using SilverLight Image manipulation library “ImageTools” from   http://imagetools.codeplex.com/ for handing bitmap processing in the client side.

When the user select a snapshot and click the save button ClientContext is initiated and List information is obtained from the server via Client OM as a Asynchronous operation.  On the successful callback FileCreationInformation object is created with the image content , add the new file  to the list of files and commit is performed as a another asynchronous call to the server.
 
/// <summary>
 /// Obtain list instance with required minimum information via Client OM
 /// </summary>
 private void GetSpTargetListInfo(string listname)
 {
     //first build the workload 
     _targetlist = _ctx.Web.Lists.GetByTitle(listname);
     _ctx.Load(_targetlist, l => l.RootFolder.ServerRelativeUrl);
     //now execute it as a on single batch  
     _ctx.ExecuteQueryAsync(ListloadSucceeded, ListloadFailed);
 }

private void ListloadSucceeded(object sender, ClientRequestSucceededEventArgs e) { if (_img == null) return; using (Stream fs = _img.ToStream()) { var fileContent = new byte[fs.Length]; fs.Read(fileContent, 0, fileContent.Length); //create file object var file = new FileCreationInformation { Content = fileContent, Url = ApplicationContext.Current.Url + 

_targetlist.RootFolder.ServerRelativeUrl + "/" + Guid.NewGuid() + ".png" }; //add the new file to the target list var files = _targetlist.RootFolder.Files; files.Add(file); //Now execute the workload _ctx.ExecuteQueryAsync(UploadRequestSucceeded, UploadRequestFailed); } }

 

If you want to play with the webcam webpart a packaged Sandbox solution (SpImageCapture.wsp) can be downloaded here.  When activating this solution Silverlight .XAP file named SLWebCam.xap will be created in the site masterpage gallery and a hosting WebPart will be added to your WebPart gallery named SLWebCamWebPart.webpart  Drag this WebPart to your page and configure its web part properties by specifying a picture library to use for storing the images and you are done.   I’ve also uploaded the  full VS2010 solution here if you are interested in the code.

Enjoy!


Getting Started with Silverlight and SharePoint 2010 at #DDDMelbourne

I was honoured to be speaking at DDDMelbourne developer conference last weekend in Melbourne. Thanks you every one who voted, attended and commented on my session “Getting Started with Silverlight and SharePoint 2010”. With SharePoint 2010 and Visual Studio 2010 the developer story has come a long way. SharePoint now is integrated into Visual Studio 2010 as a first-class platform Silverlight 4.0 provides the opportunity for developers to create the next generation of Rich Internet Applications (RIAs). SharePoint 2010 integrates closely with Silverlight to enable you to build compelling user interfaces that interact with SharePoint for deep data integration with line-of-business systems. This session will covers the techniques, data access strategies and developer productivity enhancements and for rapidly building and deploying Silverlight 4 applications on SharePoint 2010 platform including SharePoint Client Object Model, RESTful services along with Sandboxed Solutions.

The Slide deck is upload here


Handling WCF FaultExceptions with SilverLight 3

Silverlight 3 Introduced the capability of handling WCF fault exceptions.

Using FaultContracts is a good way of managing and shielding WCF exceptions, but I also wanted the silverlight client to be able to:

  • Catch generic CLR exceptions and propagate them to the client as a generic fault exceptions.
  • Catch some application specific exceptions and propagate these to the client as a general fault so that I can build the logic around the client to escalate the the cause that raised the exception in runtime.
  • Log any unhandled exceptions that may sneak there way up to the services.

Whenever sensitive data is involved create a fault exception and pass the error data to the client sufficient enough to build the logic around the client to handle the fault senario

WCF provides great exception shielding by default, but we wanted a bit more control. This is where WCF IErrorHandler interface allows you to intercept any faults or exceptions before they are sent back to the client. To use this properly, you still need to define your FaultContract as required for expected exceptions.

However By default, WCF services return fault messages with an HTTP 500 response code. Due to limitations in the browser networking stack, the bodies of these messages are inaccessible within Silverlight 3 , and consequently the fault messages cannot be read by the client.

To send faults to a Silverlight client that are accessible to it, an WCF service must modify the way it sends its fault messages. The key change needed is for WCF to return fault messages with an HTTP 200 response code instead of the HTTP 500 response code. This change enables Silverlight to read the body of the message and also enables WCF clients of the same service to continue working using their normal fault-handling procedures.

The modification on the server can be made by defining a WCF endpoint behavior for Silverlight faults. Then this behavior can be enforced either by service contract declarative style or via configuration. More details about this can be found here

The attached sample Silverlight project shows how message behaviour extensions,Fault contracts and IErrorHandler interfaced is used to achieve the above requirement.


Develop a Sandboxed Silverlight 3.0 Web part for SharePoint 2010

I recently had a chance to play around with the Silverlight Bing map control  v1 SDK and thought of integrating the map functionality with SharePoint  as a web part. In this post I am going to through the steps I’ve taken to accomplish this task. Basically we are going to develop a Silverlight 3.0 web part  as a sandbox solution for SharePoint 2010. Our web part will be interacting with SharePoint 20101 new Client object model to access data stored in a custom list to render the map with locations as pin points. The end functionality will looks as below. Out custom SharePoint list stores the locations with their Latitude and Longitudes.

image

You need to have SharePoint 2010 dev box, Visual Studio 2010 and Expression Blend 3, Silverlight Bing map control library installed for this task. I have outlined the steps required to setup a development environment for SharePoint 2010 in my previous blog post.

Let’s get started.

Step1: Create a new Silverlight 3.0 application in Visual Studio 2010

image

Step2: Choose to host your SilverLight application in a ASP.NET Web Application project.

image

Step3: Add the SharePoint 2010 reference DLL’s to interact with Client object model  into the Silverlight project that you have created. The two dll’s that you need to reference are located in the folder 14\TEMPLATE\LAYOUTS\ClientBin

image

Step 4: Download and install  Bing Maps Silverlight Control SDK. The interactive live SDK can be found here. You will also need a developer key to assess Bing maps which can be obtain from here.  Once the SDK is installed reference the Bing map dll’s (2) in your silverlight project. by default the those dll’s are present in C:\Program Files (x86)\Bing Maps Silverlight Control\V1

Once all necessary dll’s references are added our Silverlight project looks as below.

image

Step 5: Now its time to design the user interface with XAML for our web part. Import the xml namespace for Bing map control in the in MainPage.xaml file.

xmlns:m="clr-namespace:Microsoft.Maps.MapControl;assembly=Microsoft.Maps.MapControl"

once the above name space is imported all you need is  <m:Map/> to place the map control in your user interface. I’ve used expression Blend 3 to author XAML and output looks as below. Basically I got a simple Grid layout with TextBlock and Map control with the default map location points to central Australia with “Road” mode and  with zoom level 4.3. You can set these values as per your requirements. The CredentialsProvider key is what you get when you create a developer account for Bing map control.

<UserControl x:Class="SLFactoryMap.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:m="clr-namespace:Microsoft.Maps.MapControl;assembly=Microsoft.Maps.MapControl"
    mc:Ignorable="d">
    <UserControl.Resources>
        <Style x:Key="HeaderStyle" TargetType="TextBlock">
            <Setter Property="FontWeight" Value="Bold"/>
            <Setter Property="FontStyle" Value="Normal"/>
            <Setter Property="FontSize" Value="13.333"/>
            <Setter Property="Margin" Value="0,0,0,0"/>
            <Setter Property="VerticalAlignment" Value="Top"/>
            <Setter Property="HorizontalAlignment" Value="Center"/>
            <Setter Property="Foreground">
                <Setter.Value>
                    <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                        <GradientStop Color="Black" Offset="0"/>
                        <GradientStop Color="#FF725E5E" Offset="1"/>
                    </LinearGradientBrush>
                </Setter.Value>
            </Setter>
            <Setter Property="Margin" Value="5,0,0,0"/>
        </Style>
    </UserControl.Resources>

    <Grid x:Name="LayoutRoot" Background="#FF64D3DC" Width="600" Height="490">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="0.04*"/>
            <RowDefinition Height="0.92*"/>
        </Grid.RowDefinitions>
        <TextBlock Height="20" Style="{StaticResource HeaderStyle}" Grid.Row="0" Grid.Column="0"  d:LayoutOverrides="Height" Grid.ColumnSpan="2"> Production Sites </TextBlock>
        <m:Map x:Name="factorymap" Grid.Row="1" Grid.Column="0" CredentialsProvider="{your key}" Mode="Road" ZoomLevel="4.3" Center="-25.7000,133.8833"/>
    </Grid>
</UserControl>

Above XAML code will render out UI in visual studio canvas designer as shown below.

image

Step 6: Now its time to create our code behind class MainPage.xaml.cs  in C#

First import the following names spaces

using SP = Microsoft.SharePoint.Client;
using Microsoft.Maps.MapControl;

then create the following class level members

SP.ClientContext _context;
SP.Web _currentWeb;
SP.List _locationList;
SP.ListItemCollection _locations;

Then we need to create the UI loaded routed event handler and obtain the SharePoint client context reference so that we can access  sharepoint client object model. Once we get a reference to the object model (web) which corresponds to the SPWeb in server context, we are obtaining a client reference to the “factoylocations” custom list which stores our locations. We are going to access all the list items in that list. Therefore we need a CAML query with no filters. To reduce server calls we batch up all the server requests and make one single call to the server to obtain list data. In the end we make a Asynchronous call to the server by calling _context.ExecuteQueryAsync . At this point SharePoint Client object model calls WCF Services perform authentication,  calls service methods and obtain the results for us which frees us from lot of plumbing work. This is a massive developer productivity feature comes with SharePoint 2010.

void MainPage_Loaded(object sender, RoutedEventArgs e)
{    // get the current client context
    _context = SP.ClientContext.Current;
    // get a reference to the current web
    _currentWeb = _context.Web;
    //get a reference to the list that contains locations
    _locationList = _currentWeb.Lists.GetByTitle("FactoryLocations");
    //we need to obtain all items in the location list.
    SP.CamlQuery query = new SP.CamlQuery();
    query.ViewXml = "<View></View>";
    _locations = _locationList.GetItems(query);
    //batch up the work to perform
    _context.Load(_locationList);
    _context.Load(_locations);
    _context.ExecuteQueryAsync(clientRequestSucceeded, clientRequestFailed);
}

Once the sever request is completed we need a call back method which needs to run in the UI thread. Our clientRequestSucceeded callback method looks as below. Here we iterate through the listitem collection and create Pushpin for each location listitem.

Dispatcher.BeginInvoke make sure that our anonymous method get executed in the client UI thread.

/// <summary>
/// Event handler for get request succeeded
/// </summary>
private void clientRequestSucceeded(object sender, SP.ClientRequestSucceededEventArgs e)
{
    //execute the code in the UI thread as a anonymous method
    Dispatcher.BeginInvoke(() =>
    {
      try
        {
          foreach (SP.ListItem loc in _locations)
           {
             Location location = new Location((Double)loc["Latitude"], (Double)loc["Longitude"]);
             // The pushpin to add to the map.
             Pushpin pin = new Pushpin();
             pin.Location = location;
             // Adds the pushpin to the map.
             factorymap.Children.Add(pin);
           }
       }
      catch (Exception ex)
       {
            MessageBox.Show(ex.ToString());
       }
   });
}

Failed request handler looks as below.

/// <summary>
/// Event handler for get request failed
/// </summary>
private void clientRequestFailed(object sender, SP.ClientRequestFailedEventArgs e)
 {   //execute the code in the UI thread as a anonymous method
   Dispatcher.BeginInvoke(() =>
   { MessageBox.Show(string.Format("Error occured in displaying factory locations:  {0}", e.Message)); }
   );
 }

Finally we need to make sure that loaded event is wired up to the main page constructor as shown below

public MainPage()
{
    InitializeComponent();
    Loaded += new RoutedEventHandler(MainPage_Loaded);
}

Step 7: At this point we can build the project and we should be able to see the SilverLight .xap file get generated. Next Add a empty SharePoint project to the solution. Point the URL to the site collection you are working with and Select Deploy as a SandBoxed solution option. SandBoxed SharePoint Solution Package files (WSP files) that are limited in what they can do and in the server resources they can use. What they can do is limited using Process Isolation and Code Access Security limited to the SharePoint Site. The resources they can use are limited by process monitoring, logging and log aggregation. Executing Code in the Sandbox Executing Code in the Sandbox The Sandboxed Solutions Service provides for a complete isolation system that ensures code running in a sandboxed solution cannot reach out to access information beyond the scope of the deployment. Specifically, sandboxed solutions will not be able to make updates to the SharePoint object model beyond the scope of the SPSite object. Farm level and web application level changes are allowed only for read operations. This gives best option for developers as well as farm administrators.

image

Step 8: Add a module a New Item to the SharePoint Project. In this case I call it FactoryMapModule. This module item is used to include the .xap file into the SharePoint solution. Therefore we need to tell the module, the location of our .xap file. Right click the module item –> go to properties > Select Output References. In the Dialog box Click Add button. Select your SilverLight Project Name. In this case it was SLFactoryMap. Also select the deployment type as ElementFile. Finally Click OK.

Now we have our .xap file generated by the SilverLight project included as a dependency for our module.

image

Now our solution structure should look as shown below.

image

Step 9: Update element.xml file of the module item. add a File section and include the XAP file path (source path) and Url (relative URL after deployment)

image

Step 10: At this point we are ready to build the project and deploy the SharePoint solution. Right Click the SharePoint project and Select “Deploy” option. This action will build our project, Create a .wsp Solution file and deploy the solution into SharePoint solution gallery in the specified site collection and activate the feature. Now we can go to the solution galley as the Site Collection administrator and view our solution in the solution store.

Go to Site Settings –> Galleries –> Solutions

image

image

Step 11: Create a custom list in the site with the name “FactoryLocations” with two columns named “Longitude” and “Latitude” and fill some sample data init. Our web part is going to consume this data when rendering the map.

Step 12: Add the Silverlight web part to a web part page. SharePoint 2010 provides a wrapper web part (under media and content category) to host Silverlight .xap files. The concept  is similar to SmartPart approach we have in WSS3/MOSS 2007.  Therefore we need to add this wrapper  web part first into the page that you want to place the Silverlight web part as shown below.

image

Step 13: Specify the relative path of the .xap file to the Silverlight web part. In this sample the .xap file is located in the root of the site collection.

Note: Also set the Chrome type to None in the Silverlight web part properties.(This is a workaround for a bug present in Beta 2 in rendering the title of Silverlight web part)

image

Now we should be able to visualize the map control in our Silverlight Webpart with locations specified in our list marked as Pinpoints. The sandbox worker process is where your actual code runs! This is in contrast to having the code run inside of w3wp.exe. This is why you don’t have to restart the application pool every time your redeploy an sandbox solution. If you wish to debug a sandbox solution, and for any reason why F5 debugging is not working, you will need to attach your visual studio debugger to the SPUCWorkerprocess.exe process.

As we have seen the power of Silverlight 3.0 along with SharePoint 2010 client object model enhance developer productivity and open up lot of opportunities to build rich interactive applications leverage on SharePoint 2010 platform.