Dealing with .NET Managed Code in Clinet Object Model


In SharePoint 2010, one of the major changes that Microsoft has brought in development is the Client Object Model which facilitates the developers to use SharePoint 2010 Client APIs and build client based applications such as Windows Application, Silverlight and JavaScript client apps. Today, I am going to show you a nice example of using Client Object Model in .NET Managed code.

For this, first of all, I have populated few tables (Product, Category) from Microsoft Northwind Database as SharePoint lists on my site. In this example, I will deal with two of those tables which are: Product and Category. These are the screenshots of the tables:

image

image

Note that, I have a Lookup Column named ‘Category’ in Product List which is coming from ‘CategoryName’ column of Category List.

After that, I have created a Windows Application in Visual Studio 2010 and designed the following UI:

image

You can clearly see that my intention is to get all the categories and populate them in a Combo box and Products List Box will display all the products for that particular Category and the selected Product will display Product Details inside the Product Details Grid View. I also want to enable selecting multiple products which will make my Grid View more Dynamic so that the number of products you will select from the Product List Box, the same number of Product Details information will be there in the Grid View.

To achieve my goal, I have added the following code inside my Form Load method to initialize the items of Category Combo Box:

Form Load
  context = new ClientContext("http://www.teamradiant.net/"); //Creating New Client Context
  context.AuthenticationMode = ClientAuthenticationMode.FormsAuthentication; //Setting the Authentication Mode
  FormsAuthenticationLoginInfo formLoginInfo=new FormsAuthenticationLoginInfo("morshed","mypassword"); //Providing credentials for Forms Auth
  context.FormsAuthenticationLoginInfo = formLoginInfo; //Passing the credentials to Current Client Context
  web = context.Web;
                  
  var list = web.Lists.GetByTitle("Category"); //Getting the 'Category' List
  var query = new CamlQuery(); //Create a new CAML query
  query.ViewXml = "<View>" +
                 "<ViewFields>" +
                 "<FieldRef Name='CategoryName' />" +
                 "<FieldRef Name='Title' />" +
                 "</ViewFields>" +
                 "</View>"; //CAML Query details
  var items = list.GetItems(query); //Receiving the items from CAML query
  context.Load(items); //Loading the items in Current Context
  context.ExecuteQuery(); //Calling the Client.svc to send the request to SharePoint server and receive the response

  var listData = new List<DictionaryEntry>(); //Creating a Dictionary Data Structure to hold the list items
  foreach (var item in items)
  {
      var data = new DictionaryEntry(item["CategoryName"], item["Title"]); //setting every list item's column value to Key and Value.
     
      listData.Add(data); //Adding the data inside the Dictionary Data Structure object
  }
  CategoryBox.DisplayMember = "Value"; //Set the Display name of Combo Box items to item["Title"]
  CategoryBox.ValueMember = "Key"; //Set the Value of Combo box items to item to item["Key"]
  CategoryBox.DataSource = listData; //Setting the Data Source of Combo Box

You can see from the above code that I am querying for two columns from Category List which are: CategoryName and Title. ‘CategoryName’ is the Lookup column  that I need to pass to the Product List to get the related products for the selected Category.

Now, I add the following code for selected index changed method of the Combo Box:

SelectedIndexChange (ComboBox)
 if (CategoryBox.SelectedIndex == -1)
     return; //If Nothing is selected
 var category = CategoryBox.SelectedValue; //Getting the Selected Value from Category Combo Box

 var list = web.Lists.GetByTitle("Product"); //Getting the 'Product' list from the current site
 var query = new CamlQuery();
 query.ViewXml = "<View>" +
                 "<Query>" +
                 "<Where><Eq>" +
                 "<FieldRef Name='Category'/>" +
                 "<Value Type='Lookup'>" + category+"</Value>" +
                 "</Eq></Where>" +
                 "</Query>" +
                 "<ViewFields>" +
                 "<FieldRef Name='ProductID'/>" +
                 "<FieldRef Name='ProductName'/>" +
                 "</ViewFields>" +
                 "</View>"; //CAML Query details to get 'ProductID' and 'ProductName' for the selected Category
 

 var items = list.GetItems(query); //Get all items from the CAML query

 context.Load(items); //Loading items
 context.ExecuteQuery(); //Calling Client.svc to send the request to the SharePoint server and get the response

 var listData = new List<DictionaryEntry>(); //Creating a Dictionary Data Structure to hold the list items
 foreach (var item in items)
 {
     var data = new DictionaryEntry(item["ProductID"], item["ProductName"]); //setting every list item's column value to Key and Value.
     listData.Add(data); //Adding the data inside the Dictionary Data Structure object
 }
 ProductListBox.DisplayMember = "Value"; //Set the Display name of List Box items to item["Title"]
 ProductListBox.ValueMember = "Key"; //Set the Value of List box items to item to item["Key"]
 ProductListBox.DataSource = listData; ////Setting the Data Source of the List box

