The SPDataSource is a great control for retrieving data in SharePoint. You can query a single list, multiple lists/libraries or webs and bind the data to any ASP.NET data bound control such as a Repeater, ListView, GridView or DropDownList as well as the DataFormWebPart if you want to control the output using XSLT.
You can also pass in parameters for your query such as the ListName or WebUrl using the parameter classes provided by ASP.NET such as the QueryStringParameter and ControlParameter class. As these are all generic ASP.NET controls, however, there is no way of using SharePoint specific information such as properties of the current page, or information from User Profiles. For example it isn’t possible to use this on a SharePoint publishing page and use a metadata value such as the Title, Author or list item ID to filter the results.
Some examples of where this might be useful are:
Displaying items from a list that has a lookup column pointing to the pages library (e.g. a comments list that contains a lookup to a publishing page)
Displaying items that are related to properties on the current page (e.g. ‘recent articles by this author’ or ‘other articles in this category’)
Displaying items using a configurable property stored in SharePoint (e.g. displaying items from a specific list or site that can be altered by an end user)
Displaying a set of items based on information from the current users SharePoint profile (e.g. pages that relate to the current user’s office)
One easy way of creating these dynamic parameters is to create a custom class that inherits from System.Web.Controls.Parameter. We can then use the Evaluate method to retrieve the information we want. The example below shows how this can be done to retrieve a value from the current page/list item.
We can then use this in our SPDataSource to bind to parameters such as the WebURL, ListItemID, or pass these into our CAML query. The example below shows how we could use this on a publishing page to display items from a ‘Comments’ list that contains a lookup field pointing to the pages within this site.
Note the addition of a reference to our class at the top of the page and then the parameter inside the SelectParameters element of the SPDataSource. We could easily extend this to create additional properties other than the ‘PropertyName’ that is shown. If we then bind this to a Repeater we get something like the following assuming a list name ‘Comments’ exists with a lookup that references the current page.
public class PageFieldParameter : System.Web.UI.WebControls.Parameter
{
public string PropertyName { get; set; }
protected override object Evaluate(HttpContext context, System.Web.UI.Control control)
{
if (SPContext.Current != null && SPContext.Current.ListItem != null && !string.IsNullOrEmpty(PropertyName))
{
switch(PropertyName)
{
case "ID" :
return SPContext.Current.ListItem.ID;
case "DisplayName" :
return SPContext.Current.ListItem.DisplayName;
default :
return SPContext.Current.ListItem[PropertyName];
}
}
return null;
<%@ Register Tagprefix="CustomWebControls" Namespace="Ari.PublicWebsite.ServerControls" Assembly="Ari.PublicWebsite" %>
}
<SharePointWebControls:SPDataSource
}
runat="server"
ID="dsComments"
DataSourceMode="List"
UseInternalName="true"
UseServerDataFormat="true"
selectcommand="<View><Query><Where><Eq><FieldRef Name='Post' LookupId='TRUE' /><Value Type='Lookup'>{PostID}</Value></Eq></Where></Query></View>">
<SelectParameters>
<asp:Parameter Name="ListName" DefaultValue="Comments"/>
<asp:Parameter Name="WebURL" DefaultValue="{sitecollectionroot}"/>
<CustomWebControls:PageFieldParameter Name="PostID" PropertyName="ID"/>
</SelectParameters>
</SharePointWebControls:SPDataSource>
<asp:Repeater runat="server" DataSourceID="dsComments">
<ItemTemplate>
<h4><%# Eval("FullName") %></h4>
<span class="comment"><%# Eval("Body") %></span>
</ItemTemplate>
</asp:Repeater>
If we place this on the default ‘Image on left’ page layout we get something like the example shown below:
Note that in SharePoint 2010 the Content Query Web Part PageFieldValue property could be used to achieve a similar result in this specific scenario but the SPDataSource allows you to bind to controls such as the ASP.NETListView or the Data View Web Part and this can also be used in SharePoint 2007. Additionally the Content Query Web Part only provides dynamic parameters based on the query string or the page so information from places such as user profiles would need to use this approach.