ARTICLES

Home  > Articles  >  Incorporating Silverlight application into SharePoint custom application pages
Incorporating Silverlight application into SharePoint custom application pages
by Yaroslav Pentsarskyy

Hosting Silverlight applications within client web administration modules of many solutions has become more popular than ever. Mainly due to rich presentation and client execution benefits. Many are looking into utilizing already known SharePoint framework to host their Silverlight applications. There are quite few challenges that are involved in setting up your Silverlight application to run on MOSS/WSS and this article will outline all of them step by step so you can get started right away.
 
I assume you use Visual Studio 2008 to create your Silverlight application with .NET 3.5. In further articles we'll explore setting up Silverlight (on .NET 4.0) applicaption that was created using Visual Studio 2010 Beta 1.
 
First, your need to have .NET 3.5 Framework installed with all of the latest updates and service packs.
Secondly, ensure you have Silverlight 2.0 SDK installed on your system.
Finally, install Visual Studio 2008 extensions for Silverlight.
 
Once you have all of the components above installed you can start with creating your Silverlight applicaption, unless you have it already.
 
I recommend creating Silverlight application as a web application. Use Visual Studio 2008 "Publish" feature, right click web application project and click "Publish ...". Once the package is deployed to the file system copy the contents to the designated server where you will be hosting your MOSS and Silverlight.
 
I recommend creating a test website on your target server machine on a different port and dropping the package generated in the step above to the directory of the new website.
The reason why this is a good idea - is to ensure your web application and Silverlight component of it runs properly before you embark on deploying non working solution to MOSS (which complicates things of course).
 
Once you confirm that your web application is running, you can start configuring your MOSS to work with Silverlight.
 
First step is to set up "web.config" of the MOSS applicaton to load Silverlight dependencies and assemblies.
 
I recommend opening "web.config" of the application that came with the Visual Studio "Publish ..." routing and inserting parts of it into your MOSS application web.config as follows:
 
1. Find <configSections> in target web.config and insert the following:
 
<sectionGroup name="system.web.extensions" type="System.Web.Configuration.SystemWebExtensionsSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
        <sectionGroup name="scripting" type="System.Web.Configuration.ScriptingSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
          <section name="scriptResourceHandler" type="System.Web.Configuration.ScriptingScriptResourceHandlerSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
          <sectionGroup name="webServices" type="System.Web.Configuration.ScriptingWebServicesSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
            <section name="jsonSerialization" type="System.Web.Configuration.ScriptingJsonSerializationSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="Everywhere" />
            <section name="profileService" type="System.Web.Configuration.ScriptingProfileServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication" />
            <section name="authenticationService" type="System.Web.Configuration.ScriptingAuthenticationServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication" />
            <section name="roleService" type="System.Web.Configuration.ScriptingRoleServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication" />
          </sectionGroup>
        </sectionGroup>
      </sectionGroup>
 
2. Find <assemblies> in target web.config and insert the following:
 
<add assembly="System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
<add assembly="System.Data.DataSetExtensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
<add assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add assembly="System.Xml.Linq, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
 
3. Find <pages> in target web.config and insert the following:
 
<controls>
          <add tagPrefix="asp" namespace="System.Web.UI" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
          <add tagPrefix="asp" namespace="System.Web.UI.WebControls" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
        </controls>
 
 
4. Find <httpHandlers> in target web.config and insert the following:
 
<remove verb="*" path="*.asmx"/>
        <add verb="*" path="*.asmx" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
        <add verb="*" path="*_AppService.axd" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
        <add verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" validate="false"/>
 
 
5. Find <httpModules> in target web.config and insert the following:
 
<add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
 
 
6. Find <runtime> in target web.config and insert the following BEFORE ACTUAL <runtime> tag:
 
<system.webServer>
      <validation validateIntegratedModeConfiguration="false"/>
      <modules>
        <remove name="ScriptModule" />
        <add name="ScriptModule" preCondition="managedHandler" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
      </modules>
      <handlers>
        <remove name="WebServiceHandlerFactory-Integrated"/>
        <remove name="ScriptHandlerFactory" />
        <remove name="ScriptHandlerFactoryAppServices" />
        <remove name="ScriptResource" />
        <add name="ScriptHandlerFactory" verb="*" path="*.asmx" preCondition="integratedMode"
             type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
        <add name="ScriptHandlerFactoryAppServices" verb="*" path="*_AppService.axd" preCondition="integratedMode"
             type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
        <add name="ScriptResource" preCondition="integratedMode" verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
      </handlers>
    </system.webServer>
 
 
6. Find <runtime> in target web.config and insert the following within <runtime> tag:

 
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
        <dependentAssembly>
          <assemblyIdentity name="System.Web.Extensions" publicKeyToken="31bf3856ad364e35"/>
          <bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="3.5.0.0"/>
        </dependentAssembly>
        <dependentAssembly>
          <assemblyIdentity name="System.Web.Extensions.Design" publicKeyToken="31bf3856ad364e35"/>
          <bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="3.5.0.0"/>
        </dependentAssembly>
      </assemblyBinding>
 
Our web.config is ready and now I recommend porting over part of the Silverlight application and testing whether it works on its own before incorporating MOSS masterpage.
 
First, copy the contents of the bin folder (from the package generated by VS2008 when performing "Publish") to the bin folder of your associated MOSS web application folder (for example.: C:\inetpub\wwwroot\wss\VirtualDirectories\80\bin).
Next, drop "System.Web.Silverlight.dll" from the same bin directory to your "C:\Windows\Assembly". Perform IISRESET so that system picks up new DLL from GAC.
Finally, create ASPX page in your "12/layouts/yourfoldername" folder that will have the contents of the Silverlight test ASPX page generated by VS2008 during "Publish" routing (for example: SilverlightApplication1TestPage.aspx)
 
Open the folder generated by VS "Publish" and copy the following to the "12/layouts/yourfoldername": 
1. ClientBin
2. Silverlight.js
 
Try executing the page (in our case: SilverlightApplication1TestPage.aspx) and ensure it loads with all of the intended Silverlight content.
 
At last, we are ready to wrap oput page with SharePoint masterpage content by following the steps below:
 
1. Replace the content of the sample ASPX page you tested with the following:
 
<%@ Assembly Name="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register Assembly="System.Web.Silverlight" Namespace="System.Web.UI.SilverlightControls" TagPrefix="asp" %>
 
<%@ Page Language="C#" MasterPageFile="~/_layouts/application.master" EnableViewState="false" EnableViewStateMac="false" %>
 
<asp:Content ID="Main" contentplaceholderid="PlaceHolderMain" runat="server">
        <asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
        <div  style="height:100%;">
            <asp:Silverlight ID="Xaml1" runat="server" Source="SilverlightApplication1.xap" MinimumVersion="2.0.31005.0" Width="100%" Height="100%" />
        </div>
</asp:Content>
 
2. Ensure SilverlightApplication1.xap is the name of your XAP file
3. Ensure application.master is the masterpage you wish to use
4. Save the page
5. Open the masterpage you have chosen in the step above and add the following right before HTML tag of it:
 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 
I recommend making a copy of your desired masterpage and using it before rolling out your changes to production.
 
Now you can test the page by loading it in the browser and it should load with Silverlight and regular SharePoint masterpage branding.
 
Hope this helps and you're on the way creating rich Silverlight content within your SharePoint portal.
If in doubt, contact me using my blog.
 
Yaroslav Pentsarskyy