Creating and opening documents in sharepoint using a silverlight control hosted in sharepoint site

             

Recently I was working on a SharePoint – Silverlight integration project. I have to confess that it was wonderful experiencing the power and extensibility that the combination of Silverlight and SharePoint provides. While on one hand SharePoint provides the ability to host Silverlight controls without the need for building a site from scratch, Silverlight on the other hand provides ability to create full-fledged application modules that can be based on data from SharePoint lists and hosted on the SharePoint using web parts. I won’t go into much detail of doing this, you can already find lots of articles on this on the internet (just bing “SharePoint Silverlight integration”).

              What I am going to describe is an interesting scenario that I had come across in my project. The requirement was to create a new document within a document library and open it and both the operations were to done on click of a button within a Silverlight control that was hosted within the SharePoint site. I will describe this scenario in detail here as it is one of the best illustrations of the power and possibilities in the world of SharePoint – Silverlight integration.

                Let me describe the scenario by dividing it into the two operations

1. Creation of a document within a document library on click of the button in the Silverlight control

The solution for this looks pretty obvious. Call a web service that will create the document within a document library. This can be similar to the code below.

public string CreateDocument(string website, string docLibrary, string contentType, string extension, string xmlData)

        {

            string strPath = string.Format(

                CultureInfo.CurrentCulture,

                "Document_{1}.{2}",

                DateTime.Now.ToString("dd-MMM-yyyy_HHmmss", CultureInfo.CurrentCulture),

                extension); // create a unique file name

            using (SPSite site = new SPSite(website))// open the site

            {

                using (SPWeb web = site.OpenWeb())

                {

                    web.AllowUnsafeUpdates = true;

                    SPList list = web.Lists[docLibrary]; // get reference to the document library

                    // this always uses root folder

                    SPFolder folder = web.Folders[docLibrary];

                    SPFileCollection fcol = folder.Files;

                    // find the template url and open

                    string template = list.ContentTypes[contentType].DocumentTemplateUrl;

                    SPFile spf = web.GetFile(template);

                    byte[] binFile = spf.OpenBinary();

                    // Url for file to be created

                    string destFile = fcol.Folder.Url + "/" + strPath;

                    // create the document and get SPFile/SPItem for

                    // new document

                    SPFile addedFile = fcol.Add(destFile, binFile, true);

                    SPItem newItem = addedFile.Item;

                    newItem["ContentType"] = contentType; // set the correct content type

                    newItem.Update();

                    using (Stream stream = addedFile.OpenBinaryStream())

                    {

                        WriteContents(stream, xmlData); // write the data to the document

                        addedFile.SaveBinary(stream);

                    }

                    addedFile.Update();

                }

            }

            return strPath;

        }

 

The above function creates a new document. The Write Contents writes the data from the xmlData which should contain data in a string xml. The implementation of this function will depend upon the type of the document to which we are writing. One more thing to note is that we are passing various information to this function which includes the SharePoint website, name of the document library, content type to be used in the document library, file extension of the newly created document and additional data in the form of a xml string. This data will be passed from the Silverlight application. Most of it can be set in the init params of the Silverlight application. The xml data can be any custom data we want to write to the document. This can be some input entered by the user in the Silverlight application. The function returns the name of the newly created file.

 

2. Opening the document on the browser

This is more challenging than the first scenario. Since we have to open the newly created document on the browser this has to be a client side operation. Sharepoint already does it when we click on “Edit” link on the list item in a document library.

                I used the Developer tool that comes with IE8 to see what piece of JavaScript this calls. And bingo. I found that this calls the “editDocumentWithProgID2('/sites/MyPortal/Documents/Document%20Naming%20standards.docx', '', 'SharePoint.OpenDocuments', '1', 'https://sharepoint/sites/MyPortal', '0')” JavaScript function. The important parameters to note here are the “/sites/MyPortal/Document%20Naming%20standards.docx” which specifies the relative path to the document and “https://sharepoint/sites/MyPortal” which specifies the site.

We have most the information except for the document name as static and can pass it to the Silverlight control through the init params. The name of the document is returned by the web service call to create a new document. Using this information we can call the JavaScript function from the Silverlight application as follows.

string[] strArr = new string[] { string.Format(CultureInfo.CurrentCulture, "/{0}/{1}", documentLibName, fileName), string.Empty, "SharePoint.OpenDocuments", "0", sitePath, "0" };

            //call the HtmlPage.Window.Invoke to invoke the javascript function from within the silverlight application

             HtmlPage.Window.Invoke(

                    "editDocumentWithProgID2",

                    strArr);

 

The above is just a simple illustration of the possibilities that the coming together of SharePoint and Silverlight open up. If we broaden our imagination further we can have Silverlight application take in input from the user and store them within the documents of different types. Using the powerful content management features of SharePoint we can ensure that the data is stored in the correct format within the documents. In addition Silverlight will provide us a rich interface to show the data in documents and SharePoint list in multiple views. Extensibility will be easy since we can create a new Silverlight application any time and just plug them in.