Second Life of a Hungarian SharePoint Geek

January 26, 2011

Creating external lists using the managed client object model

Filed under: BCS, External list, Managed Client OM, SP 2010 — Tags: , , , — Peter Holpar @ 23:06

Last year I wrote a post about how to create external lists in SharePoint 2010 using server side code. Now I show you how to achieve the same result from the client side.

The solution does not differ too much, there are only two minor differences:

  1. External data source property names are not exposed as public fields (see the members of the SPListDataSource.BDCProperties class on the server side).
  2. When adding the new external list to the SPListCollection, you have to use the Add method that has three String parameters (title, description and url) and a dataSource parameter of SPListDataSource type. The result of the call is the ID (Guid) of the new list.
    On the client side we have use the Add method of the ListCollection class that has a single parameters parameter of type ListCreationInformation. The ListCreationInformation class represents all the information (list title, description, URL, data source properties, and a few more info) we used on the server side. The return type of the Add method is List. Another Important difference is that in this case the data source properties are not represented as a SharePoint-specific type, like SPListDataSource on the server side, but they are collected into a DataSourceProperties property that is a “standard” .NET  IDictionary<string, string> type. The additional information in ListCreationInformation contains for example a QuickLaunchOption property of enum type  QuickLaunchOption (possible values Off, On and DefaultValue).

After this introduction let’s see the code.

First, I’ve created an extension method in a static helper class to make my life easier and to avoid mistyping parameter names:

  1. // the listDataSource parameter is only a fake one to enable attaching the static method to ListDataSource type
  2. public static IDictionary<String, String> Initialize(this ListDataSource listDataSource, String entity, String entityNamespace, String lobSystemInstance, String specificFinder)
  3. {
  4.     // BDCProperties (SPListDataSource internal class) are not available from client code, we should use string literals
  5.     Dictionary<String, String> result = new Dictionary<String, String>();
  6.     result.Add("Entity", entity);
  7.     result.Add("EntityNamespace", entityNamespace);
  8.     result.Add("LobSystemInstance", lobSystemInstance);
  9.     result.Add("SpecificFinder", specificFinder);
  10.  
  11.     return result;
  12. }

As you can see, the listDataSource parameter is not used in the class. My purpose was only to bind the functionality to the ListDataSource class and keep the working of the server-side and client-side codes as parallel as it is possible.

The following code demonstrates the creation of the external list from the managed client API using the extension method we created above.

  1. ClientContext clientContext = new ClientContext(siteUrl);
  2. Web web = clientContext.Web;
  3.  
  4. ListCollection lists = web.Lists;
  5.  
  6. ListDataSource listDataSource = new ListDataSource();
  7. // set up the list data source properties using the extension method (see Extensions.cs)
  8. IDictionary<String, String> listDataSourceProp = listDataSource.Initialize("YourBdcEntity", "YourBdc.EntityNamespace", "YourLobSystemInstancece", "ReadItem");
  9.  
  10. // initialize create list info
  11. // IMPORTANT! The DataSourceProperties is not of type ListDataSource,
  12. // as one may expect, but a simple IDictionary<String, String>
  13. ListCreationInformation listCreateInfo = new ListCreationInformation
  14. {
  15.     Title = listTitle,
  16.     Description = "List description",
  17.     DataSourceProperties = listDataSourceProp,
  18.     Url = "listurl",
  19.     QuickLaunchOption = QuickLaunchOptions.On
  20. };
  21.  
  22. // create list
  23. List newList = lists.Add(listCreateInfo);
  24.  
  25. clientContext.ExecuteQuery();

I made some test if I can to change the data source binding of a list after creation.

The List class contains a DataSource property of type ListDataSource, but it is read-only so you cannot make a standard list to  an external one, or change the data source parameters simply like:

newList.DataSource = listDataSource;

The above code lines produces a compile time error.

I’ve also tested what happens if I change the properties of the data source one-by-one like shown here:

  1. clientContext.Load(newList, list => list.DataSource);
  2. clientContext.ExecuteQuery();
  3.  
  4. newList.DataSource.Properties["SpecificFinder"] = "AnotherSpecificFinder";
  5. clientContext.ExecuteQuery();

Using this code I’ve experienced neither compile-time nor run-time error, but when I checked the value of the property later using this code:

  1. clientContext.Load(existingList, list => list.DataSource);
  2. clientContext.ExecuteQuery();
  3. Console.WriteLine(existingList.DataSource.Properties["SpecificFinder"]);

I found that the value of the property has not been changed. So it seems to be a good idea to plan and set the properties of your external lists in advance.

Advertisements

Leave a Comment »

No comments yet.

RSS feed for comments on this post. TrackBack URI

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 )

Twitter picture

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

Facebook photo

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

Google+ photo

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

Connecting to %s

Create a free website or blog at WordPress.com.

%d bloggers like this: