Working with Client Object Model in Microsoft Sharepoint

Exclusive offer: get 50% off this eBook here
Microsoft SharePoint 2010 Development with Visual Studio 2010 Expert Cookbook

Microsoft SharePoint 2010 Development with Visual Studio 2010 Expert Cookbook — Save 50%

Develop, debug, and deploy business solutions for Microsoft SharePoint applications using Microsoft Visual Studio 2010 with this book and ebook.

$29.99    $15.00
by Balaji Kithiganahalli | October 2011 | Enterprise Articles Microsoft

Microsoft SharePoint 2010 is the best-in-class platform for content management and collaboration. With Visual Studio, developers have an end-to-end business solutions development IDE. To leverage this powerful combination of tools it is necessary to understand the different building blocks of SharePoint.

In this article by Balaji Kithiganahalli, author of Microsoft SharePoint 2010 Development with Visual Studio 2010 Expert Cookbook, we will cover:

  • Creating a list using a Client Object Model
  • Handling exceptions
  • Calling Object Model asynchronously

 

(For more resources on Microsoft Sharepoint, see here.)

Introduction

Since out-of-the-box web services does not provide the full functionality that the server model exposes, developers always end up creating custom web services for use with client applications. But there are situations where deploying custom web services may not be feasible. For example, if your company is hosting SharePoint solutions in a cloud environment where access to the root folder is not permitted. In such cases, developing client applications with new Client Object Model (OM) will become a very attractive proposition.

SharePoint exposes three OMs which are as follows:

  • Managed
  • Silverlight
  • JavaScript (ECMAScript)

Each of these OMs provide object interface to functionality exposed in Microsoft. SharePoint namespace. While none of the object models expose the full functionality that the server-side object exposes, the understanding of server Object Models will easily translate for a developer to develop applications using an OM. A managed OM is used to develop custom .NET managed applications (service, WPF, or console applications). You can also use the OM for ASP.NET applications that are not running in the SharePoint context as well. A Silverlight OM is used by Silverlight client applications. A JavaScript OM is only available to applications that are hosted inside the SharePoint applications like web part pages or application pages.

Even though each of the OMs provide different programming interfaces to build applications, behind the scenes, they all call a service called Client.svc to talk to SharePoint. This Client.svc file resides in the ISAPI folder. The service calls are wrapped around with an Object Model that developers can use to make calls to SharePoint server. This way, developers make calls to an OM and the calls are all batched together in XML format to send it to the server. The response is always received in JSON format which is then parsed and associated with the right objects. The basic architectural representation of the client interaction with the SharePoint server is as shown in the following image:

The three Object Models come in separate assemblies. The following table provides the locations and names of the assemblies:

Object OM Location Names
Managed ISAPI folder Microsoft.SharePoint.Client.dll
Microsoft.SharePoint.Client.Runtime.dll
Silverlight Layouts\ClientBin Microsoft.SharePoint.Client. Silverlight.dll
Microsoft.SharePoint.Client.
Silverlight.Runtime.dll
JavaScript Layouts SP.js

The Client Object Model can be downloaded as a redistributable package from the Microsoft download center at:http://www.microsoft.com/downloads/en/details.aspx?FamilyID=b4579045-b183-4ed4-bf61-dc2f0deabe47

OM functionality focuses on objects at the site collection and below. The main reason being that it will be used to enhance the end-user interaction. Hence the OM is a smaller subset of what is available through the server Object Model. In all three Object Models, main object names are kept the same, and hence the knowledge from one OM is easily portable to another. As indicated earlier, knowledge of server Object Models easily transfer development using client OM The following table shows some of the major objects in the OM and their equivalent names in the server OM:

Client OM Server OM
ClientContext SPContext
Site SPSite
Web SPWeb
List SPList
ListItem SPListItem
Field SPField

Creating a list using a Managed OM

In this recipe, we will learn how to create a list using a Managed Object Model. We will also add a new column to the list and insert about 10 rows of data to the list. For this recipe, we will create a console application that makes use of a generic list template.

Getting ready

You can copy the DLLs mentioned earlier to your development machine. Your development machine need not have the SharePoint server installed. But you should be able to access one with proper permission. You also need Visual Studio 2010 IDE installed on the development machine.

How to do it…

