<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Marcin On ASP.NET : ASP.NET Dynamic Data</title><link>http://blogs.msdn.com/marcinon/archive/tags/ASP.NET+Dynamic+Data/default.aspx</link><description>Tags: ASP.NET Dynamic Data</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>Dynamic Data samples: Extending the FilterRepeater</title><link>http://blogs.msdn.com/marcinon/archive/2008/05/29/dynamic-data-samples-extending-the-filterrepeater.aspx</link><pubDate>Fri, 30 May 2008 04:12:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8561002</guid><dc:creator>marcind</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/marcinon/comments/8561002.aspx</comments><wfw:commentRss>http://blogs.msdn.com/marcinon/commentrss.aspx?PostID=8561002</wfw:commentRss><description>&lt;P&gt;&lt;STRONG&gt;6/25 Update:&lt;/STRONG&gt; This sample has become part of the &lt;A class="" href="http://www.codeplex.com/aspnet/Release/ProjectReleases.aspx?ReleaseId=14475" mce_href="http://www.codeplex.com/aspnet/Release/ProjectReleases.aspx?ReleaseId=14475"&gt;&lt;FONT color=#555555&gt;Dynamic Data Futures&lt;/FONT&gt;&lt;/A&gt; project on codeplex. You can still use this code but you should check out the Futures project as it contains a lot more. The key conecpts are the same, though some names or APIs might have changed.&lt;/P&gt;
&lt;P&gt;&lt;I&gt;Note&lt;/I&gt;: This post is part of a series, see the list of other &lt;A href="http://blogs.msdn.com/marcinon/archive/2008/05/22/dynamic-data-samples.aspx" mce_href="http://blogs.msdn.com/marcinon/archive/2008/05/22/dynamic-data-samples.aspx"&gt;Dynamic Data samples&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;The FilterRepeater is a control in Dynamic Data that is responsible for automatically emitting a list of filter controls that can be used to filter data rows displayed for a table. The filters work by providing a list of where parameters to the data source for each supported column type. By default Dynamic Data supports foreign key and boolean columns and renders them using a DropDownList. This and upcoming posts will talk about ways in which you can add filtering for other column types and how to modify the filter UI.&lt;/P&gt;
&lt;P&gt;All of the code referenced here is part of the &lt;A href="http://blogs.msdn.com/marcinon/attachment/8561002.ashx" mce_href="http://blogs.msdn.com/marcinon/attachment/8561002.ashx"&gt;AdvancedFilterRepeaterSample solution&lt;/A&gt;.To run the sample open the solution in Visual Studio 2008 SP1 Beta or later and run AdvancedFilterRepeaterSite (note: it might not be the default project for the solution, so right click on Default.aspx inside the project and choose View in Browser). Navigate to the list page for the Products table where you can experiment with some new filtering options. For example, type "con" into the Categories filter. You should see an AJAX autocomplete drop-down instead of the default drop-down list.&lt;BR&gt;&lt;/P&gt;
&lt;H3&gt;Introduction to FilterRepeater&lt;/H3&gt;
&lt;P&gt;FilterRepeater is a specialized Repeater control that will automatically bind to a collection of filterable columns for the given request's table: if a request comes in for /Products/List.aspx, it will bind to the columns in the Products table. The table is chosen based on the route that the request matched, or it can be overridden by setting the TableName and ContextTypeName properties.&lt;/P&gt;
&lt;P&gt;To work correctly FilterRepeater expects its ItemTemplate to have correct content. Specifically, it requires a control with a known ID ("DynamicFilter" by default) that derives from FilterUserControlBase. When databinding occurs FilterRepeater initializes an instance of the filter control with information about the column to filter.&lt;/P&gt;
&lt;P&gt;Below is a snippet of the code that ships in the default Dynamic Data templates:&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(163,21,21)"&gt;asp:FilterRepeater &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;ID&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;=&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt;FilterRepeater&lt;/SPAN&gt;" &lt;SPAN style="COLOR: red"&gt;runat&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;=&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt;server&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt;&amp;gt;&lt;BR&gt;    &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(163,21,21)"&gt;ItemTemplate&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;&lt;BR&gt;        &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(163,21,21)"&gt;asp:Label &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;runat&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;=&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt;server&lt;/SPAN&gt;" &lt;SPAN style="COLOR: red"&gt;Text&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;=&lt;/SPAN&gt;'&lt;SPAN style="COLOR: blue"&gt;&amp;lt;&lt;/SPAN&gt;%# &lt;SPAN style="COLOR: red"&gt;Eval&lt;/SPAN&gt;("&lt;SPAN style="COLOR: blue"&gt;DisplayName&lt;/SPAN&gt;") %&lt;SPAN style="COLOR: blue"&gt;&amp;gt;&lt;/SPAN&gt;' /&amp;gt;&lt;BR&gt;        &lt;SPAN style="COLOR: blue"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(163,21,21)"&gt;asp:DynamicFilter &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;runat&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;=&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt;server&lt;/SPAN&gt;" &lt;SPAN style="COLOR: red"&gt;ID&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;=&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt;DynamicFilter&lt;/SPAN&gt;"&lt;BR&gt;             &lt;SPAN style="COLOR: red"&gt;OnSelectedIndexChanged&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;=&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt;OnFilterSelectedIndexChanged&lt;/SPAN&gt;" &lt;SPAN style="COLOR: blue"&gt;/&amp;gt;&lt;BR&gt;    &amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(163,21,21)"&gt;ItemTemplate&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;&lt;BR&gt;    &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(163,21,21)"&gt;FooterTemplate&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(163,21,21)"&gt;br &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;/&amp;gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(163,21,21)"&gt;br &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;/&amp;gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(163,21,21)"&gt;FooterTemplate&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;&lt;BR&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(163,21,21)"&gt;asp:FilterRepeater&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;&lt;/SPAN&gt; &lt;/PRE&gt;
&lt;H3&gt;FilterRepeater version 2.0 (well, more like 1.1 really)&lt;/H3&gt;
&lt;P&gt;The DynamicDataExtensions project contains a simple extension of FilterRepeater called AdvancedFilterRepeater. It is not really that advanced (I started with that name and never bothered to change it) as it overrides only one method: GetFilteredColumns. This method is what is used as the databinding source. Below is a slightly simplified source of how it is implemented:&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;public class &lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;AdvancedFilterRepeater &lt;/SPAN&gt;: &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;FilterRepeater &lt;/SPAN&gt;{&lt;BR&gt;    &lt;SPAN style="COLOR: blue"&gt;protected override &lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;IEnumerable&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;MetaColumn&lt;/SPAN&gt;&amp;gt; GetFilteredColumns() {&lt;SPAN style="COLOR: green"&gt;&lt;BR&gt;        &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;return &lt;/SPAN&gt;Table.Columns.Where(c =&amp;gt; IsFilterableColumn(c)).OrderBy(column =&amp;gt; column, &lt;SPAN style="COLOR: blue"&gt;new &lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;FilterOrderComparer&lt;/SPAN&gt;());&lt;BR&gt;    }&lt;BR&gt;&lt;BR&gt;    &lt;SPAN style="COLOR: blue"&gt;protected bool &lt;/SPAN&gt;IsFilterableColumn(&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;MetaColumn &lt;/SPAN&gt;column) {&lt;BR&gt;        &lt;SPAN style="COLOR: blue"&gt;if &lt;/SPAN&gt;(column.IsCustomProperty) &lt;SPAN style="COLOR: blue"&gt;return false&lt;/SPAN&gt;;&lt;BR&gt;&lt;BR&gt;        &lt;SPAN style="COLOR: blue"&gt;var &lt;/SPAN&gt;filterAttribute = column.Attributes.OfType&amp;lt;&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;FilterAttribute&lt;/SPAN&gt;&amp;gt;().FirstOrDefault();&lt;BR&gt;        &lt;SPAN style="COLOR: blue"&gt;if &lt;/SPAN&gt;(filterAttribute != &lt;SPAN style="COLOR: blue"&gt;null&lt;/SPAN&gt;) &lt;SPAN style="COLOR: blue"&gt;return &lt;/SPAN&gt;filterAttribute.Enabled;&lt;BR&gt;&lt;BR&gt;        &lt;SPAN style="COLOR: blue"&gt;if &lt;/SPAN&gt;(column &lt;SPAN style="COLOR: blue"&gt;is &lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;MetaForeignKeyColumn&lt;/SPAN&gt;) &lt;SPAN style="COLOR: blue"&gt;return true&lt;/SPAN&gt;;&lt;BR&gt;&lt;BR&gt;        &lt;SPAN style="COLOR: blue"&gt;if &lt;/SPAN&gt;(column.ColumnType == &lt;SPAN style="COLOR: blue"&gt;typeof&lt;/SPAN&gt;(&lt;SPAN style="COLOR: blue"&gt;bool&lt;/SPAN&gt;)) &lt;SPAN style="COLOR: blue"&gt;return true&lt;/SPAN&gt;;&lt;BR&gt;&lt;BR&gt;        &lt;SPAN style="COLOR: blue"&gt;return false&lt;/SPAN&gt;;&lt;BR&gt;    }&lt;BR&gt;&lt;BR&gt;    &lt;SPAN style="COLOR: blue"&gt;private class &lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;FilterOrderComparer &lt;/SPAN&gt;: &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;IComparer&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;MetaColumn&lt;/SPAN&gt;&amp;gt; {&lt;BR&gt;        &lt;SPAN style="COLOR: green"&gt;// implementation omitted for brevity&lt;/SPAN&gt;&lt;BR&gt;    }&lt;BR&gt;}&lt;/PRE&gt;
&lt;P&gt;The Table property is automatically populated with the right MetaTable instance based on the table resolution rules mentioned in the previous section. The rest is a simple LINQ extension method query and some boolean logic to choose the filterable columns. The only way this deviates from the default process is the addition and handling of FilterAttribute, which is a new attribute written for the purpose of this sample. It combines the roles of UIHintAttribute and ScaffoldColumnAttribute from Dynamic Data field templates and should be applied to columns in an analogous manner. Here's the full signature:&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;public sealed class &lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;FilterAttribute &lt;/SPAN&gt;: &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Attribute &lt;/SPAN&gt;{&lt;BR&gt;    &lt;SPAN style="COLOR: blue"&gt;public string &lt;/SPAN&gt;FilterControl { &lt;SPAN style="COLOR: blue"&gt;get&lt;/SPAN&gt;; &lt;SPAN style="COLOR: blue"&gt;set&lt;/SPAN&gt;; }&lt;SPAN style="COLOR: green"&gt;&lt;BR&gt;    &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;public int &lt;/SPAN&gt;Order { &lt;SPAN style="COLOR: blue"&gt;get&lt;/SPAN&gt;; &lt;SPAN style="COLOR: blue"&gt;set&lt;/SPAN&gt;; }&lt;BR&gt;    &lt;SPAN style="COLOR: blue"&gt;public bool &lt;/SPAN&gt;Enabled { &lt;SPAN style="COLOR: blue"&gt;get&lt;/SPAN&gt;; &lt;SPAN style="COLOR: blue"&gt;set&lt;/SPAN&gt;; }&lt;BR&gt;}&lt;/PRE&gt;
&lt;P&gt;The FilterControl property lets you specify which user control to use as the filter while the Enabled property lets you omit a given column's filter in the AdvancedFilterRepeater. The Order property let's you specify an ordering weight.&lt;/P&gt;
&lt;H3&gt;Specifying custom filter controls&lt;/H3&gt;
&lt;P&gt;The reason why the implementation of AdvancedFilterRepeater is so simple is because a lot of work is done in two other components:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;FilterFactory is the equivalent of FieldTemplateFactory for filters. It uses the information in a column's FilterAttribute to determine which filter user control to instantiate for the column. It takes the value of the attribute's FilterControl property and looks for a user control located at ~\DynamicData\Filters\{FilterControl}.ascx. If a filter attribute is not specified ~\DynamicData\Filters\Default.ascx is used, which is identical to the FilterUserControl.ascx that is part of the default Dynamic Data template. &lt;/LI&gt;
&lt;LI&gt;DelegatingFilter is a control that derives from FilterUserControlBase (which means that it is itself a filter) and delegates the filtering behavior to another filter control. It uses the FilterFactory class to determine which control to use. &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;In order to take advantage of AdvancedFilterRepeater and DelegatingFilter you need to replace the existing FilterRepeater in your List.aspx page template with the following code:&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(163,21,21)"&gt;asp:AdvancedFilterRepeater &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;id&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;=&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt;AdvancedFilterRepeater&lt;/SPAN&gt;" &lt;SPAN style="COLOR: red"&gt;runat&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;=&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt;server&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt;&amp;gt;&lt;BR&gt;    &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(163,21,21)"&gt;HeaderTemplate&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;&lt;BR&gt;        &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(163,21,21)"&gt;table&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;&lt;BR&gt;    &amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(163,21,21)"&gt;HeaderTemplate&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;&lt;BR&gt;    &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(163,21,21)"&gt;ItemTemplate&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;&lt;BR&gt;        &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(163,21,21)"&gt;tr&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;&lt;BR&gt;            &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(163,21,21)"&gt;td &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;valign&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;=&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt;top&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt;&amp;gt;&amp;lt;&lt;/SPAN&gt;%# &lt;SPAN style="COLOR: red"&gt;Eval&lt;/SPAN&gt;("&lt;SPAN style="COLOR: blue"&gt;DisplayName&lt;/SPAN&gt;") %&lt;SPAN style="COLOR: blue"&gt;&amp;gt;&lt;/SPAN&gt;:&lt;SPAN style="COLOR: blue"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(163,21,21)"&gt;td&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt; &lt;BR&gt;            &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(163,21,21)"&gt;td&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(163,21,21)"&gt;asp:DelegatingFilter &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;runat&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;=&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt;server&lt;/SPAN&gt;" &lt;SPAN style="COLOR: red"&gt;ID&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;=&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt;DynamicFilter&lt;/SPAN&gt;"&lt;BR&gt;                     &lt;SPAN style="COLOR: red"&gt;OnSelectionChanged&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;=&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt;OnFilterSelectionChanged&lt;/SPAN&gt;" &lt;SPAN style="COLOR: blue"&gt;/&amp;gt;&lt;BR&gt;        &amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(163,21,21)"&gt;tr&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;&lt;BR&gt;    &amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(163,21,21)"&gt;ItemTemplate&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;&lt;BR&gt;    &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(163,21,21)"&gt;FooterTemplate&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;&lt;BR&gt;        &amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(163,21,21)"&gt;table&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;&lt;BR&gt;    &amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(163,21,21)"&gt;FooterTemplate&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;&lt;BR&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(163,21,21)"&gt;asp:AdvancedFilterRepeater&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;
&lt;P&gt;This template is pretty similar to the default one seen earlier in this post except it wraps each filtered column in a table row for cleaner formatting (yes, using tables for layout is wrong but this post is not about layouts). And of course DynamicFilter has been replaced with DelegatingFilter.&lt;/P&gt;
&lt;P&gt;To take advantage of the custom filter controls included in the sample such as autocomplete filter or cascading filter you need to annotate your data model with FilterAttribute. Here's a snippet of how it is done in the sample:&lt;/P&gt;&lt;PRE class=code&gt;[&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;MetadataType&lt;/SPAN&gt;(&lt;SPAN style="COLOR: blue"&gt;typeof&lt;/SPAN&gt;(&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Product_MD&lt;/SPAN&gt;))]&lt;BR&gt;&lt;SPAN style="COLOR: blue"&gt;public partial class &lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Product &lt;/SPAN&gt;{ }&lt;BR&gt;&lt;BR&gt;&lt;SPAN style="COLOR: blue"&gt;public class &lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Product_MD &lt;/SPAN&gt;{&lt;BR&gt;    &lt;SPAN style="COLOR: green"&gt;// Display the Category and Supplier filters using the Autocomplete.ascx filter control&lt;BR&gt;    &lt;/SPAN&gt;[&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Filter&lt;/SPAN&gt;(FilterControl = &lt;SPAN style="COLOR: rgb(163,21,21)"&gt;"Autocomplete"&lt;/SPAN&gt;)]&lt;BR&gt;    &lt;SPAN style="COLOR: blue"&gt;public object &lt;/SPAN&gt;Category { &lt;SPAN style="COLOR: blue"&gt;get&lt;/SPAN&gt;; &lt;SPAN style="COLOR: blue"&gt;set&lt;/SPAN&gt;; }&lt;BR&gt;    [&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Filter&lt;/SPAN&gt;(FilterControl = &lt;SPAN style="COLOR: rgb(163,21,21)"&gt;"Autocomplete"&lt;/SPAN&gt;)]&lt;BR&gt;    &lt;SPAN style="COLOR: blue"&gt;public object &lt;/SPAN&gt;Supplier { &lt;SPAN style="COLOR: blue"&gt;get&lt;/SPAN&gt;; &lt;SPAN style="COLOR: blue"&gt;set&lt;/SPAN&gt;; }&lt;BR&gt;&lt;BR&gt;    &lt;SPAN style="COLOR: green"&gt;// Display the Discontinued filter using the BooleanRadio.ascx filter control&lt;BR&gt;    // Make sure the Discontinued filter is displayed first&lt;BR&gt;    &lt;/SPAN&gt;[&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Filter&lt;/SPAN&gt;(FilterControl = &lt;SPAN style="COLOR: rgb(163,21,21)"&gt;"BooleanRadio"&lt;/SPAN&gt;, Order = 1)]&lt;BR&gt;    &lt;SPAN style="COLOR: blue"&gt;public object &lt;/SPAN&gt;Discontinued { &lt;SPAN style="COLOR: blue"&gt;get&lt;/SPAN&gt;; &lt;SPAN style="COLOR: blue"&gt;set&lt;/SPAN&gt;; }&lt;BR&gt;&lt;BR&gt;    &lt;SPAN style="COLOR: green"&gt;// Display the UnitsInStock filter using Integer.ascx filter control&lt;BR&gt;    &lt;/SPAN&gt;[&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Filter&lt;/SPAN&gt;(FilterControl = &lt;SPAN style="COLOR: rgb(163,21,21)"&gt;"Integer"&lt;/SPAN&gt;)]&lt;BR&gt;    &lt;SPAN style="COLOR: blue"&gt;public object &lt;/SPAN&gt;UnitsInStock { &lt;SPAN style="COLOR: blue"&gt;get&lt;/SPAN&gt;; &lt;SPAN style="COLOR: blue"&gt;set&lt;/SPAN&gt;; }&lt;BR&gt;}&lt;/PRE&gt;
&lt;P&gt;When you run the application and view the list page for the Products table the appropriate filters get inserted automatically. Future posts will discuss how the more advanced filters are implemented.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8561002" width="1" height="1"&gt;</description><enclosure url="http://blogs.msdn.com/marcinon/attachment/8561002.ashx" length="1280408" type="application/x-zip-compressed" /><category domain="http://blogs.msdn.com/marcinon/archive/tags/ASP.NET+Dynamic+Data/default.aspx">ASP.NET Dynamic Data</category><category domain="http://blogs.msdn.com/marcinon/archive/tags/samples/default.aspx">samples</category></item><item><title>Dynamic Data samples: Custom metadata providers</title><link>http://blogs.msdn.com/marcinon/archive/2008/05/22/dynamic-data-samples-custom-metadata-providers.aspx</link><pubDate>Fri, 23 May 2008 02:35:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8535066</guid><dc:creator>marcind</dc:creator><slash:comments>5</slash:comments><comments>http://blogs.msdn.com/marcinon/comments/8535066.aspx</comments><wfw:commentRss>http://blogs.msdn.com/marcinon/commentrss.aspx?PostID=8535066</wfw:commentRss><description>&lt;P&gt;&lt;STRONG&gt;6/25 Update:&lt;/STRONG&gt; This sample has become part of the &lt;A class="" href="http://www.codeplex.com/aspnet/Release/ProjectReleases.aspx?ReleaseId=14475" mce_href="http://www.codeplex.com/aspnet/Release/ProjectReleases.aspx?ReleaseId=14475"&gt;Dynamic Data Futures&lt;/A&gt; project on codeplex. You can still use this code but you should check out the Futures project as it contains a lot more. The key conecpts are the same, though some names or APIs might have changed.&lt;/P&gt;
&lt;P&gt;&lt;I&gt;Note&lt;/I&gt;: This post is part of a series, see the list of other &lt;A href="http://blogs.msdn.com/marcinon/archive/2008/05/22/dynamic-data-samples.aspx" mce_href="http://blogs.msdn.com/marcinon/archive/2008/05/22/dynamic-data-samples.aspx"&gt;Dynamic Data samples&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;A while back I posted some &lt;A href="http://blogs.msdn.com/marcinon/archive/2007/12/10/adding-custom-metadata-providers-in-asp-net-3-5-extensions-preview.aspx" mce_href="http://blogs.msdn.com/marcinon/archive/2007/12/10/adding-custom-metadata-providers-in-asp-net-3-5-extensions-preview.aspx"&gt;sample code for adding custom metadata providers&lt;/A&gt;. Since then much has changed in the Dynamic Data runtime and it is time to post an updated version. This sample illustrates how to write a custom metadata provider that allows you to programmatically add metadata attributes to an in-memory store before you register your model with the Dynamic Data runtime in Global.asax.&lt;/P&gt;
&lt;P&gt;This sample should work with the &lt;A href="http://code.msdn.microsoft.com/dynamicdata" mce_href="http://code.msdn.microsoft.com/dynamicdata"&gt;latest preview release of Dynamic Data&lt;/A&gt;.&lt;BR&gt;&lt;/P&gt;
&lt;H3&gt;Running the sample&lt;/H3&gt;
&lt;P&gt;Download the &lt;A class="" href="http://blogs.msdn.com/marcinon/attachment/8535066.ashx" mce_href="http://blogs.msdn.com/marcinon/attachment/8535066.ashx"&gt;metadata provider sample&lt;/A&gt; solution, extract to your preferred location, and open in Visual Studio 2008 SP1. The solution contains two projects: a sample website and a small library project that contains the metadata provider code.&lt;/P&gt;
&lt;P&gt;Run the included website and go the Products list page. Once there hit Edit on any of the rows. You will be taken to a details view for the row you are editing. Change the UnitsInStock field to a negative value and move out of the field: a range validation error appears. Go back to the same field, clear it, and move out again: a required validation error appears.&lt;/P&gt;
&lt;H3&gt;How it works&lt;/H3&gt;
&lt;P&gt;The website scaffolds a small subset of the Northwind sample database. The UnitsInStock column on the Product table is decorated with two attributes: RequiredAttribute and RangeAttribute. However, the unique thing here is that each attribute is coming from a different source.&lt;/P&gt;
&lt;P&gt;The RequiredAttribute is declared in the default Dynamic Data way using a metadata proxy class:&lt;/P&gt;&lt;PRE class=code&gt;[&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;MetadataType&lt;/SPAN&gt;(&lt;SPAN style="COLOR: blue"&gt;typeof&lt;/SPAN&gt;(&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Product_MD&lt;/SPAN&gt;))]&lt;BR&gt;&lt;SPAN style="COLOR: blue"&gt;public partial class &lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Product &lt;/SPAN&gt;{&lt;BR&gt;&lt;BR&gt;    &lt;SPAN style="COLOR: blue"&gt;private class &lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Product_MD &lt;/SPAN&gt;{&lt;BR&gt;        [&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Required&lt;/SPAN&gt;(ErrorMessage=&lt;SPAN style="COLOR: rgb(163,21,21)"&gt;"This field is required [from MetadataType]"&lt;/SPAN&gt;)]&lt;BR&gt;        &lt;SPAN style="COLOR: blue"&gt;public object &lt;/SPAN&gt;UnitsInStock { &lt;SPAN style="COLOR: blue"&gt;get&lt;/SPAN&gt;; &lt;SPAN style="COLOR: blue"&gt;set&lt;/SPAN&gt;; }&lt;BR&gt;    }&lt;BR&gt;}&lt;/PRE&gt;
&lt;P&gt;The RangeAttribute is added to the InMemoryMetadataManager class in Global.asax:&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;InMemoryMetadataManager&lt;/SPAN&gt;.AddColumnAttributes&amp;lt;&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Product&lt;/SPAN&gt;&amp;gt;(p =&amp;gt; p.UnitsInStock,&lt;BR&gt;    &lt;SPAN style="COLOR: blue"&gt;new &lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;RangeAttribute&lt;/SPAN&gt;(0, 1000) { &lt;BR&gt;        ErrorMessage = &lt;SPAN style="COLOR: rgb(163,21,21)"&gt;"This field must be between {1} and {2} [from InMemeroyMetadataManager]." &lt;/SPAN&gt;}&lt;BR&gt;);&lt;/PRE&gt;
&lt;P&gt;The AddColumnAttributes function shown here has a way to strongly type the property references (as opposed to writing something like AddColumnAttributes("UnitsInStock", ...)) using a simple lambda expression. This provides for some nice IntelliSense support that would not be available if you were referring to properties using simple strings.&lt;/P&gt;
&lt;P&gt;In order to have the Dynamic Data runtime pick up the metadata attributes added to InMemoryMetadataManager you need to modify your model registration call in Global.asax:&lt;/P&gt;&lt;PRE class=code&gt;model.RegisterContext(&lt;SPAN style="COLOR: blue"&gt;typeof&lt;/SPAN&gt;(&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;NorthwindDataContext&lt;/SPAN&gt;), &lt;SPAN style="COLOR: blue"&gt;new &lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;ContextConfiguration&lt;/SPAN&gt;() {&lt;BR&gt;    ScaffoldAllTables = &lt;SPAN style="COLOR: blue"&gt;true&lt;/SPAN&gt;,&lt;BR&gt;    MetadataProviderFactory =&lt;BR&gt;        (type =&amp;gt; &lt;SPAN style="COLOR: blue"&gt;new &lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;InMemoryMetadataTypeDescriptionProvider&lt;/SPAN&gt;(type, &lt;SPAN style="COLOR: blue"&gt;new &lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;AssociatedMetadataTypeTypeDescriptionProvider&lt;/SPAN&gt;(type)))&lt;BR&gt;});&lt;/PRE&gt;
&lt;P&gt;The MetadataProviderFactory&amp;nbsp;property of ContextConfiguration lets you specify a metadata provider factory method that is used by the Dynamic Data runtime to obtain an instance of a &lt;A href="http://msdn.microsoft.com/en-us/library/system.componentmodel.typedescriptionprovider.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.componentmodel.typedescriptionprovider.aspx"&gt;TypeDescriptionProvider&lt;/A&gt; that acts as the source of metadata attributes for a given table (type). The sample above also illustrates TypeDescriptionProvider chaining, which is what supports the fact that the table receives metadata from two sources: the InMemory provider adds its metadata to the results returned by the AssociatedMetadataType provider and returns a combined collection.&lt;/P&gt;
&lt;H3&gt;Truly dynamic metadata&lt;/H3&gt;
&lt;P&gt;At this point it is tempting to consider a dynamic metadata provider that would let you add, remove, and modify attributes throughout the lifetime of the application and not just during the application's startup phase. For example, you could imagine having&amp;nbsp;some sort of administrative interface that would let you turn on and off whether a field is required or modify its description, even after the model has already been registered.&lt;/P&gt;
&lt;P&gt;While it would seem that such a scenario would require minimal changes to the InMemoryMetadataManager class there is one detail about Dynamic Data that makes this a lot more complicated: the current Dynamic Data runtime fetches the metadata upon model registration and then caches it inernally for the lifetime of the app domain. This means that any changes that you make to the metadata through InMemoryMetadataManager after the model has been registered will be ignored.&lt;/P&gt;
&lt;P&gt;This is a limitation of Dynamic Data that we will address in future versions. For the time being the only way to get around this would be to &lt;A href="http://msdn.microsoft.com/en-us/library/system.web.httpruntime.unloadappdomain.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.web.httpruntime.unloadappdomain.aspx"&gt;unload the app domain&lt;/A&gt;. However, this is means that you will need to find a place (such as a database) to store the new metadata while the app restarts.&lt;/P&gt;
&lt;H3&gt;What about the XML metadata?&lt;/H3&gt;
&lt;P&gt;My old custom metadata provider sample had an implementation of an XML-based metadata provider but the current one does not. The reason for this is that since the December CTP we have added support for even more attributes and some of the attributes have become a lot more complex. Because much of the old sample had to do with deserializing CLR attributes from an XML representation instead of anything specific to Dynamic Data I decided not to develop the old XML provider any further. However, if somebody ever wrote the appropriate XML parsing code it could easily be used to populate the InMemoryMetadataManager with the right values, essentially resulting in an XML metadata provider. Just remember about the domain unloading mentioned earlier.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8535066" width="1" height="1"&gt;</description><enclosure url="http://blogs.msdn.com/marcinon/attachment/8535066.ashx" length="869249" type="application/x-zip-compressed" /><category domain="http://blogs.msdn.com/marcinon/archive/tags/metadata/default.aspx">metadata</category><category domain="http://blogs.msdn.com/marcinon/archive/tags/ASP.NET+Dynamic+Data/default.aspx">ASP.NET Dynamic Data</category><category domain="http://blogs.msdn.com/marcinon/archive/tags/samples/default.aspx">samples</category></item><item><title>Dynamic Data samples</title><link>http://blogs.msdn.com/marcinon/archive/2008/05/22/dynamic-data-samples.aspx</link><pubDate>Thu, 22 May 2008 20:10:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8532588</guid><dc:creator>marcind</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/marcinon/comments/8532588.aspx</comments><wfw:commentRss>http://blogs.msdn.com/marcinon/commentrss.aspx?PostID=8532588</wfw:commentRss><description>&lt;P&gt;In breaks between writing the Dynamic Data runtime I also write samples illustrating the various ways Dynamic Data can be extended and customized, often in response to questions on the Dynamic Data forum. In a series of upcoming posts I will share these samples with you as well as discuss how the various extensions work with the Dynamic Data runtime. This post is meant to serve as a list of the samples:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A class="" href="http://blogs.msdn.com/marcinon/archive/2008/05/22/dynamic-data-samples-custom-metadata-providers.aspx" mce_href="http://blogs.msdn.com/marcinon/archive/2008/05/22/dynamic-data-samples-custom-metadata-providers.aspx"&gt;Custom metadata providers&lt;/A&gt; &lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://blogs.msdn.com/marcinon/archive/2008/05/29/dynamic-data-samples-extending-the-filterrepeater.aspx" mce_href="http://blogs.msdn.com/marcinon/archive/2008/05/29/dynamic-data-samples-extending-the-filterrepeater.aspx"&gt;Extending the FilterRepeater&lt;/A&gt; &lt;B&gt;{5/29 new}&lt;/B&gt; &lt;/LI&gt;
&lt;LI&gt;Autocomplete filter&lt;/LI&gt;
&lt;LI&gt;Cascading drop-down filter&lt;/LI&gt;
&lt;LI&gt;Declaring filter ordering&lt;/LI&gt;
&lt;LI&gt;.... &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;The list will be updated with links as samples become available.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8532588" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/marcinon/archive/tags/ASP.NET+Dynamic+Data/default.aspx">ASP.NET Dynamic Data</category><category domain="http://blogs.msdn.com/marcinon/archive/tags/samples/default.aspx">samples</category></item><item><title>5/20 Dynamic Data Preview posted to Code Gallery</title><link>http://blogs.msdn.com/marcinon/archive/2008/05/21/5-20-dynamic-data-preview-posted-to-code-gallery.aspx</link><pubDate>Wed, 21 May 2008 20:56:36 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8528958</guid><dc:creator>marcind</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/marcinon/comments/8528958.aspx</comments><wfw:commentRss>http://blogs.msdn.com/marcinon/commentrss.aspx?PostID=8528958</wfw:commentRss><description>&lt;p&gt;We have posted the latest &lt;a href="http://code.msdn.microsoft.com/dynamicdata/"&gt;Dynamic Data Preview&lt;/a&gt; bits to Code Gallery. You can get them &lt;a href="http://code.msdn.microsoft.com/dynamicdata/Release/ProjectReleases.aspx?ReleaseId=1039"&gt;here&lt;/a&gt;. Note that you will need &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=CF99C752-1391-4BC3-BABC-86BC0B9E8E5A&amp;amp;displaylang=en"&gt;Visual Studio 2008 SP1 Beta&lt;/a&gt; and/or &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=8C36ACA4-E947-4760-9B05-93CAC04C6F87&amp;amp;displaylang=en"&gt;.NET Framework SP1 Beta&lt;/a&gt; installed to run everything.&lt;/p&gt;  &lt;p&gt;See &lt;a href="http://forums.asp.net/t/1264480.aspx"&gt;this ASP.NET forum post&lt;/a&gt; about what has changed.&lt;/p&gt;  &lt;p&gt;In other news, I will soon be posting a collection of samples that illustrate a number of extension hooks. Stay tuned ...&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8528958" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/marcinon/archive/tags/ASP.NET+Dynamic+Data/default.aspx">ASP.NET Dynamic Data</category></item><item><title>Project templates just got bigger</title><link>http://blogs.msdn.com/marcinon/archive/2008/02/27/project-templates-just-got-bigger.aspx</link><pubDate>Thu, 28 Feb 2008 05:10:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:7898031</guid><dc:creator>marcind</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/marcinon/comments/7898031.aspx</comments><wfw:commentRss>http://blogs.msdn.com/marcinon/commentrss.aspx?PostID=7898031</wfw:commentRss><description>&lt;P mce_keep="true"&gt;One of the new things we are working on in ASP.NET is not directly connected to the new and improved features but rather to how we deliver them. Instead of packing all the functionality into binaries and DLLs, Dynamic Data "implements" a lot of what it provides in project templates. This is a pretty novel concept for ASP.NET with unique challenges yet some very exciting possibilities. Want to know more? Well, read on...&lt;/P&gt;
&lt;H3&gt;Your everyday basic project template&lt;/H3&gt;
&lt;P&gt;&lt;IMG title="Simple WebSite" style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; MARGIN: 0px 10px 0px 0px; WIDTH: 282px; HEIGHT: 166px; BORDER-RIGHT-WIDTH: 0px" height=166 alt="Simple WebSite" src="http://blogs.msdn.com/blogfiles/marcinon/WindowsLiveWriter/Projecttemplatesjustgotbigger_103D3/SimpleWebSite_5.jpg" width=282 align=left border=0 mce_src="http://blogs.msdn.com/blogfiles/marcinon/WindowsLiveWriter/Projecttemplatesjustgotbigger_103D3/SimpleWebSite_5.jpg"&gt; Most project templates you find in a default installation of Visual Studio (at least under the Web category) are very immature, little things. I do not mean to say they are useless. They certainly have a lot of potential... but you have to nurture them until they can develop into strong, functional applications, web sites, and utilities. Without any encouragement they pretty much do nothing. So I guess they might be a bit useless. Have a look here to the left.&lt;/P&gt;
&lt;P&gt;There is nothing more here than a simple &lt;EM&gt;web.config&lt;/EM&gt; file and a blank WebForm. Not even a friendly "Hello world". Instead, when you run this site all you see is a clean, white page. Essentially, this is an &lt;A href="http://en.wikipedia.org/wiki/Altricial"&gt;altricial&lt;/A&gt; creature in the Project kingdom.&amp;nbsp; Now, if you wanted this baby beast to do something - like... oh, I don't know... display and edit some data - you would have to: add database connections, create data models, drop in controls, specify tables, choose columns, enable flags, hook up events. And you would have to do all this for each table of data you are interested in. Quite a lot of work, if you ask me. And things get even more complicated if you want to add fully-editable and filterable relationships and other goodies.&lt;/P&gt;
&lt;H3&gt;A beefed up template&lt;/H3&gt;
&lt;H3&gt;&lt;/H3&gt;
&lt;P&gt;So we decided to make things a lot easier. And that is how, quite &lt;A href="http://en.wikipedia.org/wiki/Precocial"&gt;precocially&lt;/A&gt;, ASP.Net Dynamic Data was born. If you want to see how quickly you can get a working site running, see this excellent &lt;A title="Dynamic Data screen cast" href="http://blogs.msdn.com/davidebb/archive/2007/12/12/dynamic-data-screencast-is-now-available.aspx"&gt;screencast by David Ebbo&lt;/A&gt;.&lt;/P&gt;&lt;IMG style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; MARGIN: 0px 0px 0px 10px; BORDER-RIGHT-WIDTH: 0px" height=553 alt="Dynamic Data Dec'07 CTP WebSite" src="http://blogs.msdn.com/blogfiles/marcinon/WindowsLiveWriter/Projecttemplatesjustgotbigger_103D3/DynDataProject_3.gif" width=282 align=right border=0&gt; 
&lt;P&gt;The idea behind Dynamic Data is to get you up and running with a fully usable app in minutes. To achieve this goal, however, we had to depart from the tradition of providing only the simplest application skeleton.&lt;/P&gt;
&lt;P&gt;Observe to your right: this fine specimen is the default Dynamic Data project template that shipped as part of the December 2007 &lt;A title="ASP.NET 3.5 Extensions Preview site" href="http://asp.net/downloads/3.5-extensions"&gt;ASP.NET 3.5 Extensions Preview&lt;/A&gt;. All of these files (and a few more under the collapsed &lt;EM&gt;Images&lt;/EM&gt; folder) are what you get when you create a new Dynamic Data project. While the exact composition of this template has changed significantly over the last few months (e.g. the folder structure is different, we favor &lt;EM&gt;Global.asax&lt;/EM&gt; instead of &lt;EM&gt;web.config&lt;/EM&gt;, and all the files are code-behind based), this is still a very good example of everything that you get by default:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;web.config &lt;/LI&gt;
&lt;LI&gt;Default.aspx - except this one actually does stuff &lt;/LI&gt;
&lt;LI&gt;a number of page templates &lt;/LI&gt;
&lt;LI&gt;a master page to make sure it all looks the same &lt;/LI&gt;
&lt;LI&gt;a bunch of user controls &lt;/LI&gt;
&lt;LI&gt;some styles &lt;/LI&gt;
&lt;LI&gt;a few images &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;That is basically the trick - you get half or even more of a fully functional application for free thanks to the Dynamic Data engine and the project templates. And since the functionality is divided between different files, you can easily customize and replace pieces as you see fit.&lt;/P&gt;
&lt;H3&gt;&lt;/H3&gt;
&lt;H3&gt;How do we nurture these templates?&lt;/H3&gt;
&lt;P&gt;All of this comes at a price, however... at least to us - the Dynamic Data team. One of the reasons why the majority of the default project templates is so small might very well be because it is a lot easier to support them (that and the fact that it is hard to come up with anything more complicated that would make a meaningful default). The smaller the code the less you need to worry about breaking it.&lt;/P&gt;
&lt;P&gt;In the case of Dynamic Data the situation is further complicated due to the number of various combinations we want to support:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;C# vs Visual Basic &lt;/LI&gt;
&lt;LI&gt;Web Sites vs WAPs &lt;/LI&gt;
&lt;LI&gt;Linq To SQL vs Entity Framework &lt;/LI&gt;
&lt;LI&gt;Inline vs Code-behind &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;In order to avoid having... let's see... 1, 2, 3... 16 different project templates and lots of redundancy we have a pretty neat solution that combines templates, token replacement, automatic language translation, file stitching, and a few other steps to produce the end result from the absolute minimum number of source files. And in the rare few cases where our automatic tools are not sufficient to account for the differences between the various technologies we use or support, we just have manually written overrides.&lt;/P&gt;
&lt;P&gt;On the positive side, this means that a large part of the functionality is not locked away in some impenetrable, sealed DLL. If you do not like how something works, you can &lt;A title="Sample for displaying images in Dynamic Data" href="http://blogs.msdn.com/scothu/archive/2008/01/14/sample.aspx"&gt;quite easily replace it&lt;/A&gt;. And if by some remote chance there is a &lt;A href="http://blogs.msdn.com/marcinon/archive/2007/12/20/dynamic-data-december-preview-context-caching-fix.aspx"&gt;pretty nasty bug in the Dynamic Data CTP code&lt;/A&gt; (which there was), your chances of a workaround are just a bit better.&lt;/P&gt;
&lt;P&gt;If you still have not checked Dynamic Data out, &lt;A title="ASP.NET 3.5 Extensions Preview site" href="http://asp.net/downloads/3.5-extensions"&gt;give it a go&lt;/A&gt;. You might just get done with your next project that much quicker.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=7898031" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/marcinon/archive/tags/ASP.NET+Dynamic+Data/default.aspx">ASP.NET Dynamic Data</category></item><item><title>Dynamic Data December preview context caching bug fix</title><link>http://blogs.msdn.com/marcinon/archive/2007/12/20/dynamic-data-december-preview-context-caching-bug-fix.aspx</link><pubDate>Fri, 21 Dec 2007 01:50:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:6820755</guid><dc:creator>marcind</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/marcinon/comments/6820755.aspx</comments><wfw:commentRss>http://blogs.msdn.com/marcinon/commentrss.aspx?PostID=6820755</wfw:commentRss><description>&lt;P&gt;Users of our recently released &lt;A title="ASP.NET 3.5 Extensions Preview site" href="http://asp.net/downloads/3.5-extensions" target=_blank mce_href="http://asp.net/downloads/3.5-extensions"&gt;December preview&lt;/A&gt; of the new Dynamic Data feature in ASP.NET have &lt;A href="http://forums.asp.net/t/1195935.aspx" target=_blank mce_href="http://forums.asp.net/t/1195935.aspx"&gt;noticed a pretty serious bug&lt;/A&gt; relating to foreign key column drop-downs. While this could be a breaking issue for many trying to test or adopt the new feature, I am glad to report that there is a workaround available.&lt;/P&gt;
&lt;P&gt;This post talks about what the bug is and what steps are needed to resolve it. I am also attaching a zip file that you can simply unzip in the root of your Dynamic Data project (&lt;STRONG&gt;warning&lt;/STRONG&gt;: this could overwrite customizations you have made to the project files. Read on to see what files are affected).&lt;/P&gt;
&lt;P&gt;You can download the updated versions of the affected controls &lt;A class="" title=DataContextCachingFix_07_12_20.zip href="http://blogs.msdn.com/marcinon/attachment/6820755.ashx" mce_href="http://blogs.msdn.com/marcinon/attachment/6820755.ashx"&gt;here&lt;/A&gt;&amp;nbsp;(3 KB).&lt;/P&gt;
&lt;H3&gt;Bug symptoms&lt;/H3&gt;
&lt;P&gt;The bug affects the drop-down lists for foreign key relation columns as well foreign key filters. The problem occurs when you insert a new item into the parent table, then go to the child table and try to add a new entry, edit an existing one, or filter the table using the entry you added in the parent column. The drop-down list does not contain the newly added item and only restarting the entire app makes it appear (an analogous thing will happen if you remove an entry from the parent table).&lt;/P&gt;
&lt;P&gt;This bug occurs because the Dynamic Data framework is trying to cache an instance of the DataContext object that represent the data model. The DataContext instance is something that should be instantiated, used to retrieve/submit information to the database, and then discard it. Dynamic Data holds on to it a bit longer than it should.&lt;/P&gt;
&lt;H3&gt;The solution&lt;/H3&gt;
&lt;P&gt;You can download the file mentioned at the beginning of this post to get the updated versions of the affected files. Simply unzip into the root of your Dynamic Data project. The included files are in C# but they should work even if your project is in VB.&lt;/P&gt;
&lt;P&gt;The solution to the problem basically requires providing a new instance of the DataContext object to the controls responsible for rendering the drop-downs. This means you need to modify ForeignKey_Edit.ascx and FilterUserControl.ascx (both living in App_Shared\DynamicDataFields\ directory in the Dynamic Data project templates).&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;
&lt;H5&gt;ForeignKey_Edit.ascx&lt;/H5&gt;
&lt;P&gt;In the Page_Load method, replace the following line of code&lt;/P&gt;&lt;PRE class=code&gt;DropDownList1.DataSource = parentTable.Query;
&lt;/PRE&gt;
&lt;P&gt;with this&lt;/P&gt;&lt;PRE class=code&gt;DropDownList1.DataSource = parentTable.DataContextProperty.GetValue(&lt;SPAN style="COLOR: #2b91af"&gt;Activator&lt;/SPAN&gt;.CreateInstance(&lt;SPAN style="COLOR: #2b91af"&gt;DynamicDatabase&lt;/SPAN&gt;.TheDatabase.CreateDataContext().GetType()), &lt;SPAN style="COLOR: blue"&gt;null&lt;/SPAN&gt;);&lt;/PRE&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;UL&gt;
&lt;LI&gt;
&lt;H5&gt;FilterUserControl.ascx&lt;/H5&gt;
&lt;P&gt;In the Page_Init method, replace the following line of code&lt;/P&gt;&lt;PRE class=code&gt;DropDownList1.DataSource = DataSource;&lt;/PRE&gt;
&lt;P&gt;with this&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;var &lt;/SPAN&gt;foreignKeyColumn = &lt;SPAN style="COLOR: #2b91af"&gt;DynamicDatabase&lt;/SPAN&gt;.TheDatabase.GetMetaTable(&lt;SPAN style="COLOR: blue"&gt;this&lt;/SPAN&gt;.TableName).FindColumn(&lt;SPAN style="COLOR: blue"&gt;this&lt;/SPAN&gt;.DataField) &lt;SPAN style="COLOR: blue"&gt;as &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;DynamicMetaForeignKeyMember&lt;/SPAN&gt;;
&lt;SPAN style="COLOR: blue"&gt;if &lt;/SPAN&gt;(foreignKeyColumn != &lt;SPAN style="COLOR: blue"&gt;null&lt;/SPAN&gt;) {
    &lt;SPAN style="COLOR: green"&gt;// only kick in if we are dealing with a foreign key column
    &lt;/SPAN&gt;DropDownList1.DataSource = foreignKeyColumn.ParentMetaTable.DataContextProperty.GetValue(&lt;SPAN style="COLOR: #2b91af"&gt;Activator&lt;/SPAN&gt;.CreateInstance(&lt;SPAN style="COLOR: #2b91af"&gt;DynamicDatabase&lt;/SPAN&gt;.TheDatabase.CreateDataContext().GetType()), &lt;SPAN style="COLOR: blue"&gt;null&lt;/SPAN&gt;);
}
&lt;SPAN style="COLOR: blue"&gt;else &lt;/SPAN&gt;{
    DropDownList1.DataSource = DataSource;
}&lt;/PRE&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;The new code is a bit ugly but it should work. Upcoming versions of Dynamic Data will not have this problem.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=6820755" width="1" height="1"&gt;</description><enclosure url="http://blogs.msdn.com/marcinon/attachment/6820755.ashx" length="2593" type="application/x-zip-compressed" /><category domain="http://blogs.msdn.com/marcinon/archive/tags/ASP.NET+Dynamic+Data/default.aspx">ASP.NET Dynamic Data</category><category domain="http://blogs.msdn.com/marcinon/archive/tags/bug+fix/default.aspx">bug fix</category></item><item><title>Dynamic Data screencast is available</title><link>http://blogs.msdn.com/marcinon/archive/2007/12/12/dynamic-data-screencast-is-available.aspx</link><pubDate>Thu, 13 Dec 2007 02:24:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:6752636</guid><dc:creator>marcind</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/marcinon/comments/6752636.aspx</comments><wfw:commentRss>http://blogs.msdn.com/marcinon/commentrss.aspx?PostID=6752636</wfw:commentRss><description>&lt;P&gt;David Ebbo has just posted a &lt;A title="Dynamic Data Dec '07 Screencast" href="http://download.microsoft.com/download/5/D/1/5D113D2D-571C-4EDD-9C1C-59BC0E6981F6/WinVideo-2007-12-08%20Dynamic%20Data.wmv" mce_href="http://download.microsoft.com/download/5/D/1/5D113D2D-571C-4EDD-9C1C-59BC0E6981F6/WinVideo-2007-12-08%20Dynamic%20Data.wmv"&gt;screencast&lt;/A&gt; covering the Dynamic Data feature in &lt;A title="ASP.NET 3.5 Extensions Preview site" href="http://asp.net/downloads/3.5-extensions" target=_blank mce_href="http://asp.net/downloads/3.5-extensions"&gt;ASP.NET 3.5 Extensions Preview&lt;/A&gt;. It is 17 minutes long and covers the following topics:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Creating a Dynamic Data project&lt;/LI&gt;
&lt;LI&gt;Creating a Linq to SQL model&lt;/LI&gt;
&lt;LI&gt;Running the scaffolded version of a Dynamic Data project&lt;/LI&gt;
&lt;LI&gt;Customizing data validation&lt;/LI&gt;
&lt;LI&gt;Customizing UI presentation&lt;/LI&gt;
&lt;LI&gt;Adding metadata to the model&lt;/LI&gt;
&lt;LI&gt;Writing custom pages in place of the scaffolded ones&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Check out &lt;A href="http://blogs.msdn.com/davidebb/archive/2007/12/12/dynamic-data-screencast-is-now-available.aspx" target=_blank mce_href="http://blogs.msdn.com/davidebb/archive/2007/12/12/dynamic-data-screencast-is-now-available.aspx"&gt;David's post&lt;/A&gt;.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=6752636" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/marcinon/archive/tags/ASP.NET+3.5+Extensions/default.aspx">ASP.NET 3.5 Extensions</category><category domain="http://blogs.msdn.com/marcinon/archive/tags/ASP.NET+Dynamic+Data/default.aspx">ASP.NET Dynamic Data</category><category domain="http://blogs.msdn.com/marcinon/archive/tags/screencast/default.aspx">screencast</category></item></channel></rss>