Sharepoint webpart for Silverlight 2.0

March 31, 2008

Before the last release of Silverlight 2.0 beta 1 embedding a silverlight application in a webpart was a somewhat tedious thing to do. Basically, you had to deploy your silverlight.dll and .xaml file within your Sharepoint solution as well as a bunch of javascript files that are called from your sharepoint webpart to create your silverlight content.

With the last release of Silverlight 2.0 all this steps are no longer necessary and we can easily host Silverlight Applications in Sharepoint Webparts just by including Silverlight controls and deploying .xap files with our solution.

For this example, I’ll create a generic webpart that will be able to load any .xap file accessible at our server. It will have a XapUrl property where we will be able to write a Url where the webpart will search for the xap file. Obviously this means that the .xap file must be deployed in our server, I usually do that by including the file in my Sharepoint Solution and deploying it in the _layouts folder of my server.

So following, is the code of my Silverlight Webpart


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint.WebPartPages;
using System.Web.UI.WebControls.WebParts;
using System.Runtime.InteropServices;
using System.Web.UI;

namespace Examples.SilverLight
{
    public class SilverLightWebpart : System.Web.UI.WebControls.WebParts.WebPart
    {
        private ScriptManager _scriptHandler;
        private System.Web.UI.SilverlightControls.Silverlight _silverlightControl;

        private string _xapUrl = string.Empty;
        [WebBrowsable(true), Personalizable(true)]
        public string XapUrl
        {
            get { return _xapUrl; }
            set { _xapUrl = value; }
        }

        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);

            _scriptHandler = ScriptManager.GetCurrent(this.Page);
            if (_scriptHandler == null)
            {
                _scriptHandler = new ScriptManager();
                _scriptHandler.ID = "ScriptManager1";
                this.Controls.Add(_scriptHandler);
            }

            if (!string.IsNullOrEmpty(_xapUrl))
            {
                _silverlightControl = new System.Web.UI.SilverlightControls.Silverlight();
                _silverlightControl.ID = "Xaml1";
                _silverlightControl.Source = _xapUrl;
                _silverlightControl.Version = "2.0";
                this.Controls.Add(_silverlightControl);
            }
        }

    }
}

Basically what we are doing is adding a ScriptManager and a Silverlight controls to our class. The only things we have to take care of are to ensure that there is only one instance of a ScriptManager in our current page (we do that with the call ScriptManager.GetCurrent(this.Page);) and that we must create the controls in the OnInit event of our webpart instead of the usual CreateChildControls event if not, we will get an exception from ScriptManager.RegisterScriptControl telling “Script controls may not be registered before PreRender

And that’s all, see how simple is now to host silverlight applications in our sharepoint server !


Deploy a XML file in your Sharepoint Solution to the Web Application Folder

February 27, 2008

This is a small trick I’ve been using these days in a Sharepoint Solution in order to add a xml file with some data which some webpart will read later on a Sharepoint site and make use of it. There are many ways to accomplish this each one with it’s benefits and drawbacks.

The first approach I thought of was to deploy the xml file in the _layouts folder and then query the data using a WebClient request from my webpart, the problem I found is that if anonymous access wasn’t enabled for the site, the request failed with a 401 Unauthorized exception because the ASP.Net credentials where the ones used by default to access the resource. One solution was to enable the impersonation at the web.config file of the application and then, the current user’s credentials would be used instead, but as I didn’t know where my solution would be deployed and didn’t have any control over the web.config file configuration, I rejected this approach.

Finally, I decided to deploy locally the xml file in the bin folder of the application and then accessing it with a simple StreamReader. The first problem was how to deploy the file ? Finally, I found the small trick I was talking about, you can deploy any file from a Sharepoint Solution in the bin folder of the web application just by doing the same as you do with a normal assembly .dll file, with the <Assembly> tag in the manifest.xml file:

<Assemblies><Assembly DeploymentTarget=WebApplication Location=MyData.xml /></Assemblies>

When the Solution is deployed, the xml file will be copied to all the bin folders of the selected web application. This raises the obvious drawback of this approach: There’s one xml file for each web application and there’s no easy way to globally manage them.
Since we will be accessing the xml file from our webpart, and assuming we haven’t set our trust level to Full (because we know it’s a bad thing to do!), we must grant our assembly the FileIOPermission  in order to be able to read the file. We can do this in the manifest.xml with the following section:

<CodeAccessSecurity><PolicyItem><PermissionSet class=NamedPermissionSet version=1 Description=Permission set for OurAssembly><IPermission class=System.Security.Permissions.FileIOPermission version=1 Unrestricted=true /> </PermissionSet><Assemblies><Assembly Name=OurAssembly /></ Assemblies></PolicyItem></CodeAccessSecurity>

Please note that I’ve set the unrestricted=true attribute just to keep it simple but you should set the Read attribute to the appropiate folder.Now, we can read the file from our webpart:

string loc = HttpContext.Current.Server.MapPath("/") + "bin\";
using (StreamReader reader = new StreamReader(loc + @"MyData.xml"))
{
    XDoc = XDocument.Load(reader, LoadOptions.None);
}

And that’s all, with this approach we can deploy all kinds of xml data and even .dll configuration files or any other localresource you might need. I hope it’s helpful and don’t forget to leave a comment if so !