Karine Bosch’s Blog

On SharePoint

Integrating Silverlight 3 in SharePoint 2007

Silverlight 3 has been released last week and it comes with really really great features. To learn more about them, I refer to posts like those of Tim HeuerScott Guthrie and Shawn Wildermuth. And a blog I personally like very much is the blog of Mike Snow.  Besides those listed here, there are a lot of other interesting resources you can find on the net.

All these new features sounds very exciting. Today I have been trying to integrate Silverlight 3 into SharePoint and it has not been easy at all.

Installation of Silverlight 3

 – Download Silverlight 3 runtime and install

– Download the Silverlight 3 SDK and install 

– If you are a developer, download Silverlight 3 Tools for Visual Studio and install. If you run  your environment in a Virtual PC (like most of the SharePoint developers do) you will encounter problems when you have no internet connection from within your Virtual PC. Until the beta version of Silverlight 3 you could use the trick to copy the content of the temporary folder while the exe was aching to install, and then install everything separately, but this time you will not find the Silverlight.3.x_Developer.exe file to enable Silverlight debugging in Visual Studio so you DO need an internet connection this time. (To enable internet access from within your VPC, I can recommend this post).

– If you need to develop more advanced user interfaces (and you will), you can download and install the Blend 3 trial.

If you installed all these bits, you are ready to go. Open Visual Studio 2008 and you can start developing your first Silverlight 3 applications. Exciting isn’t it? But if you are a SharePoint developer like me, there is the next hurdle to take: how can I display my first Silverlight 3 application in SharePoint? The SharePoint path has always been steep and has never been easy to take.

Configuration of the SharePoint server

Here comes the good news: in despite of previous versions, with Silverlight 3 you have to change NOTHING to the web.config of your SharePoint web application(s) on the server. You only have to configure the web.config for Framework 3.5 but this can easily lazily be done by Visual Studio 2008.

The last week I received a lot of questions on my blog: “Where is the System.Web.Silverlight.dll? I can’t find it.”. Well, I’m sorry, but it doesn’t exist anymore. You have to create the silverlight applications from within javascript, at least if you want to stay compatible.

Consequences for the SharePoint developer

You have two options:

– You are conservative and you install the Silverlight 3 SDK side by side with the Silverlight 2 SDK. In that case you can continue using the SilverlightControl, even with Silverlight 3 applications. 

– You are progressive and you remove the Silverlight 2 SDK and install the Silverlight 3 SDK. In that case you have to change your code.

The conservative way

Install the Silverlight 3 SDK side by side with the Silverlight  2 SDK. In that case the System.Web.Silverlight.dll is still available and can be deployed in the Global Assembly Cache, and you can continue using the Silverlight control, residing in that System.Web.Silverlight.dll. The control works with Silverlight 2 and Silverlight 3 applications.

PS. I haven’t checked HttpWebRequest to call SharePoint web services, so I don’t know if that’s boobytrapped too. 

The progressive way

Update 25/07/2009: because of encountering problems with execution of the script inside the web part code, I altered this post slightly.

This post explains how you can create a SharePoint web part that hosts a Silverlight 3 application. In a following post you will read how to host a Silverlight 3 application from within an application page. Both techniques are the basics that can be used in every SharePoint development scenario.

Create a javascript file with f.e. the name SpSilverlight.js. Include the following script to create a Silverlight application based on the silverlight.CreateObjectEx method:

