Back

TechnologyJul 17, 2009

Using SharePoint Web Services to Integrate SharePoint and Silverlight

Kevin King

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.

[code lang=”csharp”]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; }

}

[/code]

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.

[code lang=”csharp”]private void DataRequestCallback(IAsyncResult asyncResult)

{

try

{

string envelope =

@”

List Name

TRUE

“;

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 () {}

}

[/code]

Increase business process efficiency and collaboration with Microsoft SharePoint

Explore Our Microsoft Consulting Services  →

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.

[code lang=”csharp”]private void DataResponseCallback(IAsyncResult asyncResult)

{

HttpWebRequest request = (HttpWebRequest)asyncResult.AsyncState;

HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asyncResult);

Stream content = response.GetResponseStream();

if (request != null && response != null)

{

if (response.StatusCode == HttpStatusCode.OK)

{

using (StreamReader reader = new StreamReader(content))

{

responseString = reader.ReadToEnd();

reader.Close();

}

try

{

this.Dispatcher.BeginInvoke(ProcessResponseData);

}

catch () {}

}

}

}

[/code]

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.

[code lang=”csharp”]

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; }

}

}

[/code]

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:

[code lang=”csharp”]

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 { }

}

[/code]

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