This article is available also on SilverlightShow:
http://www.silverlightshow.net/items/Discover-Sharepoint-with-Silverlight-Part.aspx
Let me take a step back: in my first article on the winning pair (Sharepoint & Silverlight) I described how to set up a development environment and how to use three different ways to insert a Silverlight application in a Sharepoint site. In a second article I briefly highlighted how to interact with Sharepoint objects inside of a Silverlight application. Now it should be the time to go through the concepts in depth and try to better understand how we can steer Sharepoint by using the Silverlight Client Object Model. So I wondered why not creating an application that can navigate through the hierarchy of the objects exposed by Sharepoint and show its properties? And this was when the title of this article crossed my mind. Exploring, and in a certain way discovering Sharepoint using a sort of Silverlight navigator could be a good opportunity to learn something on the Sharepoint framework and, at the same time, to become familiar with the Silverlight Client Object Model.
This is exactly what we start to see in this article. In the next article we will see the application in action and it will be possible to download the source code.
This article may be useful to…
Silverlight developers who want to create Rich Internet Applications exploiting the potential offered by the Sharepoint 2010 platform. To achieve this they need to learn the main concepts behind that and know how to use the internal objects of Sharepoint.
Two words on Sharepoint 2010
There is something that I overlooked in my previous articles, indeed. I thought that from the point of view of a Silverlight developer, knowing in broad terms what is Sharepoint as well as the potential contribution of Silverlight are elements deserving a few words. SharePoint is essentially a business productivity platform built on a Web-based technology and you can interact with it using a web browser over an intranet, extranet, or Internet solution. Here is what sharepoint offers:
- An extended collaboration platform which includes enterprise content management (ECM), Web content management (WCM), business intelligence features and social capabilities (blogs, portals, tagging and so on)
- A complete interoperability platform with office applications and means to handle line of business data
- a rich development platform which ensures extensibility and customization.
Focusing on the last point, we can say that Sharepoint 2010 provides both a framework with tools and means to aid power users in building high level applications and a complex programming environment. You may work with page layouts and master pages to change the look and feel as well as the way in which the contents are structured. You can control the flow of information creating the so called workflows, namely business processes intended as sequences of steps to be performed in order to achieve a target. All these tasks can be performed using the high level tools and features offered by the environment. For developers who want more control, Sharepoint comes with a rich object model which has been totally server-based since the beginning. And for client application? Now in Sharepoint 2010 there is a client object model declined into three sub-types: for .NET managed applications, for ECMAScripts executing in the browser and for Silverlight applications. In this model most of the server objects are mapped to client objects with a similar name as in the non-exaustive table below:
Explaining in detail all these objects is beyond the scope of this article but it’s obvious that a Silverlight developer who wants to seriously build Silverlight apps that strongly interact with the framework should be aware of the Server Object model.
The Silverlight client object model behind the scenes
I don’t want to describe the basics of the SL COM (Silverlight Client Object Model) here, since there is the official tutorial for that. But there is something else I want to highlight, that is the mechanism behind. When I was doing my first experiments a particular method of the class Clientcontext caught my attention, that is “ExecutingWebRequest”. I wrote the piece of code below to investigate it further:
private void ContactSharepoint(string siteUrl)
{
myClContext = new ClientContext(siteUrl);
myClContext.ExecutingWebRequest += new EventHandler<WebRequestEventArgs>(myClContext_ExecutingWebRequest);
myClContext.Load(myClContext.Site);
myClContext.ExecuteQueryAsync(OnQuerySucceeded, OnQueryFailed);
}
void myClContext_ExecutingWebRequest(object sender, WebRequestEventArgs e)
{
WebRequest wb = e.WebRequest;
}
Here substantially I created a new ClientContext passing the Url of my Sharepoint site in order to know its properties. The logic is simple and straightforward: if you want to obtain information about properties and features regarding one or more properties of one or more client objects you have to use the ClientContext as main entry point, “load” it in your request (the “Site” object in the example above)and fire the query. I added an event handler for ExecutingWebRequest and I put a breakpoint inside the handler as in the image below:
In this way I discovered that the ExecuteQueryAsync(…) method performs a first HttpWebRequest to the Site Web service (http://<server-url>/_vti_bin/sites.asmx) and then a second HttpWebRequest to the Client Web Service (http://<server-url>/_vti_bin/client.svc) as in the image below:
The first request is performed only once when Sharepoint is contacted for the first time, all the subsequent requests are turned to the Client web service. So, what happens next? To understand it better I used the Fiddler tool in order to capture and analyze the web traffic.
The image below shows the details captured by Fiddler:
In the text area on the top right panel you can see the request invoking the method GetUpdatedFormDigest of the Site web service, and in the text area below the response. This method returns a security validation value (a FormDigest value). What is its purpose? This link http://msdn.microsoft.com/en-us/library/ms472879.aspx clarifies it all. It claims that a web application cannot “modify the contents of the database unless you include security validation on the page making the request.” And furthermore “When the user requests a page, the server returns the page with security validation inserted. When the user then submits the form, the server verifies that the security validation has not changed.” Practically this first request is made to obtain a token with an expiration time which is used by Sharepoint to verify that the subsequent requests to the Client Web Service are genuine. Let’s analyze the second request now. The traffic captured is:
In the response we see clearly that we requested information about an object of type SP.Site and all its properties. We also notice another thing: the request is formatted in XML and the response, instead, is in JSON format. Why this? Most probably because the “client.svc” web service is used also by the ECMAScript Object Model to allow javascript developers to use a similar object -oriented pattern. What is important is that for a “client developer” (i.e. Silverlight, javascript or even .managed apps developer) the mechanism is transparent:
1) the Client Object Model translates the request in xml and passes it to the client.svc
2) The client.svc interrogates the content database and returns the response in a JSON format
3) the Client Object Model finally maps the JSON objects to the relevant client objects
now , what if we want to know more about the object Web and, in particular, its title as in the code below?
private void ContactSharepoint(string siteUrl)
{
myClContext = new ClientContext(siteUrl);
myClContext.ExecutingWebRequest += new EventHandler<WebRequestEventArgs>(myClContext_ExecutingWebRequest);
myClContext.Load(myClContext.Web, w => w.Title);
myClContext.ExecuteQueryAsync(OnQuerySucceeded, OnQueryFailed);
}
void myClContext_ExecutingWebRequest(object sender, WebRequestEventArgs e)
{
WebRequest wb = e.WebRequest;
Once again the web traffic captured reveals some interesting things:
The request passes the Digest value previously obtained to ensure that it is valid and the list of actions required with the query linked. In the response we are informed that the value of the title property of the object SP.Web is “Team Site”. This introduces another interesting argument, that is how the parameters are passed to the Load(…) and LoadQuery(…) methods of the ClientContext object and this is the object of the next paragraph.
Asking information to Sharepoint: Load(…) and LoadQuery(…)
The Load(…) and LoadQuery(…) methods of the ClientContext obect are defined as follows:
public void Load<T>(T clientObject, params Expression<Func<T, object>>[] retrievals) where T : ClientObject;
public IEnumerable<T> LoadQuery<T>(ClientObjectCollection<T> clientObjects) where T : ClientObject;
public IEnumerable<T> LoadQuery<T>(IQueryable<T> clientObjects) where T : ClientObject;
We have already seen some simple examples of using the Load(…) method in this and in my previous article.
At this point it should be clear that when using these methods, the underlying Client Object Model engine prepares a request to Sharepoint in order to know the values of the objects passed as an argument. The request is fired only when we call the ExecuteQueryAsync(…) or the ExecuteQuery() methods of the CleintContext and you can inspect and use the Client objects requested only after this call.
I want to focus on the second argument now. It is (in case of Load(…) method) an array of Lambda Expression with reference to objects of type “ClientObject”. The ClientObject class is the base class for all the client objects listed in the “server-client objects correspondence table” above. So what? Let’s think of an application where starting from a root node you want to know information on all the child nodes as in a treeview – logic and let’s imagine that each node represents a ClientObject of Sharepoint with its properties (petals). In this way you could start from the root node, i.e. the Site object and get all the child nodes with subsequent requests to Sharepoint. Virtually you could navigate each branch of the tree preparing each time the correct expression to pass to the Load(…) method. The question is: how to generalize this via code? One way is to use reflection and in the second part of this article we will see how.
ExecuteQueryAsync(…) VS ExecuteQuery(…)
In my previous article I told you that “ […] since Silverlight follows an asynchronous model, you can only make asynchronous queries to the Sharepoint Server from the UI thread. You can perform synchronous queries only in a thread that does not interact with the UI thread […] “.
On the basis of this statement it should be possible to make synchronous queries using ExecuteQuery() also in Silverlight with some caution. In my application I put the call in a secondary thread and I verified that it works. The implementation is very simple, in the code below I instantiated a Thread object passing a lambda expression as argument and then I started the thread. In this way the ExecuteInThread(…) method is executed in a secondary thread and can be used to call ExecuteQuery(…).
public void ExecuteAction()
{
Thread t = new Thread(() => ExecuteInThread(new
{
ClientContext = m_clientContext,
ClientObject = m_clientObject,
LeftTreeItem = m_currentItem
}
));
t.Start();
In conclusion using either ExecuteQueryAsync(…) or ExecuteQuery(…) is your choice depending on the scenario.
The Silverlight Client Object Model and OOB application limitations
During my experiments I discovered one inconvenience. If you want to use the SL Client Object Model in a SL OOB application, keep in mind that there are strong limitations. The fact is that inside an OOB (Out Of Browser) application from the point of view of Sharepoint you are impersonating an anonymous user and you can view and do just what the anonymous user can view and do. This depends on the fact that the SL Client Object Model interacts with Sharepoint using the default credentials as you can see in the image below where I put a breakpoint on the ExecutingWebRequest() event handler:
With the managed client model (that is the model used for managed applications like command-line apps, winforms and WPF applications) you can change the authentication mode on the ClientContext object using the AuthenticationMode property. For instance, you can set this property on forms authentication which gives you the possibility to supply username and password (obviously you have to enable forms authentication in your Sharepoint site in this case). Unfortunately in the Silverlight client object model this property is not implemented and this means that if you want to interact with Sharepoint using an OOB application you have to take care of all the details needed to perform the authentication.
Summary
In this article we began exploring Sharepoint using Silverlight. We have looked more closely at the Silverlight Object Model and we have discovered how it works behind the scenes. We have also given a look to server and client object hierarchy of Sharepoint and highlighted the limitations in terms of interaction between the SL client object model and SL OOB applications. In the second part of the article we will see a SL application able to navigate the hierarchy of client objects and to show their properties.