SharePoint Config

Ari Bakker's thoughts on customising and configuring SharePoint

Creating custom parameters for a SPDataSource

with 3 comments

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.

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;
    }
}

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.

<%@ Register Tagprefix="CustomWebControls" Namespace="Ari.PublicWebsite.ServerControls" Assembly="Ari.PublicWebsite"  %>
<SharePointWebControls:SPDataSource
    runat="server"
    ID="dsComments"
    DataSourceMode="List"
    UseInternalName="true"
    UseServerDataFormat="true"
    selectcommand="&lt;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>

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.

<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:

sharepoint-2010-blog-comments-page

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.NET ListView 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.

If you haven’t used this control before check out the SPDataSource documentation on MSDN. Chris O’Brian also has a good series titled SPDataSource every developers friend.

Post to Twitter Post to Delicious Post to Digg Post to Reddit Post to StumbleUpon

Written by Ari Bakker

August 12th, 2010 at 8:55 pm

3 Responses to 'Creating custom parameters for a SPDataSource'

Subscribe to comments with RSS or TrackBack to 'Creating custom parameters for a SPDataSource'.

  1. Ari,
    Great article, I have just been thinking about how to exclude the current item being viewed from a list of results created by SPDataSource.

    After doing some reading, thought about a custom parameter class – quick check on Google and its already been done! This post will save me sometime!

    Have to catch up soon!

    Thanks
    Simon

    Simon Doy

    27 Aug 10 at 12:56 pm

  2. Hi Ari,

    Excellent article, i’ve done exactly the same thing on a Enterprise Wiki site, with a twist – i use jQuery and ECMA script to submit comments, customized to be used instead of the Blog site.

    Regards,
    C:\Marius

    C:\Marius

    15 Nov 11 at 1:21 pm

  3. Hi Ari,

    Thank you for your post. I am sort of find my way around working with SPD however not sure where how should I create the namespace and the assembly for the class you created in my page. If you could give me some hints, it would be much apprecited.

    Many Thanks,
    Hamish

    Hamish

    22 Dec 11 at 4:23 am

Leave a Reply

*