Posts Tagged ‘Silverlight’

Passing Parameters to a Silverlight Webpart in SharePoint

Friday, July 17th, 2009

In this blog, I will outline the steps necessary to pass initialization parameters to a Silverlight webpart within SharePoint.  Due to the client-side processing nature of Silverlight applications, it is not easy to get server-side information for use in your Silverlight application during runtime.  Fortunately, leveraging the SilverlightApp.InitParameters property makes it quite straight-forward to pass information on startup..

Steps:

  1. Define the SilverlightApp1.InitParameters in the webpart’s CreateChildControls method
  2. Extract these parameters in the Application_Startup method in App.xaml.cs and pass it to the page
  3. Extract the information from the Page parameters

Define the SilverlightApp1.InitParameters in the webpart’s CreateChildControls method

In the CreateChildControls method in the webpart.cs class, we want to create our Silverlight application control and add it to the page.  The Silverlight application object has a property called InitParameters.  This is a string that accepts parameters in this format:  “parameter=value”.  Each parameter/value pair is seperated by a comma, like this:  “parameter1=value1, parameter2=value2″.

Here is a code snippet of the entire Silverlight instantiation, manipulation, and addition:

protected override void CreateChildControls()
{
base.CreateChildControls();

silverlightControl = new System.Web.UI.SilverlightControls.Silverlight();
silverlightControl.ID = "Silverlight App";

silverlightControl.MinimumVersion = "2.0.31005.0";
string parameters = "SiteUrl=" + SPContext.Current.Web.Url.ToString() + ", " +  "Date=" + DateTime.Now.ToString();
silverlightControl.InitParameters = parameters;

silverlightControl.Source = SPContext.Current.Site.Url + "/XAPS/SilverlightApp.xap";

this.Controls.Add(silverlightControl);
}

As you can see, two parameters will be passed to the Silverlight application at startup.  The first is the current site url that the webpart resides in.  This is useful when using SharePoint web services that require the url of the SharePoint site.  It is key that we use the InitParameters property to pass this information, as the Silverlight application runs on the client-side, so accessing the site url within the Silverlight application itself is not possible.  The second is the Date/Time when the application starts up.

Extract these parameters in the AppStartup method in App.xaml.cs

In the Silverlight application in App.xaml.cs, there is a method called Application_Startup with event arguments StartupEventArgs.  These event args have a property called InitParams.  This is the property that is passed to the page when it is instantiated and set as the RootVisual.

private void Application_Startup(object sender, StartupEventArgs e)
{
RootVisual = new Page(e.InitParams);
}

Extract the information from the Page parameters

In Page.xaml.cs, the original initialization parameters are passed as page instantiation parameters as shown above.  Within Page.xaml.cs, the Page creation method takes the e.InitParams object, which is of type IDictionary<String, String>.  Therefore, we extract this information like so.

public Page(IDictionary initParams)
{
string siteUrl = initParams["SiteUrl"];

string dateTimeNow = initParams["Date"];

InitializeComponent();

}

We now have two string values, the current SharePoint site url and the date/time when the application is started that can be used by the Silverlight application.

Using SharePoint Web Services to Integrate SharePoint and Silverlight

Friday, July 17th, 2009

When integrating Silverlight with a SharePoint site, it becomes apparent very early on that using data that lives in SharePoint in your Silverlight application will be difficult.  The reason being that Silverlight applications run on the client-side.  Therefore, a developer wanting to extract list data or use files hosted in SharePoint cannot simply use the SharePoint object model directly to accomplish this.  Fortunately, SharePoint provides out-of-the-box web services that can be leveraged to get this data.

The first step to using the SharePoint web services is creating the HttpWebRequest object and beginning the call.  In this example, we will be using the Lists.asmx web service located at http://sharepointsite.com/_vti_bin/Lists.asmx.  We will define the Method, ContentType, and Headers of the web service.  Finally, we will call the BeginGetRequestStream method to begin the call.

private void GetDataEntryPoint()
{
try
{
string siteUrl = "http://sharepointsite.com"

HttpWebRequest request = (HttpWebRequest)WebRequest.Create(new Uri(siteUrl + "/_vti_bin/Lists.asmx", UriKind.Absolute));

request.Method = "Post";
request.ContentType = "application/soap+xml; charset=utf-8";
request.Headers["ClientType"] = "Silverlight";
request.BeginGetRequestStream(new AsyncCallback(DataRequestCallback), request);
}
catch (Exception ex) { string error = ex.Message; }
}

In the above snippet, you will see the DataRequestCallback delegate.  This is the method we will work with next.  It will be called whenever we receive the asynchronous callback from SharePoint telling us that we have a connection and it is ready for more information.  In this method, we will do a few things.  We will define the SOAP envelope that contains information that tells SharePoint what data we are looking for.  I’ve included a query option as an example that tells SharePoint to send us any attachments as well for each item.  In the envelope below, the 3 items that need to be changed are the list name, the field to sort with, and the fields we want to be returned.  The next part of this method reacreates the HttpWebRequest object using the asynchronous result.  We also define the encoding type we will want to use.  Next, we see the Stream object body that will temporarily hold the data.  Then we will use our configured encoding to write the response to an array of bytes.  This object will be used by the next callback method to collect the data.  We then define our method delegate, DataResponseCallback, to be called when the data is returned by SharePoint in an asynchronous callback.