Note that, in Client Object Model, unlike the Server Side Object, the actual Loading of list items or data does not happen until we call ExecuteQuery()  which is  synchronous for .NET Managed Code.

Now, To show multiple selected items from the Products list inside the Products Grid View, I have created the following Class:

public class Products
    {
        public string ProductID { get; set; }
        public string ProductName { get; set; }
        public string SupplierID { get; set; }
        public string QuantityPerUnit { get; set; }
    }

To show the selected Products Details in the grid view, I have added the following code block inside the Selected Index Changed method of the Products  List box:

SelectedIndexChange (ListBox)
  1. if (ProductListBox.SelectedIndex == -1)
  2.     return; //If Nothing is selected inside Product List box
  3. var product = ProductListBox.SelectedValue; //get the single selected value of Product List box
  4. string strInProduct = "";
  5.  
  6. var total = ProductListBox.Items.Count; //Total Items inside Product List Box
  7. for(int i=0; i<total ;i++)
  8. {
  9.      if(ProductListBox.SelectedItems.Contains(ProductListBox.Items[i]))
  10.     {
  11.         var product1 = new DictionaryEntry(); //Create a new Dictionary Data Object to hold multiple selected items
  12.         product1=(DictionaryEntry)ProductListBox.Items[i]; //Setting each selected item with Keys and Values
  13.         strInProduct += "<Value Type='Number'>" + product1.Key + "</Value>"; //Modifying the CAML query clause inside 'IN' to check a range of items
  14.     }
  15. }
  16.  
  17. var list = web.Lists.GetByTitle("Product"); //Calling the 'Product' list of current site
  18. var query = new CamlQuery();
  19. query.ViewXml = "<View>" +
  20.                 "<Query>" +
  21.                 "<Where><In>" +
  22.                 "<FieldRef Name='ProductID'/><Values>" +
  23.                 strInProduct +
  24.                 "</Values></In></Where>" +
  25.                 "</Query>" +
  26.                 "<ViewFields>" +
  27.                 "<FieldRef Name='ProductID'/>" +
  28.                 "<FieldRef Name='ProductName'/>" +
  29.                 "<FieldRef Name='SupplierID'/>"+
  30.                 "<FieldRef Name='QuantityPerUnit'/>"+
  31.                 "</ViewFields>" +
  32.                 "</View>"; //Selecting 'ProductID', 'ProductName', 'SupplierID' and 'QuantityPerUnit' for each Product which are IN the range of selected items
  33.  
  34. var items = list.GetItems(query); //Getting the items from CAML query result
  35.  
  36. context.Load(items); //Loading the items in Current Context
  37. context.ExecuteQuery(); //Calling the Client.svc to send request to SharePoint server and get the response
  38.  
  39. List<Products> spProducts = new List<Products>(); //Create a List of 'Products' class type which is already defined
  40. foreach (ListItem item in items)
  41. {
  42.     spProducts.Add(new Products
  43.     {
  44.         ProductID = item["ProductID"].ToString(),
  45.         ProductName=item["ProductName"].ToString(),
  46.         SupplierID=item["SupplierID"].ToString(),
  47.         QuantityPerUnit=item["QuantityPerUnit"].ToString() //Setting each property of 'spProducts' list which is 'Products' class type   
  48.     });
  49. }
  50. gvProductDetails.DataSource = spProducts; //Setting the Data Source for the Grid View with 'spProducts' list

That’s basically it. I have commented about each line of code explaining the details for your understanding.

Now, I will be able to run this application from any machine as this app is using Client Object Model. As long as you use two DLLs in your application (Microsoft.SharePoint.Client & Microsoft.SharePoint.Client.Runtime), you can get the advantage of Client Object Model APIs from any application. Here is a screenshot of the application I discussed until now:

image

As you can see that all the Products for a particular category is showing up inside the list box and the details of those products are being shown inside the Grid View.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s