In order to create a list using a Managed OM, adhere to the following steps:

  1. Launch your Visual Studio 2010 IDE as an administrator (right-click the shortcut and select Run as administrator).
  2. Select File | New | Project . The new project wizard dialog box will be displayed (make sure to select .NET Framework 3.5 in the top drop-down box).
  3. Select Windows Console application under the Visual C# | Windows | Console Application node from Installed Templates section on the left-hand side.
  4. Name the project OMClientApplication and provide a directory location where you want to save the project and click on OK to create the console application template.
  5. To add a references to Microsoft.SharePoint.Client.dll and Microsoft.SharePoint.Client.Runtime.dll, go to the menu Project | Add Reference and navigate to the location where you copied the DLLs and select them as shown In the following screenshot:

  6. Now add the code necessary to create a list. A description field will also be added to our list. Your code should look like the following (make sure to change the URL passed to the ClientContext constructor to your environment):

    using Microsoft.SharePoint.Client;
    namespace OMClientApplication
    {
    class Program
    {
    static void Main(string[] args)
    {
    using (ClientContext clientCtx = new
    ClientContext("http://intsp1"))
    {

    Web site = clientCtx.Web;
    // Create a list.
    ListCreationInformation listCreationInfo = new
    ListCreationInformation();
    listCreationInfo.Title = "OM Client Application
    List";
    listCreationInfo.TemplateType =
    (int)ListTemplateType.GenericList;
    listCreationInfo.QuickLaunchOption =
    QuickLaunchOptions.On;
    List list = site.Lists.Add(listCreationInfo);
    string DescriptionFieldSchema = "<Field
    Type='Note' DisplayName='Item Description' Name='Description'
    Required='True' MaxLength='500' NumLines='10' />";
    list.Fields.AddFieldAsXml(DescriptionFieldSchema,
    true, AddFieldOptions.AddToDefaultContentType);
    // Insert 10 rows of data - Concat loop Id with "Item Number"
    string.
    for (int i = 1; i < 11; ++i)
    {
    ListItemCreationInformation
    listItemCreationInfo = new ListItemCreationInformation();
    ListItem li = list.AddItem(listItemCreationInf
    o);
    li["Title"] = string.Format("Item number
    {0}",i);
    li["Item_x0020_Description"] = string.
    Format("Item number {0} from client Object Model", i);
    li.Update();
    }
    clientCtx.ExecuteQuery();
    Console.WriteLine("List creation completed");
    Console.Read();
    }
    }
    }
    }

  7. Build and execute the solution by pressing F5 or from the menu Debug | Start Debugging . This should bring up the command window with a message indicating that the List creation completed as shown in the following screenshot. Press Enter and close the command window.

  8. Navigate to your site to verify that the list has been created. The following screenshot shows the list with the new field and ten items inserted:

    (Move the mouse over the image to enlarge.)

How it works...

The first line of the code in the Main method is to create an instance of ClientContext class. The ClientContext instance provides information about the SharePoint server context in which we will be working. This is also the proxy for the server we will be working with. We passed the URL information to the context to get the entry point to that location. When you have access to the context instance, you can browse the site, web, and list objects of that location. You can access all the properties like Name , Title , Description , and so on.

The ClientContext class implements the IDisposable interface, and hence you need to use the using statement. Without that you have to explicitly dispose the object. If you do not do so, your application will have memory leaks. For more information on disposing objects refer to MSDN at:http://msdn.microsoft.com/en-us/library/ee557362.aspx

From the context we were able to obtain access to our site object on which we wanted to create the list. We provided list properties for our new list through the ListCreationInformation instance.

Through the instance of ListCreationInformation, we set the values to list properties like name, the templates we want to use, whether the list should be shown in the quick launch bar or not, and so on.

We added a new field to the field collection of the list by providing the field schema. Each of the ListItems are created by providing ListItemCreationInformation.

The ListItemCreationInformation is similar to ListCreationInformation where you would provide information regarding the list item like whether it belongs to a document library or not, and so on. For more information on ListCreationInformation and ListItemCreationInformation members refer to MSDN at:http://msdn.microsoft.com/en-us/library/ee536774.aspx.

All of this information is structured as an XML and batched together to send it to the server. In our case, we created a list and added a new field and about ten list items. Each of these would have an equivalent server-side call, and hence, all these multiple calls were batched together to send it to the server. The request is only sent to the server when we issue an ExecuteQuery or ExecuteQueryAsync method in the client context.

The ExecuteQuery method creates an XML request and passes that to Client.svc. The application waits until the batch process on the server is completed and then returns back with the JSON response. Client.svc makes the server Object Model call to execute our request.

There's more...

By default, ClientContext instance uses windows authentication. It makes use of the windows identity of the person executing the application. Hence, the person running the application should have proper authorization on the site to execute the commands. Exceptions will be thrown if proper permissions are not available for the user executing the application. We will learn about handling exceptions in the next recipe.

It also supports Anonymous and FBA (ASP.Net form based authentication) authentication. The following is the code for passing FBA credentials if your site supports it:

using (ClientContext clientCtx = new ClientContext("http://intsp1"))
{
clientCtx.AuthenticationMode = ClientAuthenticationMode.
FormsAuthentication;
FormsAuthenticationLoginInfo fba = new FormsAuthenticationLoginInfo("u
sername", "password");
clientCtx.FormsAuthenticationLoginInfo = fba;
//Business Logic
}

Impersonation

In order to impersonate you can pass in credential information to the ClientContext as shown in the following code:

clientCtx.Credentials = new NetworkCredential("username",
"password", "domainname");

Passing credential information this way is supported only in Managed OM.

 

Microsoft SharePoint 2010 Development with Visual Studio 2010 Expert Cookbook Develop, debug, and deploy business solutions for Microsoft SharePoint applications using Microsoft Visual Studio 2010 with this book and ebook.
Published: September 2011
eBook Price: $29.99
Book Price: $49.99
See more
Select your format and quantity:

 

(For more resources on Microsoft Sharepoint, see here.)

Handling exceptions

In the previous recipe, we created a list with a custom field and some data. If all of these calls are batched together and sent to the server, how do we handle exceptions? In this recipe, we will create a console application to see how to handle exceptions.

Getting ready

You should complete the previous recipe successfully to follow this one.

How to do it...

In order to handle exceptions, adhere to the following steps:

  1. Launch your Visual Studio 2010 IDE as an administrator (right-click the shortcut and select Run as administrator ).
  2. Select File | New | Project . The new project wizard dialog box will be displayed (make sure to select .NET Framework 3.5 in the top drop-down box).
  3. Select Windows console application under the Visual C# | Windows | Console Application node from Installed Templates section on the left-hand side.
  4. Name the project HandleErrors and provide a directory location where you want to save the project and click on OK to create the console application template.
  5. Add references to Microsoft.SharePoint.Client.dll and Microsoft. SharePoint.Client.Runtime.dll.
  6. Add the code to retrieve a non-existent list called Standard Method list and try to add an item to this list. Your code in Program.cs should look like the following block:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Microsoft.SharePoint.Client;
    namespace HandleError
    {
        class Program
        {
            static void Main(string[] args)
            {
                CreateListAndAddItemStandard("http://intsp1,
    "Standard Method List", "Add Item By Standard Method");
            }
            public static void CreateListAndAddItemStandard(string
    siteUrl, string listName, string itemTitle)
            {
                using (ClientContext clientCtx = new
    ClientContext(siteUrl))
                {
                    Web site = clientCtx.Web;
                    try
    {
                        //Get the list
                        List list = site.Lists.GetByTitle(listName);
                        ListItemCreationInformation
    listItemCreationInfo = new ListItemCreationInformation();
                     ListItem li = list.AddItem(listItemCreationInfo);
                        li["Title"] = itemTitle;
                        li.Update();
                        list.Update();
                        clientCtx.ExecuteQuery();
                    }
                    catch (ServerException)
                    {
                      // Create a list.
                      ListCreationInformation listCreationInfo = new
    ListCreationInformation();
                        listCreationInfo.Title = listName;
                        listCreationInfo.TemplateType =
    (int)ListTemplateType.GenericList;
                        listCreationInfo.QuickLaunchOption =
    QuickLaunchOptions.On;
                        List list = site.Lists.Add(listCreationInfo);
                        ListItemCreationInformation
    listItemCreationInfo = new ListItemCreationInformation();
                     ListItem li = list.AddItem(listItemCreationInfo);
                        li["Title"] = itemTitle;
                        li.Update();
                        list.Update();
                        clientCtx.ExecuteQuery();
                        Console.WriteLine("List Created");
                        Console.Read();
                    }
                }
            }

  7. The list will be created from the catch block and an item will be added as shown in the following screenshot:

How it works...

In the previous recipe, we indicated to you that the batch processing would not send the request to the server until you issue an ExecuteQuery call. In the preceding program too, the batch request is issued as a ExecuteQuery method. Client.svc uses the server Object Model to get the list and fails, and hence throws the error.

In the catch block, we are creating the list and adding the item. We are also issuing anothe ExecuteQuery command to send the batch request to perform the required actions.

This is typical .NET programming, where we make decisions based on exceptions. If the exception caught was due to the list not found, then we will create a new one and continue with our business logic.

The flaw in this case is calling ExecuteQuery method twice. This is inefficient coding. Round trips to server should be reduced as much as possible for better user interactions.

Fortunately, an OM provides a way to batch our exception scopes without multiple trips to the server. The same code that we ran in the recipe can be rewritten with exception scope as follows:

public static void CreateListAndAddItem(string siteUrl, string
listName, string itemTitle)
        {
            using (var clientContext = new ClientContext(siteUrl))
            {
                var ehScope = new ExceptionHandlingScope
                (clientContext);
                List list;
                using (ehScope.StartScope())
                {
                    using (ehScope.StartTry())
                    {
                        list = clientContext.Web.Lists.
GetByTitle(listName);
                        clientContext.Load(list);
                    }
                    using (ehScope.StartCatch())
                    {
                        var listCreationInformation = new 
                        ListCreationInformation();
                        listCreationInformation.Title = listName;
                        listCreationInformation.TemplateType = 
                        (int)ListTemplateType.GenericList;
                      
                        list = clientContext.Web.Lists.Add
                        (listCreationInformation);
                    }
                    using (ehScope.StartFinally())
                    {
                        ListItemCreationInformation
listItemCreationInfo = new ListItemCreationInformation();
                   ListItem li = list.AddItem(listItemCreationInfo);
                        li["Title"] = itemTitle;
                        li.Update();
                        list.Update();
                    
                    }
  }
                clientContext.ExecuteQuery();
            }

The exception block in OM programming starts with an instance of ExceptionHandlingScope. This scope defines the scope of the exception that it needs to tackle in case the server raises an exception.

ExceptionHandlingScope always starts with the StartScope() method which should contain StartTry() and StartCatch() methods respectively in that order. StartFinally() in the end if provided, will always execute.

Apart from these methods, ExceptionHandlingScope also provides useful properties like ErrorMessage, ServerStackTrace, ServerErrorValue, ServerErrorCode, and HasException for you to understand what exactly went wrong on the server. The following is the Fiddler output of the JSON response for our recipe. If you look closely, it does indicate HasException, ErrorMessage, ServerErrorCode, and ServerErrorValue.

For more information on ExceptionHandlingScope refer to MSDN at:http://msdn.microsoft.com/en-us/library/ee541237.aspx.

There's more...

By default, to improve performance and reduce the network traffic, certain properties are not retrieved. In case you try to access such a property you will get a PropertyOrFieldNotInitializedException exception. The properties that are retrieved are based on the object type that is used in the Load method. For example, on ListItem, properties like DisplayName, RoleAssignments, EffectiveBasePermissions, and HasUniqueRoleAssignments are not retrieved by default. Use the IsPropertyAvailable method to check if that property is retrieved or not. You can also specify the properties that you want to retrieve in the client context Load method as follows:

clientContext.Load(listItems, li => li.Include(i =>
i["WorkPhone"], i => i["EMail"]));
clientContext.Load(web, w => w.Id, w => w.Title,w => w.Created);

Calling Object Model asynchronously

The previous recipes all included calling object model synchronously. There are times when the execution is a long running process, it makes sense to call the method asynchronously and provide a visual cue to the users about the progress of the execution. In this recipe, we will create a console application that calls the Object Model asynchronously.

Getting ready

You should have successfully completed the previous two recipes to follow this.

How to do it...

In order to call the Object Model asynchronously, adhere to the following steps:

  1. Launch your Visual Studio 2010 IDE as an administrator (right-click the shortcut and select Run as administrator).
  2. Select File | New | Project. The new project wizard dialog box will be displayed (make sure to select .NET Framework 3.5 in the top drop-down box).
  3. Select Windows console application under the Visual C# | Windows | Console Application node from the Installed Templates section on the left-hand side.
  4. Name the project OMClientAsynch and provide a directory location where you want to save the project and click on OK to create the console application template.
  5. Add references to Microsoft.SharePoint.Client.dll and Microsoft. SharePoint.Client.Runtime.dll.
  6. Add the code to change the site title and retrieve the names of all the lists in the site. Your code in Program.cs should look like the following:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Microsoft.SharePoint.Client;
    namespace OMClientAsynch
    {
    class Program
    {
    static void Main(string[] args)
    {
    OMClientAsynch asynch = new OMClientAsynch();
    asynch.RunAsynchronously();
    }
    }
    class OMClientAsynch
    {
    delegate void ExecuteAsynchQuery();
    Microsoft.SharePoint.Client.Web site;
    Microsoft.SharePoint.Client.ClientContext context;
    public void RunAsynchronously()
    {
    context = new ClientContext("http://intsp1");
    site = context.Web;
    ListCollection listcol = context.Web.Lists;
    context.Load(site, s => s.Title);
    context.Load(listcol);
    ExecuteAsynchQuery executeQueryAsync = new ExecuteAsyn
    chQuery(context.ExecuteQuery);
    executeQueryAsync.BeginInvoke(AsynchCallback, null);
    Console.WriteLine("This will be the first line that
    will be displayed in the console");
    Console.WriteLine("Asynchronous method is already
    invoked. But the results will show up now");
    Console.Read();Working with Client Object Model
    }
    private void AsynchCallback(IAsyncResult arg)
    {
    Console.WriteLine("Aynchronous Callback!");
    Console.WriteLine("Let us change the site title");
    Console.WriteLine("Title before changing: {0}", site.
    Title);
    site.Title = site.Title + " From Aysnchronous client
    application";
    site.Update();
    Console.WriteLine("Listings of all the lists from the
    site!");
    foreach (Microsoft.SharePoint.Client.List list in site.
    Lists)
    {
    Console.WriteLine(list.Title);
    }
    context.ExecuteQuery();
    Console.WriteLine("Query completed!");
    }
    }
    }

  7. The following screenshot shows the output of the program:

  8. The change of the site title is shown as follows:

How it works...

The ExecuteQueryAsynch method is used by both Silverlight and JavaScript Object Models to make asynchronous calls. This method is not supported in the Managed OM. We have to use the standard .NET techniques to invoke the ExecuteQuery method asynchronously. For that purpose, we use delegate. When we execute a method asynchronously, we need to provide a callback method that can be invoked when the asynchronous call completes and is ready with the response. Our callback method in the code is AsynchCallback.

A delegate is a type that references a method. You can associate a delegate with any method as long as they have the compatible signature. We defined a delegate named ExecuteAsynchQuery. In our declaration of delegates, we did not define any parameters because ExecuteQuery does not have any either. We associated our delegate instance with ExecuteQuery and invoked it asynchronously by using the method BeginInvoke. The .NET runtime automatically defines the BeginInvoke and EndInvoke methods on the delegate with appropriate signatures. The method signature of BeginInvoke is BeginInvoke(callback, object[]params);.

The first parameter takes the callback method delegate. The second parameter is the user defined values that can be passed to the callback method. In our case, we are not passing in any and hence null. The BeginInvoke executes the method described in the delegate asynchronously. Once the method completes its execution, it invokes the callback method indicated. For more information on calling synchronous methods asynchronously, refer to MSDN at: http://msdn.microsoft.com/en-US/library/2e08f6yc(v=VS.80).aspx

Summary

In this article we learnt the exception handling techniques and asynchronous calling of the object models.


Further resources on this subject:


Microsoft SharePoint 2010 Development with Visual Studio 2010 Expert Cookbook Develop, debug, and deploy business solutions for Microsoft SharePoint applications using Microsoft Visual Studio 2010 with this book and ebook.
Published: September 2011
eBook Price: $29.99
Book Price: $49.99
See more
Select your format and quantity:

About the Author :


Balaji Kithiganahalli

Balaji Kithiganahalli is the CEO of Integrate, LLC that specializes in SharePoint implementations. Balaji has a Master’s degree in Systems Engineering and has over 18 years of consulting experience in Microsoft technologies. Balaji has architected and implemented SharePoint solutions for many fortune 500 companies and government organizations.

Balaji Kithiganahalli is the author of "Microsoft SharePoint 2010 Development with Visual Studio 2010 Expert Cookbook".

Books From Packt

Code Download and Errata
Packt Anytime, Anywhere
Register Books
Print Upgrades
eBook Downloads
Video Support
Contact Us
Awards Voting Nominations Previous Winners
Judges Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software
Resources
Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software