private void DataRequestCallback(IAsyncResult asyncResult)
{
try
{
string envelope =
@"&lt;?xml version=""1.0"" encoding=""utf-8""?&gt;
&lt;soap12:Envelope
xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance""
xmlns:xsd=""http://www.w3.org/2001/XMLSchema""
xmlns:soap12=""http://www.w3.org/2003/05/soap-envelope""&gt;
&lt;soap12:Body&gt;
&lt;GetListItems xmlns=""http://schemas.microsoft.com/sharepoint/soap/""&gt;
&lt;listName&gt;List Name&lt;/listName&gt;
&lt;query&gt;
&lt;Query xmlns=""""&gt;
&lt;OrderBy&gt;
&lt;FieldRef Name=""Title"" /&gt;
&lt;/OrderBy&gt;
&lt;/Query&gt;
&lt;/query&gt;
&lt;viewFields&gt;
&lt;ViewFields xmlns=""""&gt;
&lt;FieldRef Name='Title' /&gt;
&lt;FieldRef Name='Age' /&gt;
&lt;/ViewFields&gt;
&lt;/viewFields&gt;
&lt;queryOptions&gt;
&lt;QueryOptions xmlns=""""&gt;
&lt;IncludeAttachmentUrls&gt;TRUE&lt;/IncludeAttachmentUrls&gt;
&lt;/QueryOptions&gt;
&lt;/queryOptions&gt;
&lt;/GetListItems&gt;
&lt;/soap12:Body&gt;
&lt;/soap12:Envelope&gt;";

UTF8Encoding encoding = new UTF8Encoding();
HttpWebRequest request = (HttpWebRequest)asyncResult.AsyncState;

Stream body = request.EndGetRequestStream(asyncResult);

byte[] formBytes = encoding.GetBytes(envelope);

body.Write(formBytes, 0, formBytes.Length);
body.Close();

request.BeginGetResponse(new AsyncCallback(DataResponseCallback), request);
}
catch () {}
}

In the next method, we will receive the asynchronous result from SharePoint containing the data we want.  Unforunately, it is not in the correct format for how we want to use it.   We will save this returned data into a string called responseString (this will be defined outside our method so that it can be accessed by multiple methods).  We will then use the Dispatcher to invoke our processing method, ProcessResponseData, that will parse the raw data and load it into a custom object.

private void DataResponseCallback(IAsyncResult asyncResult)
{
HttpWebRequest request = (HttpWebRequest)asyncResult.AsyncState;
HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asyncResult);
Stream content = response.GetResponseStream();

if (request != null &amp;&amp; response != null)
{
if (response.StatusCode == HttpStatusCode.OK)
{
using (StreamReader reader = new StreamReader(content))
{
responseString = reader.ReadToEnd();
reader.Close();
}

try
{

this.Dispatcher.BeginInvoke(ProcessResponseData);

}

catch () {}
}
}
}

Before we jump into the parsing of the raw data SharePoint gave us, let’s define an object called Person that will have properties of Title, Age, and Image.


public class Person
{
private string _image;
public string Image
{
get { return _image; }
set { _image = value; }

}
private string _name;
public string Name
{
get { return _name; }
set { _name = value; }
}

private string _age;
public string Age
{
get { return _age; }
set { _age= value; }
}
}

Now that we have our custom Person object, we can instantiate one and assign it values using our SharePoint web services data.  For each attribute we are reading, we find it by passing “ows_FieldName” to the MoveToAttribute method of the XmlReader object.  For the URL of the attachment, we need to use some simple Regex.Replace to extract the actual URL.  This technique can be used for any attachments.  Here is a code snippet:


private void ProcessResponseBusinessUnitListItems()
{
try
{
using (XmlReader reader = XmlReader.Create(new StringReader(responseString)))
{
while (reader.Read())
{
if (reader.IsStartElement("row", "#RowsetSchema"))
{

reader.MoveToAttribute("ows_Title");
string titleString = reader.Value;

reader.MoveToAttribute("ows_Name");
string nameString = reader.Value;

reader.MoveToAttribute("ows_Age");
string ageString = reader.Value;

reader.MoveToAttribute("ows_Attachments");
string attachmentUrl1 = reader.Value;
string attachmentUrl2 = Regex.Replace(reader.Value, "#", "");
string attachmentUrl = Regex.Replace(attachmentUrl2, ";", "");

Person person = new Person();
person.Name = personName;
person.Age = personAge;
person.Image = attachmentUrl;

reader.MoveToElement(); //Moves the reader back to the element node.

}
}
}
}
catch { }
}

That’s it, now we have our custom object loaded with data from a SharePoint list.