function onSilverlightError(sender, args) {
         var appSource = "";
         if (sender != null && sender != 0) {
            appSource = sender.getHost().Source;
         }

         var errorType = args.ErrorType;
         var iErrorCode = args.ErrorCode;
         if (errorType == "ImageError" || errorType == "MediaError") {
             return;
         }
         var errMsg = "Unhandled Error in Silverlight Application " +  appSource + "\n" ;
         errMsg += "Code: "+ iErrorCode + "    \n";
         errMsg += "Category: " + errorType + "       \n";
         errMsg += "Message: " + args.ErrorMessage + "     \n";
         if (errorType == "ParserError") {
             errMsg += "File: " + args.xamlFile + "     \n";
             errMsg += "Line: " + args.lineNumber + "     \n";
             errMsg += "Position: " + args.charPosition + "     \n";
         }
         else if (errorType == "RuntimeError") {          
             if (args.lineNumber != 0) {
                 errMsg += "Line: " + args.lineNumber + "     \n";
                 errMsg += "Position: " +  args.charPosition + "     \n";
             }
             errMsg += "MethodName: " + args.methodName + "     \n";
         }
         throw new Error(errMsg);
}
function createSL(divid, swidth, sheight, source, initparameters)
{
    var pluginid = divid + "Plugin";
    var divElement = document.getElementById(divid);
    var altHTML = divElement.innerHTML;
    if (swidth == null)
       swidth='100%';
    if (sheight == null)
       sheight='750px';     
    Silverlight.createObjectEx(
    {
        source: source,
        parentElement: divElement,
        id: pluginid,
        properties:
        {
          // Plug-in properties
          width:swidth, 
          height:sheight,
          minRuntimeVersion:'2.0.31005.0'
        },
        events:
        {
           OnError: onSilverlightError // OnError property value -- event-handler function name.
           // OnLoad property value -- event-handler function name.
        },
        initParams: initparameters
    });
}

You can also create a Silverlight object using the silverlight.CreateObject method and include that in the SpSilverlight.js file.

In your web parts in the OnPreRender event you will have to register following javascript files:

  •  the Silverlight.js file (which comes with Silverlight and can be found in the C:\Program Files\Microsoft SDKs\Silverlight\v3.0\Tools directory)
  • the SpSilverlight.js file you just created.
protected override void OnPreRender(EventArgs e)
{
     base.OnPreRender(e);
     ClientScriptManager cs = Page.ClientScript;// Include the required javascript file.
     if (!cs.IsClientScriptIncludeRegistered("sl_javascript"))
         cs.RegisterClientScriptInclude(this.GetType(), "sl_javascript", "/_LAYOUTS/SL3/Silverlight.js");
     if (!cs.IsClientScriptIncludeRegistered("spsl_javascript"))
         cs.RegisterClientScriptInclude(this.GetType(), "spsl_javascript", "/_LAYOUTS/SL3/SpSilverlight.js");
}

Notice the path to the javascript files. I both deployed them to a sub folder of the 12\TEMPLATE\LAYOUTS folder. To avoid having to deploy these files for each web part and application page, you can best deploy them once to a single sub folder of the 12\TEMPLATE\LAYOUTS folder. You can also deploy them to the ClientBin folder under your SharePoint web application (in IIS).

Call the above javascript from within the CreateChildControls method:

protected override void CreateChildControls()
{
    string slstring = "<script type=\"text/javascript\">"
       + "createSL('silverlightHost', '300', '100', '/_LAYOUTS/SL3/HelloSilverlight3.xap', null);"
       + "</script>";
    silverlightHost = new LiteralControl(string.Format("<div id=\"silverlightHost\" style=\"width:100%; height:100%\"></div>{0}", slstring));           
    this.Controls.Add(silverlightHost);
}

If you need to pass data to the Silverlight control you need to set the initParams argument. This is a comma delimited string which has the following syntax:

key1=value1,key2=value2,...

Note that there are no spaces.

The CreateChildControls method would look as follows:

protected override void CreateChildControls()
{
    string xaplocation = "/_LAYOUTS/SL3/HelloSilverlight3.xap";
    string initparams = string.Format("url={0},list=Shared Documents", SPContext.Current.Web.Url);
    string slstring = string.Format("<script type=\"text/javascript\">"
       + "createSL('silverlightHost', '300', '100', '{0}', '{1}');"
       + "</script>", xaplocation, initparams);
    silverlightHost = new LiteralControl(string.Format("<div id=\"silverlightHost\" style=\"width:100%; height:100%\"></div>{0}", slstring));           
    this.Controls.Add(silverlightHost);
}

Voila! If you get this easy one to work, you are ready to go for all the great new stuff Silverlight 3 brings you!

Have fun!

July 17, 2009 Posted by | SharePoint 2007, Silverlight | 90 Comments