<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:series="http://unfoldingneurons.com/"
	>

<channel>
	<title>SharePoint Magazine &#187; datasources</title>
	<atom:link href="http://sharepointmagazine.net/tag/datasources/feed" rel="self" type="application/rss+xml" />
	<link>http://sharepointmagazine.net</link>
	<description>SharePoint Magazine is an online Magazine dedicated to the world of SharePoint</description>
	<lastBuildDate>Mon, 05 Jul 2010 09:14:11 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Populating data sources in code</title>
		<link>http://sharepointmagazine.net/technical/development/populating-data-sources-in-code</link>
		<comments>http://sharepointmagazine.net/technical/development/populating-data-sources-in-code#comments</comments>
		<pubDate>Fri, 25 Jul 2008 09:28:27 +0000</pubDate>
		<dc:creator>furuknap</dc:creator>
				<category><![CDATA[Customisation]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Technical]]></category>
		<category><![CDATA[dataformwebpart]]></category>
		<category><![CDATA[datasources]]></category>
		<category><![CDATA[dfwp]]></category>

		<guid isPermaLink="false">http://sharepointmagazine.net/?p=12</guid>
		<description><![CDATA[How to modify the data sources of a DataFormWebPart real-time and make a simple content aggregator.]]></description>
			<content:encoded><![CDATA[<p>Let’s say you want to aggregate news articles from any sub site in a site collection. Now, it would be easy to do this statically using a linked data source as AggregateDataSource and SharePoint designer. However, what if the sub sites change? You will have to remake the data source in SPD or even by hand.</p>
<p>Now, some will argue that you can use a cross site SPDataSource to accomplish this, and more, and they would of course be right. There are far simpler ways of getting to the end result, but the point of this article is to show you how to modify components runtime. If you wanted to make a simple aggregator, use Content Query Web Part, a cross site SPDataSource or even RSS. If you want to learn runtime modification of a component, read on.</p>
<p>Just to make sure you know where we stand, I&#8217;ll explain the AggregateDataSource and how to make a linked data source in SPD. Even if you know how to do this, please follow the example so you understand the problems we face when we have a dynamic site structure and understand the site structure from which we are trying to aggregate.</p>
<p>First, we begin by assuming the following site structure:<br />
<img style="middle;" src="http://sharepointmagazine.net/wp-content/uploads/2008/07/sitestructure2.png" alt="Site Structure" width="491" height="214" /><br />
Now, in each of these sub sites we have a custom list called &#8216;Articles&#8217; containing at least the fields &#8216;Title&#8217; and &#8216;Pri&#8217;. We want to have a web part that aggregates all the titles from all the articles, sorted by Pri.<br />
If the site structure is static you can accomplish this by using what is called a linked data source. To create one, start up SPD and go to the Data Source Library. On the very bottom, click ‘Connect to another library…’ Then, for each sub site in the structure, click Add and enter a name and the location of the sub site.</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/07/step-11.png" target="_blank"><img class="size-medium wp-image-14" src="http://sharepointmagazine.net/wp-content/uploads/2008/07/step-11-300x231.png" alt="Screenshot - click to open in new window" width="300" height="231" /></a></p>
<p>Click image to open larger screenshot in new window</p>
<p>If you look at the Data Source Library again, you will notice that among the data sources available to you, you now have access to all the lists in the sub sites you entered. You can add any list or data source as a web part to a page. However, we want to aggregate all the articles from several lists, and for this we need a linked data source.</p>
<p>Expand the &#8216;Linked sources’ node and click ’Create a new Linked Source…’ and then [Configure Linked Source…]. For each of the sub sites you added earlier, double-click the Articles-lists to add them to the ‘Selected data sources’ list and then click Next.</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/07/step-2.png" target="_blank"><img class="size-medium wp-image-9" src="http://sharepointmagazine.net/wp-content/uploads/2008/07/step-2-300x230.png" alt="Screenshot - click to open in new window" width="300" height="230" /></a></p>
<p>Click image to open larger screenshot in new window</p>
<p>On the next page, make sure that you select the ‘Merge’ option, and then click Finish. If you like, go to the General tab and add a name, description and keywords for this data source. When done, click Ok.</p>
<p>Once created you can drag-and-drop the new data source to a page to create a DataFormWebPart (DFWP) with the merged articles. You can work with the DFWP just as you would any other DFWP with a single list data source. Format it, add or remove fields, apply layouts, do what you want.</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/07/step-31.png" target="_blank"><img class="size-medium wp-image-16" src="http://sharepointmagazine.net/wp-content/uploads/2008/07/step-31-300x230.png" alt="Screenshot - click to open in new window" width="300" height="230" /></a></p>
<p>Click image to open larger screenshot in new window</p>
<p>This is useful for static site structures where the lists are pre-defined or very rarely changing. However, should you chose to add, edit or remove sub sites containing information you want aggregated you need to modify your data source.</p>
<p>Now, if you watch the web part in code view in SharePoint Designer you will see that what you have added is actually a normal DataFormWebPart with a child element called DataSources, marked in the screenshot by a green line, containing an AggregateDataSource. The tags, such as DataFormWebPart are just ordinary .net classes represented as markup. As such we can easily manipulate the contents of the tag and thus the behavior of the class using custom code. This is how we can create a dynamic AggregateDataSource.</p>
<p>First things first, we need a DataFormWebPart whose DataSources we will manipulate. Create a new aspx-page, give it a name (mine is called MyTestPage.aspx), and drag your newly created Linked DataSource onto the design canvas in SPD. Feel free to change layouts or anything else as mentioned above.<br />
Now, you may ask: If I am going to write code to manipulate the DataSources, why not just write code to create the whole DataFormWebPart? Great question, I am glad you asked.</p>
<p>The short answer is: It is easier.</p>
<p>The longer answer is: Well, if you do that you either need to inherit or create the design-capabilities of your custom DataFormWebPart. By using a DFWP that already exists you can format, layout and manipulate that using the built-in design capabilities and only worry about what data will be displayed, not how. Designers will love you for this; they get to go bananas making the thing look beautiful and you get to drop your custom component someplace on the page and change the data that is getting displayed. Good development practice isolates presentation from data.</p>
<p>Let’s get down to the code, shall we.</p>
<p>Start by creating a simple custom component. If you have not done this before I have written an article that will guide you through the steps of creating a simple custom component, at <a href="http://furuknap.blogspot.com/2008/05/creating-your-own-custom-components-for.html">http://furuknap.blogspot.com/2008/05/creating-your-own-custom-components-for.html</a>. However, contrary to that example, do not override the RenderContents method but rather the OnLoad method. If you don’t want to write all the code I’ve attached a ‘Begin’ solution for Visual Studio 2005. Look at the very end of this article for it. Just do it now, and then come back. I&#8217;ll wait right here for you.</p>
<p>Overriding OnLoad ensures that when the component is loaded we can access the DataSources of the DFWP. The OnLoad event happens before the DataBinding events so by changing the DataSources in OnLoad we make sure we set the DataSources at the right time. This is important, once the DataBinding methods have been run there is no way to manipulate them and get the result displayed.</p>
<div style="white;">
<pre style="0px;"><span style="#2b91af;">   33</span>         <span style="#0000ff;">protected</span> <span style="#0000ff;">override</span> <span style="#0000ff;">void</span> OnLoad(<span style="#2b91af;">EventArgs</span> e)</pre>
<pre style="0px;"><span style="#2b91af;">   34</span>         {</pre>
</div>
<p>Since we are going to manipulate an existing DataFormWebPart control, we need some method of identifying and accessing that control. We also need some way of knowing which lists we want to aggregate. Lets solve these problems by adding a few properties to our control. Add the following lines to your class:</p>
<div style="white;">
<pre style="0px;"><span style="#2b91af;">   17</span>         <span style="#0000ff;">private</span> <span style="#0000ff;">string</span> m_DataFormWebPartId;</pre>
<pre style="0px;"><span style="#2b91af;">   18</span></pre>
<pre style="0px;"><span style="#2b91af;">   19</span>         <span style="#0000ff;">public</span> <span style="#0000ff;">string</span> DataFormWebPartId</pre>
<pre style="0px;"><span style="#2b91af;">   20</span>         {</pre>
<pre style="0px;"><span style="#2b91af;">   21</span>             <span style="#0000ff;">get</span> { <span style="#0000ff;">return</span> m_DataFormWebPartId; }</pre>
<pre style="0px;"><span style="#2b91af;">   22</span>             <span style="#0000ff;">set</span> { m_DataFormWebPartId = <span style="#0000ff;">value</span>; }</pre>
<pre style="0px;"><span style="#2b91af;">   23</span>         }</pre>
<pre style="0px;"><span style="#2b91af;">   24</span></pre>
<pre style="0px;"><span style="#2b91af;">   25</span>         <span style="#0000ff;">private</span> <span style="#0000ff;">string</span> m_ListName;</pre>
<pre style="0px;"><span style="#2b91af;">   26</span></pre>
<pre style="0px;"><span style="#2b91af;">   27</span>         <span style="#0000ff;">public</span> <span style="#0000ff;">string</span> ListName</pre>
<pre style="0px;"><span style="#2b91af;">   28</span>         {</pre>
<pre style="0px;"><span style="#2b91af;">   29</span>             <span style="#0000ff;">get</span> { <span style="#0000ff;">return</span> m_ListName; }</pre>
<pre style="0px;"><span style="#2b91af;">   30</span>             <span style="#0000ff;">set</span> { m_ListName = <span style="#0000ff;">value</span>; }</pre>
<pre style="0px;"><span style="#2b91af;">   31</span>         }</pre>
</div>
<p>Doing this allows us to configure the component at design-time. The public properties are used as part of the asp.net tag, for instance &lt;MyTags:DynamicAggregateDataSource <em><strong>DataFormWebPartId</strong></em>=”MyDFWPId” <em><strong>ListName</strong></em>=”Articles” runat=”server”/&gt;</p>
<p>Now what we have a way of identifying the DFWP and the listnames to aggregate we need to gain access to the DFWP DataSources. Then we can start manipulating the datasources. Add the following code to the OnLoad method:</p>
<div style="white;">
<pre style="0px;"><span style="#2b91af;">   35</span>             <span style="#2b91af;">DataFormWebPart</span> m_dfwp = <span style="#0000ff;">this</span>.Page.FindControl(DataFormWebPartId) <span style="#0000ff;">as</span> <span style="#2b91af;">DataFormWebPart</span>;</pre>
<pre style="0px;"><span style="#2b91af;">   36</span></pre>
<pre style="0px;"><span style="#2b91af;">   37</span>             m_dfwp.DataSources.Clear(); <span style="#008000;">// Empty datasources</span></pre>
<pre style="0px;"><span style="#2b91af;">   38</span></pre>
<pre style="0px;"><span style="#2b91af;">   39</span>             <span style="#2b91af;">AggregateDataSource</span> ads = <span style="#0000ff;">new</span> <span style="#2b91af;">AggregateDataSource</span>();</pre>
<pre style="0px;"><span style="#2b91af;">   40</span>             <span style="#0000ff;">int</span> sourceCounter = 0;</pre>
<pre style="0px;"><span style="#2b91af;">   41</span>             <span style="#2b91af;">SPWeb</span> web = <span style="#2b91af;">SPContext</span>.Current.Web;</pre>
<pre style="0px;"><span style="#2b91af;">   42</span>             <span style="#2b91af;">StringBuilder</span> aggregateString = <span style="#0000ff;">new</span> <span style="#2b91af;">StringBuilder</span>();</pre>
<pre style="0px;"><span style="#2b91af;">   43</span></pre>
<pre style="0px;"><span style="#2b91af;">   44</span>             aggregateString.AppendLine(<span style="#a31515;">"&lt;concat name=\"data source\"&gt;"</span>);</pre>
</div>
<p>In line 35 we get the reference to the DFWP. Line 37 clears the current datasources. Lines 39-44 creates objects and variables we need to build our DataSources. I&#8217;ll explain some of these a bit later.</p>
<p>Lookup back at the markup of the DFWP, specifically the DataSources tag:<br />
2 &lt;DataSources&gt;<br />
3   &lt;SharePoint:AggregateDataSource runat=&#8221;server&#8221; IsSynchronous=&#8221;false&#8221; id=&#8221;Articles_x0020_from_x0020_all_x0020_subsites1&#8243;&gt;<br />
4     &lt;sources&gt;<br />
5       &lt;SharePoint:SPDataSource runat=&#8221;server&#8221; DataSourceMode=&#8221;List&#8221; UseInternalName=&#8221;true&#8221; selectcommand=&#8221;&lt;View&gt;&lt;/View&gt;&#8221;&gt;<br />
6         &lt;SelectParameters&gt;<br />
7           &lt;asp:Parameter Name=&#8221;ListID&#8221; DefaultValue=&#8221;DD7603E8-1705-4AC4-8F9F-6BD31D6976ED&#8221;/&gt;<br />
8         &lt;/SelectParameters&gt;<br />
9         &lt;DeleteParameters&gt;<br />
10           &lt;asp:Parameter Name=&#8221;ListID&#8221; DefaultValue=&#8221;DD7603E8-1705-4AC4-8F9F-6BD31D6976ED&#8221;/&gt;<br />
11         &lt;/DeleteParameters&gt;<br />
12         &lt;UpdateParameters&gt;<br />
13           &lt;asp:Parameter Name=&#8221;ListID&#8221; DefaultValue=&#8221;DD7603E8-1705-4AC4-8F9F-6BD31D6976ED&#8221;/&gt;<br />
14         &lt;/UpdateParameters&gt;<br />
15         &lt;InsertParameters&gt;<br />
16           &lt;asp:Parameter Name=&#8221;ListID&#8221; DefaultValue=&#8221;DD7603E8-1705-4AC4-8F9F-6BD31D6976ED&#8221;/&gt;<br />
17         &lt;/InsertParameters&gt;<br />
18       &lt;/SharePoint:SPDataSource&gt;<br />
19       &lt;SharePoint:SPDataSource runat=&#8221;server&#8221; DataSourceMode=&#8221;List&#8221; UseInternalName=&#8221;true&#8221; selectcommand=&#8221;&lt;View&gt;&lt;/View&gt;&#8221;&gt;<br />
20         &lt;SelectParameters&gt;<br />
21           &lt;asp:Parameter Name=&#8221;ListID&#8221; DefaultValue=&#8221;9189EF30-7877-4B8D-9583-E7EE3C74C84F&#8221;/&gt;<br />
22           &lt;asp:Parameter Name=&#8221;WebURL&#8221; DefaultValue=&#8221;/ss1/&#8221;/&gt;</p>
<p>…etc. The code has been abbreviated to save space.</p>
<p>This markup reveals how the DataSources work and what we need to create using code. First, as stated in markup line 3, there needs to be an AggregateDataSource, which we create in codeline 39. This in turn contains a property, in markup line 4, called Sources. The Sources property, although we do not know exactly what type it is only from the markup, seems to contain a collection of several SPDataSources, markup lines 5 and 19, which in turn contains a set of Select-, Delete-, Update-, and Insert Parameters objects each.</p>
<p>In addition, after the Sources tag of the AggregateDataSource there is a tag called aggregate containing some strings.</p>
<p>110     &lt;aggregate&gt;<br />
111       &lt;concat name=&#8221;data source&#8221;&gt;<br />
112         &lt;datasource name=&#8221;Articles&#8221; id=&#8221;0&#8243; Type=&#8221;SPList&#8221;/&gt;<br />
113         &lt;datasource name=&#8221;Articles2&#8243; id=&#8221;1&#8243; Type=&#8221;SPList&#8221;/&gt;<br />
114         &lt;datasource name=&#8221;Articles3&#8243; id=&#8221;2&#8243; Type=&#8221;SPList&#8221;/&gt;<br />
115         &lt;datasource name=&#8221;Articles4&#8243; id=&#8221;3&#8243; Type=&#8221;SPList&#8221;/&gt;<br />
116         &lt;datasource name=&#8221;Articles5&#8243; id=&#8221;4&#8243; Type=&#8221;SPList&#8221;/&gt;<br />
117         &lt;datasource name=&#8221;Articles6&#8243; id=&#8221;5&#8243; Type=&#8221;SPList&#8221;/&gt;<br />
118       &lt;/concat&gt;<br />
119     &lt;/aggregate&gt;<br />
120   &lt;/SharePoint:AggregateDataSource&gt;</p>
<p>In the AggregateDataSource class, this property is not, despite its appearances, a collection, but a string. It would make sense to have the aggregate property as a collection so we can just add items to it, but for some reason, this is not so. We therefore need to build this string, using unique names and id values for each datasource we want to add. This is why we have the sourcecounter int and stringbuilder aggregateString in the code, lines 40 and 42.</p>
<p>So, based on this we can start thinking of how our component should build the DataSources. We have our AggregateDataSource, now we need to start adding SPDataSources to its sources property.</p>
<p>Since we want to aggregate from several subsites it makes sense to use a recursive function, and lets call it getSubWebItems. Now, in my implementation I will be breaking some best practices regarding recursive functions, but bear with me, I’m doing this as a sample, you will likely want to implement your own recursiveness.</p>
<p>The signature of the function could be something like this:<br />
private void getSubWebItems(AggregateDataSource ads, ref int sourceCounter, StringBuilder aggregateString, SPWeb web)<br />
The function will then use the web and sourceCounter objects to manipulate the ads and aggregateString objects. Let’s take a look:</p>
<div style="white;">
<pre style="0px;"><span style="#2b91af;">   57</span>         <span style="#0000ff;">private</span> <span style="#0000ff;">void</span> getSubWebItems(<span style="#2b91af;">AggregateDataSource</span> ads, <span style="#0000ff;">ref</span> <span style="#0000ff;">int</span> sourceCounter, <span style="#2b91af;">StringBuilder</span> aggregateString, <span style="#2b91af;">SPWeb</span> web)</pre>
<pre style="0px;"><span style="#2b91af;">   58</span>         {</pre>
<pre style="0px;"><span style="#2b91af;">   59</span>             <span style="#0000ff;">try</span></pre>
<pre style="0px;"><span style="#2b91af;">   60</span>             {</pre>
<pre style="0px;"><span style="#2b91af;">   61</span>                 <span style="#2b91af;">SPList</span> list = web.Lists[m_ListName];</pre>
<pre style="0px;"><span style="#2b91af;">   62</span>                 <span style="#2b91af;">SPDataSource</span> sds = <span style="#0000ff;">new</span> <span style="#2b91af;">SPDataSource</span>();</pre>
<pre style="0px;"><span style="#2b91af;">   63</span>                 <span style="#2b91af;">Parameter</span> p = <span style="#0000ff;">new</span> <span style="#2b91af;">Parameter</span>();</pre>
<pre style="0px;"><span style="#2b91af;">   64</span>                 p.Name = <span style="#a31515;">"ListId"</span>;</pre>
<pre style="0px;"><span style="#2b91af;">   65</span>                 p.DefaultValue = list.ID.ToString();</pre>
<pre style="0px;"><span style="#2b91af;">   66</span>                 sds.SelectParameters.Add(p);</pre>
<pre style="0px;"><span style="#2b91af;">   67</span></pre>
<pre style="0px;"><span style="#2b91af;">   68</span>                 p = <span style="#0000ff;">new</span> <span style="#2b91af;">Parameter</span>();</pre>
<pre style="0px;"><span style="#2b91af;">   69</span>                 p.Name = <span style="#a31515;">"WebURL"</span>;</pre>
<pre style="0px;"><span style="#2b91af;">   70</span>                 p.DefaultValue = web.ServerRelativeUrl;</pre>
<pre style="0px;"><span style="#2b91af;">   71</span>                 sds.SelectParameters.Add(p);</pre>
<pre style="0px;"><span style="#2b91af;">   72</span></pre>
<pre style="0px;"><span style="#2b91af;">   73</span>                 sds.DataSourceMode = <span style="#2b91af;">SPDataSourceMode</span>.List;</pre>
<pre style="0px;"><span style="#2b91af;">   74</span>                 sds.UseInternalName = <span style="#0000ff;">true</span>;</pre>
<pre style="0px;"><span style="#2b91af;">   75</span></pre>
<pre style="0px;"><span style="#2b91af;">   76</span>                 sds.SelectCommand = <span style="#a31515;">"&lt;View&gt;&lt;/View&gt;"</span>;</pre>
<pre style="0px;"><span style="#2b91af;">   77</span>                 ads.Sources.Add(sds);</pre>
<pre style="0px;"><span style="#2b91af;">   78</span></pre>
<pre style="0px;"><span style="#2b91af;">   79</span>                 aggregateString.AppendLine(<span style="#a31515;">"&lt;datasource name=\""</span> + m_ListName + sourceCounter + <span style="#a31515;">"\" id=\""</span> + sourceCounter + <span style="#a31515;">"\" Type=\"SPList\"/&gt;"</span>);</pre>
<pre style="0px;"><span style="#2b91af;">   80</span>                 sourceCounter++;</pre>
<pre style="0px;"><span style="#2b91af;">   81</span></pre>
<pre style="0px;"><span style="#2b91af;">   82</span>             }</pre>
<pre style="0px;"><span style="#2b91af;">   83</span>             <span style="#0000ff;">catch</span> (<span style="#2b91af;">Exception</span>)</pre>
<pre style="0px;"><span style="#2b91af;">   84</span>             {</pre>
<pre style="0px;"><span style="#2b91af;">   85</span>                 <span style="#008000;">// Add your own error handling</span></pre>
<pre style="0px;"><span style="#2b91af;">   86</span>             }</pre>
</div>
<p>As good developers we always use try-catch, right? Right. Lines 59 and 83-86 handle that. And yes, you need to add error handling.</p>
<p>Line 61 gets a reference to the ListName we have configured in our component from the current SPWeb. Line 62 creates the SPDataSource we need to add to the ads.DataSources. We then start adding the parameters (lines 63-71), and contrary to what the markup code shows, we only add the select parameter. You may want or need to add the other insert, update, and delete parameters as well, depending on wheter or not you want the dataformwebpart to be editable. Of so, follow the selectparameter template.</p>
<p>Lines 73-76 finish configuring the SPDataSource before we add it to the ads.Sources property in line 77.<br />
Remember that strange aggregate string which looked like a collection? Well, as it is only a string, we need to build that string, using the sourceCounter to get a unique string, for each datasource. This is done in line 79 before we finally increment the sourceCounter.</p>
<p>Lastly we need to make this recursive by calling the same function inside itself. We need to change the parameters to make sure we do not get an endless loop. We want all subsites to be aggregated as well, so we call the function with each of the subwebs of the current web:</p>
<div style="white;">
<pre style="0px;"><span style="#2b91af;">   88</span>             <span style="#0000ff;">try</span></pre>
<pre style="0px;"><span style="#2b91af;">   89</span>             {</pre>
<pre style="0px;"><span style="#2b91af;">   90</span>                 <span style="#0000ff;">foreach</span> (<span style="#2b91af;">SPWeb</span> subweb <span style="#0000ff;">in</span> web.Webs)</pre>
<pre style="0px;"><span style="#2b91af;">   91</span>                 {</pre>
<pre style="0px;"><span style="#2b91af;">   92</span>                     getSubWebItems(ads, <span style="#0000ff;">ref</span> sourceCounter, aggregateString, subweb);</pre>
<pre style="0px;"><span style="#2b91af;">   93</span>                     subweb.Dispose();</pre>
<pre style="0px;"><span style="#2b91af;">   94</span>                 }</pre>
<pre style="0px;"><span style="#2b91af;">   95</span></pre>
<pre style="0px;"><span style="#2b91af;">   96</span>             }</pre>
<pre style="0px;"><span style="#2b91af;">   97</span>             <span style="#0000ff;">catch</span> (<span style="#2b91af;">Exception</span>)</pre>
<pre style="0px;"><span style="#2b91af;">   98</span>             {</pre>
<pre style="0px;"><span style="#2b91af;">   99</span>                 <span style="#008000;">// Add your own error handling            </span></pre>
<pre style="0px;"><span style="#2b91af;">  100</span>             }</pre>
<pre style="0px;"><span style="#2b91af;">  101</span>         }</pre>
</div>
<p>Last step of code is to call the getSubWebItems on the OnLoad method, clean up a few things and then add the AggregateDataSource to the DFWP control:</p>
<div style="white;">
<pre style="0px;"><span style="#2b91af;">   46</span>             getSubWebItems(ads, <span style="#0000ff;">ref</span> sourceCounter, aggregateString, web);</pre>
<pre style="0px;"><span style="#2b91af;">   47</span></pre>
<pre style="0px;"><span style="#2b91af;">   48</span>             aggregateString.AppendLine(<span style="#a31515;">"&lt;/concat&gt;"</span>);</pre>
<pre style="0px;"><span style="#2b91af;">   49</span></pre>
<pre style="0px;"><span style="#2b91af;">   50</span>             ads.Aggregate = aggregateString.ToString();</pre>
<pre style="0px;"><span style="#2b91af;">   51</span></pre>
<pre style="0px;"><span style="#2b91af;">   52</span>             m_dfwp.DataSources.Add(ads);</pre>
<pre style="0px;"><span style="#2b91af;">   53</span></pre>
<pre style="0px;"><span style="#2b91af;">   54</span></pre>
<pre style="0px;"><span style="#2b91af;">   55</span>         }</pre>
</div>
<p>Lines 48-50 finishes the aggregate-string which looked like a collection and adds it to the ads object.</p>
<p>Wow! That’s it. Code is done. Pat yourself on the back. Now comes the easier part, getting this to run and working with our DataFormWebPart.</p>
<p>Now it is time to deploy and add our new component to a page. This has been described many times, including in my blog at <a href="http://furuknap.blogspot.com/2008/05/creating-your-own-custom-components-for.html">http://furuknap.blogspot.com/2008/05/creating-your-own-custom-components-for.html</a>. I’ll skip this now and just head on back to SharePoint Designer to put our component to the test.<br />
In SPD, open the MyTestPage.aspx page and add the Assembly and Register tags as described in my blog article. You should be getting intellisense in code view now:</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/07/step-4.png" target="_blank"><img class="size-medium wp-image-17" src="http://sharepointmagazine.net/wp-content/uploads/2008/07/step-4-300x230.png" alt="Screenshot - click to open in new window" width="300" height="230" /></a></p>
<p>Click image to open larger screenshot in new window</p>
<p>Complete your custom ASP.net component tag by finding the id-value of the DataFormWebPart you added earlier and putting it in the DataFormWebPartId field of your tag. Add also the ListName of the list you want to aggregate. And, of course, the runat=”server”:</p>
<blockquote><p>&lt;MyComponents:DynamicAggregateDataSource DataFormWebPartId=&#8221;g_0de093cc_8ba4_4c03_ba5a_b8b7591baf2a&#8221; ListName=&#8221;Articles&#8221; runat=&#8221;server&#8221;/&gt;</p></blockquote>
<p>Save, open in browser, et voilá, your subsites’ articles are getting aggregated like there’s no tomorrow:</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/07/step-5.png" target="_blank"><img class="size-medium wp-image-18" src="http://sharepointmagazine.net/wp-content/uploads/2008/07/step-5-300x232.png" alt="Screenshot - click to open in new window" width="300" height="232" /></a></p>
<p>Click image to open larger screenshot in new window</p>
<p>Now, back to the beauty of this… Give the DataFormWebPart to your designer. Let them make sure this looks exactly as they want it. Sort it, filter it, do what you want, and you will have all the power with a dynamic datasource without the need to constantly update the linked datasource every time you add a new site.</p>
<p>A few things to note:</p>
<p>- <strong>This is not scalable code! </strong>This component traverses your entire site collection for every hit to the page, which is an expensive operation. You would probably want to either implement some kind of caching or limit which pages are using the component. The point is to show how you can manipulate the datasources, not give you production code.</p>
<p>- Remember to add your assembly to the SafeControls of your web.config, as per <a href="http://furuknap.blogspot.com/2008/05/creating-your-own-custom-components-for.html">http://furuknap.blogspot.com/2008/05/creating-your-own-custom-components-for.html</a>. If you don’t you will get a ‘The control type &#8216;youcomponent&#8217; is not allowed on this page. The type is not registered as safe.’ error message.</p>
<p>- Remember to reset IIS when you update and redistribute your assembly. Also, SharePoint designer keeps a local cache of your component’s signature, so that if you add or modify properties and you don’t get intellisense, it may be very likely that the local cache is interfering. To remove the cache you need to go to C:\Documents and Settings\[YourUserName]\Local Settings\Application Data\Microsoft\WebsiteCache and clear out items. Don’t worry, you can safely delete everything in this folder, it will get recreated once you reopen a site. Remember to close SPD before you clear it’s cache.</p>
<p>Hey, we’re at the end of the article. Don’t forget to post comments if you have problems or if you just want to give feedback. I’ve also uploaded the completed solution as a zipped Vsual Studio solution for you to use in case you got something wrong.</p>
<p>Attached files for your convenience:</p>
<p>Beginning solution:<br />
<a href="http://sharepointmagazine.net/wp-content/uploads/2008/07/dynamicaggregatedatasource_begin1.zip">dynamicaggregatedatasource_begin1</a></p>
<p>End solution:<br />
<a href="http://sharepointmagazine.net/wp-content/uploads/2008/07/dynamicaggregatedatasource_end1.zip">dynamicaggregatedatasource_end1</a></p>
]]></content:encoded>
			<wfw:commentRss>http://sharepointmagazine.net/technical/development/populating-data-sources-in-code/feed</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
	</channel>
</rss>
