How to use SharePoint List for Telerik Reporting Datasource

by Reporting Team | Comments 3

SharePoint provides types and members in the Microsoft.SharePoint.Client namespace for accessing SharePoint remotely from a client computer or server. To get started with SharePoint client object model you will need Microsoft.SharePoint.Client and Microsoft.SharePoint.Client.Runtime assemblies. You can copy these DLLs from the %ProgramFiles%\Common Files\Microsoft Shared\web server extensions\14\ISAPI folder of the server that runs Microsoft SharePoint Foundation 2010.

Using the Microsoft.SharePoint.Client types you can get access to SharePoint List data. However in order to have design time support (Telerik Reporting Data Explorer, Wizards and Expression editor) with SharePoint as data source, you will need the following SharePointDataSource helper class. This class manages the SharePoint credentials, list schema and data retrieval. Just add the SharePointDataSource class to you project and build it. Then you can use it in Telerik Reporting ObjectDataSource as DataSource type and GetListData method as DataMember. The GetListData() method is parametrized with the required SharePoint credentials, List name and SharePoint URL thus you can directly set them in the ObjectDataSource wizard.

using System.Data;
using System.Net;
using System.Collections.Generic;
using Microsoft.SharePoint.Client;
 
namespace Telerik.Reporting
{
    class SharePointDataSource
    {
        /// <summary>
        /// Stores the list schema and data
        /// </summary>
        DataTable ListData { get; set; }
 
        /// <summary>
        /// Used by ObjectDataSource for retrieving the specified SP list data
        /// </summary>
        /// <param name="spFullUrl">SharePoint full URL</param>
        /// <param name="listName">List name</param>
        /// <param name="username">username</param>
        /// <param name="password">password</param>
        /// <param name="domain">domain</param>
        /// <returns>SharePoint List data as DataTable</returns>
        public DataTable GetListData(string spFullUrl,
                          string listName,
                          string username,
                          string password,
                          string domain)
        {
            var context = GetContext(spFullUrl,
                             username,
                             password,
                             domain);
            // build the CAML query to get ALL items
            var query = new CamlQuery();
            query.ViewXml = "";
            var list = context.Web.Lists.GetByTitle(listName);
            ListItemCollection items = list.GetItems(query);
            items.RetrieveItems().Retrieve();
            context.ExecuteQuery();
 
            ListData = new DataTable("ListData");
 
            var keys = new List<string>(InitializeSchema(items));
            FillDataTable(items,
                     keys);
 
            context.Dispose();
            return ListData;
        }
 
        void FillDataTable(ListItemCollection items,
                    List<string> keys)
        {
            foreach (ListItem item in items)
            {
                var rowValues = new object[keys.Count];
                var counter = 0;
                foreach (var key in keys)
                {
                    rowValues[counter++] = item.FieldValues[key];
                }
                ListData.LoadDataRow(rowValues, true);
            }
        }
 
        IEnumerable<string> InitializeSchema(ListItemCollection items)
        {
            var firstRow = items[0].FieldValues;
            foreach (var key in firstRow.Keys)
            {
                if (null != firstRow[key])
                {
                    ListData.Columns.Add(key, firstRow[key].GetType());
                    yield return key;
                }
            }
        }
 
        static ClientContext GetContext(string spFullUrl,
                             string username,
                             string password,
                             string domain)
        {
            var context = new ClientContext(spFullUrl);
            var credetentials = new NetworkCredential(username,
                                       password,
                                       domain);
            context.Credentials = credetentials;
            return context;
        }
    }
}

Check out SharePointDataSource.zip sample project that illustrates the suggested approach. In order to run it you have to reference the Microsoft.SharePoint.Client and Microsoft.SharePoint.Client.Runtime assemblies. Additionally you have to update the ObjectDataSource parameters with your SharePoint URL, credentials and list name.

About the author

Petar Raykov

is a Software Developer in the Telerik Reporting division. He loves snowboarding, horror novels and electronic music.

3 Comments

Eric
Love it... but How do I take 2 lists and join them?
2 seperate datasource do not seem to work...
Suggestions?
Peter

Telerik Reporting data items (report, crosstab, table, list and chart) are optimized to work with a single datasource component. Thus when data is required from multiple data objects like SP lists my suggestion is to:

  • use separate data items for every data object. For example you can have any number of crosstabs, tables, lists and charts in a single report definition and every data item can utilize a separate data source component;
  • If you have a common key for the SP Lists, you can use a report parameter for the common key column and multiple data items. Then you can filter the data items based on this common column parameter. This way you can have one report that uses a distinct data item for every SP List;
  • internally handle the relations between the separate data objects and return a single data object (DataTable) that contains both DataTable SP list data.
    In accomplish this you can extend the GetListData() constructor to accept multiple SP list names. Then for every SP list you can invoke InitializeSchema() and FillDataTable() and combine those DataTables based on SP Lists relations logic.

Magnus Lindgren
The link to the sample projekt is broken, can you fix it?

Comments

  1.    
      
      
       
  2. (optional, emails won't be shown on public pages)
  3. (optional)
Read more articles by Reporting Team - or - read latest articles in Developer Tools