<?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>Angle Bracket Percent : Dynamic Data</title><link>http://blogs.msdn.com/davidebb/archive/tags/Dynamic+Data/default.aspx</link><description>Tags: Dynamic Data</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>Peter Blum’s new blog and his cool new data source controls</title><link>http://blogs.msdn.com/davidebb/archive/2009/11/12/peter-blum-s-new-blog-and-his-cool-new-data-source-controls.aspx</link><pubDate>Fri, 13 Nov 2009 01:19:54 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9921686</guid><dc:creator>davidebb</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/davidebb/comments/9921686.aspx</comments><wfw:commentRss>http://blogs.msdn.com/davidebb/commentrss.aspx?PostID=9921686</wfw:commentRss><wfw:comment>http://blogs.msdn.com/davidebb/rsscomments.aspx?PostID=9921686</wfw:comment><description>&lt;p&gt;Peter Blum has been well known is the ASP.NET world for many years for writing a whole suite of powerful controls, which you can read all about on &lt;a href="http://www.peterblum.com/Home.aspx"&gt;his site&lt;/a&gt;.&amp;#160; One thing that was missing on Peter’s resume is that he never had a blog.&amp;#160; Well he started one earlier this month, and is making up for the lost time in a big way, with already 11 posts!&amp;#160; And we’re not talking about small posts that just point to other people’s stuff (unlike this post I suppose!), but real with useful meaty content.&amp;#160; Make sure you check out his blog at &lt;a title="http://weblogs.asp.net/peterblum/" href="http://weblogs.asp.net/peterblum/"&gt;http://weblogs.asp.net/peterblum/&lt;/a&gt;.&amp;#160; I hope he keeps the good stuff coming!&lt;/p&gt;  &lt;p&gt;In particular, Peter has been working hard on some interesting data source controls that work with Visual Studio 2010.&amp;#160; He’s calling them the ‘Versatile DataSources’, and is making it all &lt;a href="http://versatiledatasources.codeplex.com/"&gt;available for free on CodePlex&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;The following posts on his blog describe the data source controls:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;First, an &lt;a href="http://weblogs.asp.net/peterblum/archive/2009/11/03/introducing-versatile-datasources.aspx"&gt;Intro Post&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;Then a &lt;a href="http://weblogs.asp.net/peterblum/archive/2009/11/03/datasources-dynamic-data-and-soc.aspx"&gt;follow up post&lt;/a&gt; with more details and many code samples&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;The simplest way to try out his controls is to &lt;a href="http://versatiledatasources.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=35313#DownloadId=90624"&gt;download them from CodePlex&lt;/a&gt;.&amp;#160; The package contains a rich set of samples that you can directly run and play with.&amp;#160; You’ll need VS2010 Beta 2 to run this, so if you don’t already have it, get it from &lt;a href="http://msdn.microsoft.com/en-us/vstudio/dd582936.aspx"&gt;here&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;I haven’t fully tried everything yet, but the one I played with the most is his POCODataSource, which is quite interesting.&amp;#160; The core idea is very simple: you give it a type and it makes it easy to put up a WebForms UI to fill up an instance of that type.&amp;#160; The UI supports full validation using standard model annotations supported by Dynamic Data.&lt;/p&gt;  &lt;p&gt;The beauty is that it’s really quite easy to use.&amp;#160; The data source declaration looks something like this (borrowed from Peter’s samples):&lt;/p&gt;  &lt;pre class="brush: xml;"&gt;   &amp;lt;poco:POCODataSource ID=&amp;quot;POCODataSource1&amp;quot; runat=&amp;quot;server&amp;quot; POCOTypeName=&amp;quot;CEOEmailGenerator&amp;quot; /&amp;gt;&lt;/pre&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;For the actual UI, you can use any standard ASP.NET data control like DetailsView, FormView or some similar 3rd party control.&amp;#160; Then when an Update operation happens, you simply access the built instance from the data source using&amp;#160; POCODataSource1.POCOInstance.&amp;#160; At that point, you can do whatever you want with it.&amp;#160; In Peter’s sample, he ends up calling an action method directly on the object, e.g.&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;protected void FormView1_ItemUpdated(object sender, FormViewUpdatedEventArgs e) {
   if (Page.IsValid) {
      ((CEOEmailGenerator)POCODataSource1.POCOInstance).Send();
   }
}&lt;/pre&gt;

&lt;p&gt;But I don’t see anything that ties you to this pattern, and you could instead just call some helper method and pass the object if your object doesn’t have an action method itself.&lt;/p&gt;

&lt;p&gt;Anyway, check it out in much more details on Peter’s blog!&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9921686" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/davidebb/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://blogs.msdn.com/davidebb/archive/tags/Dynamic+Data/default.aspx">Dynamic Data</category><category domain="http://blogs.msdn.com/davidebb/archive/tags/Entity+Framework/default.aspx">Entity Framework</category></item><item><title>Using an Associated Metadata Class outside Dynamic Data</title><link>http://blogs.msdn.com/davidebb/archive/2009/07/24/using-an-associated-metadata-class-outside-dynamic-data.aspx</link><pubDate>Sat, 25 Jul 2009 04:31:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9848007</guid><dc:creator>davidebb</dc:creator><slash:comments>8</slash:comments><comments>http://blogs.msdn.com/davidebb/comments/9848007.aspx</comments><wfw:commentRss>http://blogs.msdn.com/davidebb/commentrss.aspx?PostID=9848007</wfw:commentRss><wfw:comment>http://blogs.msdn.com/davidebb/rsscomments.aspx?PostID=9848007</wfw:comment><description>&lt;P&gt;A while back, I &lt;A href="http://blogs.msdn.com/davidebb/archive/2008/06/16/dynamic-data-and-the-associated-metadata-class.aspx" mce_href="http://blogs.msdn.com/davidebb/archive/2008/06/16/dynamic-data-and-the-associated-metadata-class.aspx"&gt;blogged&lt;/A&gt; about how ASP.NET Dynamic Data apps can uses an Associated Metadata class (aka a ‘buddy’ class) to add metadata attributed to properties defined in a generated class.&amp;nbsp; It’s a mostly ugly thing that was made necessary by limitations of the C# and VB.NET languages: they don’t let you add attributes to properties defined in another partial class.&lt;/P&gt;
&lt;P&gt;What I didn’t mention there is that this ‘buddy’ class mechanism is actually not specific to Dynamic Data apps, and can in fact be used anywhere.&amp;nbsp; Since I’ve recently heard of several cases of users trying to do something similar, I’ll describe how it’s done.&amp;nbsp; If you’re familiar with TypeDescriptionProviders (which have been around since ancient times), this will look very trivial.&lt;/P&gt;
&lt;P&gt;I will illustrate this in a very simple console app to keep all other distractions out of the picture (the full sample is attached to the post).&amp;nbsp; So the general scenario is that we have a generated class somewhere, e.g.&lt;/P&gt;&lt;PRE class="brush: csharp;"&gt;// Assume that this is generated code that should never be hand modified.
// Hence metadata attributes can't be added directly here

public partial class Product {
    public string Name { get; set; }

    public int UnitsInStock { get; set; }
}&lt;/PRE&gt;
&lt;P&gt;Instead, the buddy provider let’s you write:&lt;/P&gt;&lt;PRE class="brush: csharp;"&gt;[MetadataType(typeof(Product_Metadata))]
public partial class Product {
}

class Product_Metadata {
    [DisplayName("The Units In Stock")]
    public object UnitsInStock { get; set; }
}&lt;/PRE&gt;
&lt;P&gt;This works in Dynamic Data, but if we’re in some other context, no one will find our Product_Metadata ‘buddy’.&amp;nbsp; In our to hook it up ourselves, we just need to make one call!&lt;/P&gt;&lt;PRE class="brush: csharp;"&gt;TypeDescriptor.AddProvider(
    new AssociatedMetadataTypeTypeDescriptionProvider(typeof(Product)),
    typeof(Product));&lt;/PRE&gt;
&lt;P&gt;Pretty trivial stuff: we instantiate a TypeDescriptionProvider (with a somewhat scary name, I’ll give you that) and we register it by calling TypeDescriptor.AddProvider.&lt;/P&gt;
&lt;P&gt;Once we do that, the attributes on the ‘buddy’ class magically show up as if they were defined on the real class:&lt;/P&gt;&lt;PRE class="brush: csharp;"&gt;// Get the property descriptor for UnitsInStock
PropertyDescriptor propDesc = TypeDescriptor.GetProperties(
    typeof(Product)).Find("UnitsInStock", true);

// Get the display name attribute, which is not actually on the property,
// but on its counterpart in the 'buddy' class
var displayName = propDesc.Attributes.OfType&amp;lt;DisplayNameAttribute&amp;gt;().First();&lt;/PRE&gt;
&lt;P&gt;And that’s pretty much it.&amp;nbsp; One important thing to notice here is that &lt;STRONG&gt;we are not using the standard reflection API&lt;/STRONG&gt; (which would look like typeof(Product).GetCustomAttributes()), but we are instead using the TypeDescriptor API from the System.ComponentModel model namespace.&lt;/P&gt;
&lt;P&gt;So to summarize, you can easily use this ‘buddy’ class mechanism anytime you deal with generated code that you need to annotate with attributes.&amp;nbsp; And even though it’s not pretty to have to use that extra class, it’s comes very handy when there is no alternative.&amp;nbsp; Maybe the day will come when C# will support doing this more cleanly, but in the meantime that’ll have to do!&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9848007" width="1" height="1"&gt;</description><enclosure url="http://blogs.msdn.com/davidebb/attachment/9848007.ashx" length="7616" type="application/x-zip-compressed" /><category domain="http://blogs.msdn.com/davidebb/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://blogs.msdn.com/davidebb/archive/tags/Dynamic+Data/default.aspx">Dynamic Data</category></item><item><title>Using a DomainService in ASP.NET and Dynamic Data</title><link>http://blogs.msdn.com/davidebb/archive/2009/03/24/using-domaindatasource-in-asp-net.aspx</link><pubDate>Wed, 25 Mar 2009 04:52:02 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9506050</guid><dc:creator>davidebb</dc:creator><slash:comments>13</slash:comments><comments>http://blogs.msdn.com/davidebb/comments/9506050.aspx</comments><wfw:commentRss>http://blogs.msdn.com/davidebb/commentrss.aspx?PostID=9506050</wfw:commentRss><wfw:comment>http://blogs.msdn.com/davidebb/rsscomments.aspx?PostID=9506050</wfw:comment><description>&lt;p&gt;One of the big things that I discussed in my &lt;a href="http://videos.visitmix.com/MIX09/T47F"&gt;MIX talk&lt;/a&gt; is the new DomainDataSource control.&amp;#160; It is currently available in Preview form as part of &lt;a href="http://aspnet.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=24887"&gt;ASP.NET Dynamic Data 4.0 Preview 3&lt;/a&gt;.&amp;#160; This can be confusing, because even though Dynamic Data makes use of DomainDataSource, DomainDataSource is absolutely not tied to Dynamic Data, and is fully usable in ‘regular’ aspx pages.&lt;/p&gt;  &lt;p&gt;In addition to this preview, you’ll want to also install &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=76bb3a07-3846-4564-b0c3-27972bcaabce&amp;amp;displaylang=en"&gt;Microsoft .NET RIA Services&lt;/a&gt; in order to get some useful tooling.&amp;#160; This too can be confusing, because it makes it sound like it’s tied to RIA and Silverlight in some way, when in fact it is not.&lt;/p&gt;  &lt;p&gt;The deal is that there is this new thing called a DomainService, which is essentially a Business Layer class that exposes CRUD methods.&amp;#160; Once you have a DomainService, you can use it in various scenarios, including ASP.NET apps and Silverlight apps.&amp;#160; Here, we will focus on its use from ASP.NET.&amp;#160; For more information about the Silverlight side of things, check out &lt;a href="http://www.nikhilk.net/RIA-Services-MIX09.aspx"&gt;Nikhil’s post&lt;/a&gt; (and his MIX &lt;a href="http://videos.visitmix.com/MIX09/T41F"&gt;talk&lt;/a&gt;).&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Important&lt;/strong&gt;: after getting the ASP.NET DD preview and the RIA Services mentioned above, you’ll need to do a little extra step to avoid a tricky setup issue. Find System.Web.DynamicData.dll under DefaultDomainServiceProject\bin in the ASP.NET Preview zip file, and copy it over the one in \Program Files\Microsoft SDKs\RIA Services\v1.0\Libraries\Server (which is where the RIA install puts them).&lt;/p&gt;  &lt;p&gt;Now you’re actually ready to start playing with DomainService.&lt;/p&gt;  &lt;p&gt;First, you’ll want to make a copy of the whole DefaultDomainServiceProject folder so you can work with it without touching the ‘original’.&amp;#160; Then, just open DefaultDomainServiceProject.sln in VS.&amp;#160; Normally, this would be a Project Template, but right now we don’t have one.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h3&gt;&lt;/h3&gt;  &lt;h3&gt;Creating a DomainService&lt;/h3&gt;  &lt;p&gt;DefaultDomainServiceProject comes with a default DomainService, but to make things more interesting you should just delete it and recreate one from scratch.&amp;#160; Just delete DomainServices\NorthwindEntitiesDomainService.cs.&lt;/p&gt;  &lt;p&gt;Now right click on DomainServices, choose Add New Item, and pick Domain Service Class.&amp;#160; Name it for instance Catalog.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/davidebb/WindowsLiveWriter/UsingthenewDomainDataSource_F0FE/image_4.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/blogfiles/davidebb/WindowsLiveWriter/UsingthenewDomainDataSource_F0FE/image_thumb_1.png" width="808" height="488" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;You’ll see a New Domain Service dialog.&amp;#160; In here, do the following:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Uncheck Enable Client Access. That’s only useful for the Silverlight scenario.&lt;/li&gt;    &lt;li&gt;Check Categories and Products.&amp;#160; For Products, also click the right check box to enable editing.&lt;/li&gt;    &lt;li&gt;Check ‘Generate associated classes’ at the bottom. This will be useful for Dynamic Data.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/davidebb/WindowsLiveWriter/UsingthenewDomainDataSource_F0FE/image_6.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/blogfiles/davidebb/WindowsLiveWriter/UsingthenewDomainDataSource_F0FE/image_thumb_2.png" width="445" height="467" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;You should end up with a class that looks like this:&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;public class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Catalog &lt;/span&gt;: &lt;span style="color: #2b91af"&gt;LinqToEntitiesDomainService&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;NorthwindEntities&lt;/span&gt;&amp;gt; {

&lt;span style="color: blue"&gt;    public &lt;/span&gt;&lt;span style="color: #2b91af"&gt;IQueryable&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Categories&lt;/span&gt;&amp;gt; GetCategories() {
        &lt;span style="color: blue"&gt;return this&lt;/span&gt;.Context.Categories;
    }

&lt;span style="color: blue"&gt;    public &lt;/span&gt;&lt;span style="color: #2b91af"&gt;IQueryable&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Products&lt;/span&gt;&amp;gt; GetProducts() {
        &lt;span style="color: blue"&gt;return this&lt;/span&gt;.Context.Products;
    }

    &lt;span style="color: blue"&gt;public void &lt;/span&gt;InsertProducts(&lt;span style="color: #2b91af"&gt;Products &lt;/span&gt;products) {
        &lt;span style="color: blue"&gt;this&lt;/span&gt;.Context.AddToProducts(products);
    }

    &lt;span style="color: blue"&gt;public void &lt;/span&gt;UpdateProducts(&lt;span style="color: #2b91af"&gt;Products &lt;/span&gt;currentProducts, &lt;span style="color: #2b91af"&gt;Products &lt;/span&gt;originalProducts) {
        &lt;span style="color: blue"&gt;this&lt;/span&gt;.Context.AttachAsModified(currentProducts, originalProducts);
    }

    &lt;span style="color: blue"&gt;public void &lt;/span&gt;DeleteProducts(&lt;span style="color: #2b91af"&gt;Products &lt;/span&gt;products) {
        &lt;span style="color: blue"&gt;if &lt;/span&gt;((products.EntityState == &lt;span style="color: #2b91af"&gt;EntityState&lt;/span&gt;.Detached)) {
            &lt;span style="color: blue"&gt;this&lt;/span&gt;.Context.Attach(products);
        }
        &lt;span style="color: blue"&gt;this&lt;/span&gt;.Context.DeleteObject(products);
    }&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;Basically, it’s just a class for a few CRUD methods that you want to expose.&amp;#160; In this case, it’s working over an Entity Framework model (hence the base class), but it would look similar with Linq to SQL or other ORM technologies.&lt;/p&gt;

&lt;p&gt;The important part is that all data access goes through those methods, so you have full control over it.&amp;#160; This is quite different from using LinqDataSource/EntityDataSource, where they talk directly to the DAL without going through your code.&amp;#160; You have to write a little code, but the extra control you get makes it well worth it!&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h3&gt;Registering your DomainService with Dynamic Data&lt;/h3&gt;

&lt;p&gt;Before we get into writing ‘standard’ ASP.NET pages by hand (in future posts), we’ll use Dynamic Data to get started quickly.&amp;#160; To do this, simply add this line to global.asax (replacing the similar line that’s already there):&lt;/p&gt;

&lt;pre class="code"&gt;DefaultModel.RegisterContext(
    &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;DomainModelProvider&lt;/span&gt;(&lt;span style="color: blue"&gt;typeof&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;Catalog&lt;/span&gt;)),
    &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ContextConfiguration&lt;/span&gt;() { ScaffoldAllTables = &lt;span style="color: blue"&gt;true &lt;/span&gt;});&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h3&gt;Running it&lt;/h3&gt;

&lt;p&gt;Now you can just Ctrl-F5 and you should get a working Dynamic Data app.&amp;#160; Note how it only lets you do things for which you have CRUD methods.&amp;#160; e.g.&amp;#160; you can edit Products but not Categories.&lt;/p&gt;

&lt;p&gt;To make things more interesting, try various things:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Debug the app and set break points in your CRUD methods to see them getting called.&lt;/li&gt;

  &lt;li&gt;Change GetProduct() to only return a subset of the products, and watch it affect the UI&lt;/li&gt;

  &lt;li&gt;Change UpdateProduct() to modify the product before saving it,&lt;/li&gt;

  &lt;li&gt;Add some Dynamic Data style metadata in DomainServices\Catalog.metadata.cs.&amp;#160; e.g. add a [Range(0, 100)] attribute to some integer field, and try an edit that violates the range&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;&amp;#160;&lt;/h3&gt;

&lt;h3&gt;Conclusion&lt;/h3&gt;

&lt;p&gt;This was really just a quick intro to using DomainService in ASP.NET and Dynamic Data.&amp;#160; I’ll try to follow up with some posts that go into more details on how to use DomainDataSource directly in a page without involving any Dynamic Data.&amp;#160; To reiterate, though Dynamic Data works great with DomainDataSource, DomainDataSource completely stands on its own without Dynamic Data (as was shown in my &lt;a href="http://videos.visitmix.com/MIX09/T47F"&gt;MIX talk&lt;/a&gt;).&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9506050" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/davidebb/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://blogs.msdn.com/davidebb/archive/tags/Dynamic+Data/default.aspx">Dynamic Data</category></item><item><title>My MIX 2009 ASP.NET Data talk is available online</title><link>http://blogs.msdn.com/davidebb/archive/2009/03/23/my-mix-2009-asp-net-data-talk-is-available-online.aspx</link><pubDate>Tue, 24 Mar 2009 09:41:59 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9503554</guid><dc:creator>davidebb</dc:creator><slash:comments>6</slash:comments><comments>http://blogs.msdn.com/davidebb/comments/9503554.aspx</comments><wfw:commentRss>http://blogs.msdn.com/davidebb/commentrss.aspx?PostID=9503554</wfw:commentRss><wfw:comment>http://blogs.msdn.com/davidebb/rsscomments.aspx?PostID=9503554</wfw:comment><description>&lt;p&gt;Last Friday, I gave a talk at &lt;a href="http://live.visitmix.com/"&gt;MIX&lt;/a&gt; on various things that we’re working on in ASP.NET data land.&amp;#160; This includes both some Dynamic Data features and some features usable outside Dynamic Data.&lt;/p&gt;  &lt;p&gt;The great thing about MIX is that they make all talks freely available online shortly after, and you can watch mine &lt;a href="http://videos.visitmix.com/MIX09/T47F"&gt;here&lt;/a&gt;.&amp;#160; Enjoy!&lt;/p&gt;  &lt;p&gt;I’ll try to blog in more detail about some of the features discussed in the talk in the next few days.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9503554" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/davidebb/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://blogs.msdn.com/davidebb/archive/tags/Dynamic+Data/default.aspx">Dynamic Data</category></item><item><title>A helper to easily set up change notifications in Entity Framework</title><link>http://blogs.msdn.com/davidebb/archive/2009/01/09/a-helper-to-easily-set-up-change-notifications-in-entity-framework.aspx</link><pubDate>Sat, 10 Jan 2009 05:39:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9303268</guid><dc:creator>davidebb</dc:creator><slash:comments>7</slash:comments><comments>http://blogs.msdn.com/davidebb/comments/9303268.aspx</comments><wfw:commentRss>http://blogs.msdn.com/davidebb/commentrss.aspx?PostID=9303268</wfw:commentRss><wfw:comment>http://blogs.msdn.com/davidebb/rsscomments.aspx?PostID=9303268</wfw:comment><description>&lt;p&gt;&lt;/p&gt;  &lt;p&gt;When you use Entity Framework, you can perform Insert/Update/Delete operations on your entities, and you eventually call ObjectContext.SaveChanges() to actually make it all happen.&amp;#160; The call to SaveChanges() is either explicit, or can happen implicitly when you use the EntityDataSource (e.g. within a Dynamic Data application).&lt;/p&gt;  &lt;p&gt;Before SaveChanges() actually performs the operations, it gives you a chance to look at the entities, letting you modify them, and possibly cancel certain operations.&amp;#160; Unfortunately, doing this requires using some pretty ugly code, because the API is a little too low level.&amp;#160; Instead of nicely handing you the changes one by one, it just gives you the raw change list and lets you deal with it.&lt;/p&gt;  &lt;p&gt;For instance, suppose you want to do something special when a Product is being updated.&amp;#160; You have to:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Register for the ObjectContext.SavingChanges event &lt;/li&gt;    &lt;li&gt;In your handler, call ObjectStateManager.GetObjectStateEntries(EntityState.Modified) &lt;/li&gt;    &lt;li&gt;Go through the whole list looking for those where stateEntry.Entity is a Product &lt;/li&gt;    &lt;li&gt;Finally they can do what they want with the Product &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;While certainly possible, it’s a lot more pain than it should be!&amp;#160; To make this easier, we’ll write a little helper which lets you trivially listen to the changes you care about.&lt;/p&gt;  &lt;p&gt;Before we get to the implementation of the helper, let’s look at the end result with the helper.&amp;#160; It lets you write something like this:&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;public partial class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;NorthwindEntities &lt;/span&gt;{
    &lt;span style="color: blue"&gt;partial void &lt;/span&gt;OnContextCreated() {
        &lt;span style="color: green"&gt;// This line hooks up the change notifications
        &lt;/span&gt;&lt;span style="color: blue"&gt;this&lt;/span&gt;.SetupChangeNotifications();
    }
}

&lt;span style="color: blue"&gt;public partial class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Products &lt;/span&gt;: &lt;span style="color: #2b91af"&gt;INotifyUpdating &lt;/span&gt;{
    &lt;span style="color: blue"&gt;public bool &lt;/span&gt;Updating() {
        &lt;span style="color: green"&gt;// Make a small change to test that you can affect the entity
        &lt;/span&gt;ProductName += &lt;span style="color: #a31515"&gt;&amp;quot;!&amp;quot;&lt;/span&gt;;
        &lt;span style="color: blue"&gt;return true&lt;/span&gt;;
    }
}

&lt;span style="color: blue"&gt;public partial class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Categories &lt;/span&gt;: &lt;span style="color: #2b91af"&gt;INotifyDeleting &lt;/span&gt;{
    &lt;span style="color: blue"&gt;public bool &lt;/span&gt;Deleting() {
        &lt;span style="color: green"&gt;// Prevent the deletion
        &lt;/span&gt;&lt;span style="color: blue"&gt;return false&lt;/span&gt;;
    }
}&lt;/pre&gt;

&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Notice how you just need to implement a simple interface on the partial class on the relevant entity type in order to get notified.&amp;#160; You don’t need to know anything about the change list, or other such low level things.&lt;/p&gt;

&lt;p&gt;Now let’s take a look at how the help works.&amp;#160; First, we define the Insert/Update/Delete interfaces:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;public interface &lt;/span&gt;&lt;span style="color: #2b91af"&gt;INotifyInserting &lt;/span&gt;{
    &lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color: green"&gt;Return false to cancel the Insert operation
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
    &lt;/span&gt;&lt;span style="color: blue"&gt;bool &lt;/span&gt;Inserting();
}

&lt;span style="color: blue"&gt;public interface &lt;/span&gt;&lt;span style="color: #2b91af"&gt;INotifyUpdating &lt;/span&gt;{
    &lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color: green"&gt;Return false to cancel the Update operation
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
    &lt;/span&gt;&lt;span style="color: blue"&gt;bool &lt;/span&gt;Updating();
}

&lt;span style="color: blue"&gt;public interface &lt;/span&gt;&lt;span style="color: #2b91af"&gt;INotifyDeleting &lt;/span&gt;{
    &lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color: green"&gt;Return false to cancel the Delete operation
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
    &lt;/span&gt;&lt;span style="color: blue"&gt;bool &lt;/span&gt;Deleting();
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;Pretty simple stuff.&amp;#160; And now, the core logic that makes it all happen:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;public static class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;EntityFrameworkHelpers &lt;/span&gt;{
    &lt;span style="color: blue"&gt;public static void &lt;/span&gt;SetupChangeNotifications(&lt;span style="color: blue"&gt;this &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ObjectContext &lt;/span&gt;context) {
        &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ObjectContextHelper&lt;/span&gt;(context);
    }

    &lt;span style="color: blue"&gt;private class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ObjectContextHelper &lt;/span&gt;{
        &lt;span style="color: #2b91af"&gt;ObjectContext &lt;/span&gt;_context;

        &lt;span style="color: blue"&gt;public &lt;/span&gt;ObjectContextHelper(&lt;span style="color: #2b91af"&gt;ObjectContext &lt;/span&gt;context) {
            &lt;span style="color: green"&gt;// Keep track of the context
            &lt;/span&gt;_context = context;

            &lt;span style="color: green"&gt;// Register for the SavingChanges event
            &lt;/span&gt;_context.SavingChanges += &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;EventHandler&lt;/span&gt;(Context_SavingChanges);
        }

        &lt;span style="color: blue"&gt;void &lt;/span&gt;Context_SavingChanges(&lt;span style="color: blue"&gt;object &lt;/span&gt;sender, &lt;span style="color: #2b91af"&gt;EventArgs &lt;/span&gt;e) {
            &lt;span style="color: green"&gt;// Go through all the Insert/Update/Delete changes and notify the user code if needed
            &lt;/span&gt;ProcessObjectStateEntries(&lt;span style="color: #2b91af"&gt;EntityState&lt;/span&gt;.Added);
            ProcessObjectStateEntries(&lt;span style="color: #2b91af"&gt;EntityState&lt;/span&gt;.Modified);
            ProcessObjectStateEntries(&lt;span style="color: #2b91af"&gt;EntityState&lt;/span&gt;.Deleted);
        }

        &lt;span style="color: blue"&gt;private void &lt;/span&gt;ProcessObjectStateEntries(&lt;span style="color: #2b91af"&gt;EntityState &lt;/span&gt;entityState) {
            &lt;span style="color: green"&gt;// Go through all the entries
            &lt;/span&gt;&lt;span style="color: blue"&gt;foreach &lt;/span&gt;(&lt;span style="color: #2b91af"&gt;ObjectStateEntry &lt;/span&gt;entry &lt;span style="color: blue"&gt;in &lt;/span&gt;_context.ObjectStateManager.GetObjectStateEntries(entityState)) {

                &lt;span style="color: blue"&gt;if &lt;/span&gt;(entry.Entity == &lt;span style="color: blue"&gt;null&lt;/span&gt;)
                    &lt;span style="color: blue"&gt;continue&lt;/span&gt;;

                &lt;span style="color: green"&gt;// If the entity implements the interface (Insert, Update or Delete), call the
                // method.  If it returns false, cancel the operation
                &lt;/span&gt;&lt;span style="color: blue"&gt;bool &lt;/span&gt;proceedWithChange = &lt;span style="color: blue"&gt;true&lt;/span&gt;;
                &lt;span style="color: blue"&gt;switch &lt;/span&gt;(entityState) {
                    &lt;span style="color: blue"&gt;case &lt;/span&gt;&lt;span style="color: #2b91af"&gt;EntityState&lt;/span&gt;.Added:
                        &lt;span style="color: blue"&gt;var &lt;/span&gt;notifyInserting = entry.Entity &lt;span style="color: blue"&gt;as &lt;/span&gt;&lt;span style="color: #2b91af"&gt;INotifyInserting&lt;/span&gt;;
                        &lt;span style="color: blue"&gt;if &lt;/span&gt;(notifyInserting != &lt;span style="color: blue"&gt;null&lt;/span&gt;)
                            proceedWithChange = notifyInserting.Inserting();
                        &lt;span style="color: blue"&gt;break&lt;/span&gt;;
                    &lt;span style="color: blue"&gt;case &lt;/span&gt;&lt;span style="color: #2b91af"&gt;EntityState&lt;/span&gt;.Modified:
                        &lt;span style="color: blue"&gt;var &lt;/span&gt;notifyUpdating = entry.Entity &lt;span style="color: blue"&gt;as &lt;/span&gt;&lt;span style="color: #2b91af"&gt;INotifyUpdating&lt;/span&gt;;
                        &lt;span style="color: blue"&gt;if &lt;/span&gt;(notifyUpdating != &lt;span style="color: blue"&gt;null&lt;/span&gt;)
                            proceedWithChange = notifyUpdating.Updating();
                        &lt;span style="color: blue"&gt;break&lt;/span&gt;;
                    &lt;span style="color: blue"&gt;case &lt;/span&gt;&lt;span style="color: #2b91af"&gt;EntityState&lt;/span&gt;.Deleted:
                        &lt;span style="color: blue"&gt;var &lt;/span&gt;notifyDeleting = entry.Entity &lt;span style="color: blue"&gt;as &lt;/span&gt;&lt;span style="color: #2b91af"&gt;INotifyDeleting&lt;/span&gt;;
                        &lt;span style="color: blue"&gt;if &lt;/span&gt;(notifyDeleting != &lt;span style="color: blue"&gt;null&lt;/span&gt;)
                            proceedWithChange = notifyDeleting.Deleting();
                        &lt;span style="color: blue"&gt;break&lt;/span&gt;;
                }

                &lt;span style="color: green"&gt;// If the method returned false, cancel the change
                &lt;/span&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;(!proceedWithChange)
                    entry.AcceptChanges();
            }
        }
    }
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;I’ll let the comments speak for themselves here.&amp;#160; But in any case, you don’t really need to look at the details of this code if you just want to use the helpers.&lt;/p&gt;

&lt;p&gt;I attached a complete Dynamic Data solution that includes and uses the helpers, so just download it and start from there!&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9303268" width="1" height="1"&gt;</description><enclosure url="http://blogs.msdn.com/davidebb/attachment/9303268.ashx" length="597700" type="application/x-zip-compressed" /><category domain="http://blogs.msdn.com/davidebb/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://blogs.msdn.com/davidebb/archive/tags/Dynamic+Data/default.aspx">Dynamic Data</category><category domain="http://blogs.msdn.com/davidebb/archive/tags/Entity+Framework/default.aspx">Entity Framework</category></item><item><title>Two worlds of Dynamic Data customization: generic vs schema specific</title><link>http://blogs.msdn.com/davidebb/archive/2008/12/22/two-worlds-of-dynamic-data-customization-generic-vs-schema-specific.aspx</link><pubDate>Tue, 23 Dec 2008 02:44:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9248725</guid><dc:creator>davidebb</dc:creator><slash:comments>5</slash:comments><comments>http://blogs.msdn.com/davidebb/comments/9248725.aspx</comments><wfw:commentRss>http://blogs.msdn.com/davidebb/commentrss.aspx?PostID=9248725</wfw:commentRss><wfw:comment>http://blogs.msdn.com/davidebb/rsscomments.aspx?PostID=9248725</wfw:comment><description>&lt;P&gt;There are many ways to customize a ASP.NET Dynamic Data site, which can sometimes be a bit overwhelming to newcomers.&amp;nbsp; Before deciding what customization makes sense for you, it is important to understand the two major buckets that they fall into:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;&lt;STRONG&gt;Generic customization&lt;/STRONG&gt;: things that apply generically to any table/column. &lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Schema specific customization&lt;/STRONG&gt;: things that apply to specific tables and/or columns. &lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;They can both very useful depending on your scenario, but it is important to understand how they are different in order to make the right choices.&amp;nbsp; The rule of thumb is that you want to stay in the world of generic customization whenever possible, and only use the schema specific customization when you have to.&amp;nbsp; Doing this will increase reusability and decrease redundancy.&lt;/P&gt;
&lt;P&gt;We’ll now look at each in more details.&lt;/P&gt;
&lt;H2&gt;Generic customization&lt;/H2&gt;
&lt;P&gt;Generic customization includes everything that you can do without any knowledge of the database schema that it will be applied to.&amp;nbsp; That is, it’s the type of things that you can write once and potentially use without changes for any number of projects.&amp;nbsp; It lets you achieve a consistent and uniform behavior across an arbitrarily large schema, without needing to do any additional work every time you add or modify a table.&lt;/P&gt;
&lt;P&gt;Here are some key types of generic customization:&lt;/P&gt;
&lt;H3&gt;Page Template customization&lt;/H3&gt;
&lt;P&gt;Under the ~/DynamicData/PageTemplates folder, you’ll find some default Page Templates like List.aspx and Edit.aspx.&amp;nbsp; If you look at them, you won’t find any references to a specific table/column.&amp;nbsp; Instead, they define the general layout and look-and-feel of your pages in an agnostic way.&lt;/P&gt;
&lt;P&gt;e.g. if you look at List.aspx, you’ll see a GridView and a LinqDataSource (or EntityDataSource with Entity Framework), but the data source doesn’t have any ContextTypeName/TableName attributes, and the GridView doesn’t define a column set.&amp;nbsp; Instead, all of that gets set dynamically at runtime based on what table is being accessed.&lt;/P&gt;
&lt;P&gt;You can easily make changes to these Page Templates, such as modifying the layout, adding some new controls or adding logic to the code behind.&amp;nbsp; It’s a ‘normal’ aspx page, so you can treat is as such, but you should never add anything to it that is specific to your schema.&amp;nbsp; When you feel the need to do this, you need to instead create a Custom Page (see below).&lt;/P&gt;
&lt;H3&gt;Field Template customization&lt;/H3&gt;
&lt;P&gt;Under the ~/DynamicData/FieldTemplates folder, you’ll find a whole bunch of field templates, which are used to handle one piece of data of a given type.&amp;nbsp; e.g. DateTime_Edit.ascx handles DateTime columns when they’re being edited.&lt;/P&gt;
&lt;P&gt;As is the case for Page Templates, Field Templates should always be schema agnostic.&amp;nbsp; That is, you don’t write a field template that’s only meant to handle a specific column of a specific table.&amp;nbsp; Instead, you write a field template that can handle all columns of a certain type.&lt;/P&gt;
&lt;P&gt;For example, in this &lt;A href="http://blogs.msdn.com/davidebb/archive/2008/10/25/a-many-to-many-field-template-for-dynamic-data.aspx" mce_href="http://blogs.msdn.com/davidebb/archive/2008/10/25/a-many-to-many-field-template-for-dynamic-data.aspx"&gt;post&lt;/A&gt; I describe a field template that can handle Many To Many relationships.&amp;nbsp; It will work for any such relationship in any schema (though it is Entity Framework specific).&lt;/P&gt;
&lt;H3&gt;Field Generator customization&lt;/H3&gt;
&lt;P&gt;Under Page Template above, I mentioned that the GridView didn’t specify a column set.&amp;nbsp; Instead, the way it works is that there is something called a Field Generator which comes up with the set of columns to use for the current table.&lt;/P&gt;
&lt;P&gt;The idea is that the Field Generator can look at the full column set for a table, and use an arbitrary set of rules to decide which one to include, and in what order to include them.&amp;nbsp; e.g. it can choose to look at custom model attributes to decide what to show.&lt;/P&gt;
&lt;P&gt;Steve Naughton has a &lt;A href="http://csharpbits.notaclue.net/2008/05/dynamicdata-generate-columnsrows-using.html" mce_href="http://csharpbits.notaclue.net/2008/05/dynamicdata-generate-columnsrows-using.html"&gt;great post&lt;/A&gt; on writing a custom field generator, so I encourage you to read that for more info on that topic.&lt;/P&gt;
&lt;H2&gt;Schema specific customization&lt;/H2&gt;
&lt;P&gt;Any time you make a customization that is specific to a certain table or column, you are doing schema specific customization.&amp;nbsp; Here are the main type of things you can do:&lt;/P&gt;
&lt;H3&gt;Custom Pages&lt;/H3&gt;
&lt;P&gt;When you want to have a very specific look for a certain page (e.g. for the Edit page for your Product table), a generic Page Template will no longer do the job.&amp;nbsp; At that point, you want to create a Custom Page.&amp;nbsp; Those live under ~/DynamicData/CustomPages/[TableName].&amp;nbsp; e.g. to have a custom page to edit products, you would create a ~/DynamicData/CustomPages/Products/Edit.aspx.&lt;/P&gt;
&lt;P&gt;You can start out with the custom page being an identical copy of the page template, but then you can start making all kind of schema specific changes.&amp;nbsp; For instance, you could define a custom &amp;lt;Fields&amp;gt; collection in the DetailsView, at which point you no longer rely on the Field Generator (discussed below).&amp;nbsp; Taking this one step further, you can switch from a DetailsView into a FormView (or ListView), giving you full control over the layout of the fields.&lt;/P&gt;
&lt;H3&gt;Model annotations&lt;/H3&gt;
&lt;P&gt;Another very important type of schema specific customization is model annotation.&amp;nbsp; This is what most introductory Dynamic Data demos show, where you add CLR attributes to the partial class of your entity classes.&lt;/P&gt;
&lt;P&gt;For instance, you can add a [Range(0, 100)] attribute to an integer field to specify that it should only take values between 0 and 100.&amp;nbsp; Dynamic Data comes with a number of built-in annotation attributes, and you can easily build your own to add news ways to annotate your model.&lt;/P&gt;
&lt;P&gt;The general idea here is that it is cleaner to add knowledge at the model level than to do it in your UI layer.&amp;nbsp; Anything that you can add to describe your data in more details is a good fit for model annotations.&lt;/P&gt;
&lt;H2&gt;Conclusion&lt;/H2&gt;
&lt;P&gt;All of the different types of customization that I describe above have useful scenarios that call for them.&amp;nbsp; My suggestion is to get a good understanding of what makes some of them Generic while others are Schema Specific, in order to make an informed decision on the best one to use for your scenarios.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9248725" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/davidebb/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://blogs.msdn.com/davidebb/archive/tags/Dynamic+Data/default.aspx">Dynamic Data</category></item><item><title>Using Dynamic Data with multiple databases</title><link>http://blogs.msdn.com/davidebb/archive/2008/12/11/using-dynamic-data-with-multiple-databases.aspx</link><pubDate>Fri, 12 Dec 2008 05:47:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9199694</guid><dc:creator>davidebb</dc:creator><slash:comments>9</slash:comments><comments>http://blogs.msdn.com/davidebb/comments/9199694.aspx</comments><wfw:commentRss>http://blogs.msdn.com/davidebb/commentrss.aspx?PostID=9199694</wfw:commentRss><wfw:comment>http://blogs.msdn.com/davidebb/rsscomments.aspx?PostID=9199694</wfw:comment><description>&lt;P&gt;Most Dynamic Data web sites typically only use a single database, with either a Linq To Sql or Entity Framework model over it.&amp;nbsp; But in some cases, you need your site to use multiple databases/models.&amp;nbsp; This came up today in this &lt;A href="http://forums.asp.net/t/1359685.aspx" mce_href="http://forums.asp.net/t/1359685.aspx"&gt;forum thread&lt;/A&gt;.&amp;nbsp; In fact, the original poster (Chris) is the one that came up with a good solution, and that’s what my sample app in this post is doing (so credits to him!).&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;The full sample is attached at the end, so feel free to get it now if you prefer!&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Note that I’ll cheat a little bit, by doing the following:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;I’ll only use one Northwind database (bear with me here!) &lt;/LI&gt;
&lt;LI&gt;I’ll create both a Linq To Sql and an Entity Framework model over it&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;The main reason for doing this is to avoid having to include two MDF files in the sample.&amp;nbsp; There is actually another reason: by using the same DB, we know we’re going to get some name conflicts between the two models, which forces us to make sure that we’re able to handle that case!&lt;/P&gt;
&lt;P&gt;Also, the fact that the two models use different ORMs brings up an interesting problem, because normally in Dynamic Data you use a different project template for L2S vs EF.&amp;nbsp; Here, we’re going to want some kind of hybrid.&amp;nbsp; Specifically, what’s different between the two are the Page Templates, since they use different DataSource controls (LinqDataSource vs. EntityDataSource).&amp;nbsp; However, other things like the Field Templates can and should be shared (always avoid duplication when possible!).&amp;nbsp; So we’re aiming for a folder structure that looks like this:&lt;/P&gt;
&lt;P&gt;&lt;IMG title=image style="BORDER-TOP-WIDTH: 0px; DISPLAY: inline; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" height=172 alt=image src="http://blogs.msdn.com/blogfiles/davidebb/WindowsLiveWriter/UsingDynamicDatawithmultipledatabases_F887/image_3.png" width=224 border=0 mce_src="http://blogs.msdn.com/blogfiles/davidebb/WindowsLiveWriter/UsingDynamicDatawithmultipledatabases_F887/image_3.png"&gt; &lt;/P&gt;
&lt;P&gt;So basically, we keep the DynamicData folder for the shared stuff, and use EF and L2S folders for the different stuff.&amp;nbsp; What they contain is completely unmodified from what you’d find in the default project templates.&lt;/P&gt;
&lt;P&gt;The next step it to deal with the routes.&amp;nbsp; Our goal is to use different routes for each model so they don’t conflict.&amp;nbsp; e.g. the URL might look like “&lt;STRONG&gt;L2S_NW&lt;/STRONG&gt;/Products/List.aspx” for L2S, and “&lt;STRONG&gt;EF_NW&lt;/STRONG&gt;/Products/List.aspx” for the EF model.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;Let’s take a look at global.asax, which deals with the two things we just discussed: the folder structure and the route set up.&amp;nbsp; Read through the comments as they cover some important points:&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: green"&gt;// Keep track of the mapping from db name to MetaModel.  This is used in default.aspx
&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;public static &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Dictionary&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: blue"&gt;string&lt;/SPAN&gt;, &lt;SPAN style="COLOR: #2b91af"&gt;MetaModel&lt;/SPAN&gt;&amp;gt; Models = &lt;SPAN style="COLOR: blue"&gt;new &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Dictionary&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: blue"&gt;string&lt;/SPAN&gt;, &lt;SPAN style="COLOR: #2b91af"&gt;MetaModel&lt;/SPAN&gt;&amp;gt;();

&lt;SPAN style="COLOR: blue"&gt;public static void &lt;/SPAN&gt;RegisterRoutes(&lt;SPAN style="COLOR: #2b91af"&gt;RouteCollection &lt;/SPAN&gt;routes) {
    &lt;SPAN style="COLOR: green"&gt;// Register both models along with their routes
    &lt;/SPAN&gt;RegisterContext(routes, &lt;SPAN style="COLOR: #a31515"&gt;"L2S_NW"&lt;/SPAN&gt;, &lt;SPAN style="COLOR: blue"&gt;typeof&lt;/SPAN&gt;(&lt;SPAN style="COLOR: #2b91af"&gt;NorthwindLinqToSqlDataContext&lt;/SPAN&gt;), &lt;SPAN style="COLOR: #a31515"&gt;"~/DynamicData_L2S"&lt;/SPAN&gt;);
    RegisterContext(routes, &lt;SPAN style="COLOR: #a31515"&gt;"EF_NW"&lt;/SPAN&gt;, &lt;SPAN style="COLOR: blue"&gt;typeof&lt;/SPAN&gt;(NorthwindModel.&lt;SPAN style="COLOR: #2b91af"&gt;NorthwindEntities&lt;/SPAN&gt;), &lt;SPAN style="COLOR: #a31515"&gt;"~/DynamicData_EF"&lt;/SPAN&gt;);
}

&lt;SPAN style="COLOR: blue"&gt;private static void &lt;/SPAN&gt;RegisterContext(&lt;SPAN style="COLOR: #2b91af"&gt;RouteCollection &lt;/SPAN&gt;routes, &lt;SPAN style="COLOR: blue"&gt;string &lt;/SPAN&gt;dbName, &lt;SPAN style="COLOR: #2b91af"&gt;Type &lt;/SPAN&gt;contextType, &lt;SPAN style="COLOR: blue"&gt;string &lt;/SPAN&gt;ddFolder) {
    &lt;SPAN style="COLOR: green"&gt;// Set the Dynamic Data folder to the custom one that was passed in.  However, keep the
    // field templates in the central location since they're the same for EF and L2S
    &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;var &lt;/SPAN&gt;model = &lt;SPAN style="COLOR: blue"&gt;new &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;MetaModel&lt;/SPAN&gt;() {
        DynamicDataFolderVirtualPath = ddFolder,
        FieldTemplateFactory = &lt;SPAN style="COLOR: blue"&gt;new &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;FieldTemplateFactory&lt;/SPAN&gt;() {
            TemplateFolderVirtualPath = &lt;SPAN style="COLOR: #a31515"&gt;"~/DynamicData/FieldTemplates"
        &lt;/SPAN&gt;}
    };

    model.RegisterContext(contextType, &lt;SPAN style="COLOR: blue"&gt;new &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;ContextConfiguration&lt;/SPAN&gt;() { ScaffoldAllTables = &lt;SPAN style="COLOR: blue"&gt;true &lt;/SPAN&gt;});

    &lt;SPAN style="COLOR: green"&gt;// Register the route, using the db name as the prefix. Also, we add the db name
    // as a constraint to make sure that we always build the correct URL for a given db
    &lt;/SPAN&gt;routes.Add(&lt;SPAN style="COLOR: blue"&gt;new &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;DynamicDataRoute&lt;/SPAN&gt;(&lt;SPAN style="COLOR: #a31515"&gt;"{dbname}/{table}/{action}.aspx"&lt;/SPAN&gt;) {
        Constraints = &lt;SPAN style="COLOR: blue"&gt;new &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;RouteValueDictionary&lt;/SPAN&gt;(&lt;SPAN style="COLOR: blue"&gt;new &lt;/SPAN&gt;{
            action = &lt;SPAN style="COLOR: #a31515"&gt;"List|Details|Edit|Insert"&lt;/SPAN&gt;,
            dbname = dbName }),
        Model = model
    });

    Models[dbName] = model;
}&lt;/PRE&gt;
&lt;P&gt;Next, let’s look at what needs to happen in default.aspx.&amp;nbsp; Normally, it only lists the tables from one model.&amp;nbsp; Our goal is to allow the model to be selected via a dbname query string parameter.&amp;nbsp; e.g. “Default.aspx?dbname=L2S_NW” or “Default.aspx?dbname=EF_NW”.&lt;/P&gt;
&lt;P&gt;First, in the markup, we’ll add a GridView that will act as a model selector, above the existing GridView that lists the tables:&lt;/P&gt;&lt;PRE class=code&gt;    &lt;SPAN style="COLOR: blue"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;asp&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;:&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;GridView &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;ID&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="ModelMenu" &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;runat&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="server" &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;AutoGenerateColumns&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="false"
        &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;CssClass&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="gridview" &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;AlternatingRowStyle-CssClass&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="even"&amp;gt;
        &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;Columns&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;
            &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;asp&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;:&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;TemplateField &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;HeaderText&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="Model Name" &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;SortExpression&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="TableName"&amp;gt;
                &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;ItemTemplate&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;
                    &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;asp&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;:&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;HyperLink &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;ID&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="HyperLink1" &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;runat&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="server"
                        &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;NavigateUrl&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;='&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: #ffee62"&gt;&amp;lt;%&lt;/SPAN&gt;#"?dbname=" + Eval("Key") &lt;SPAN style="BACKGROUND: #ffee62"&gt;%&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;'&amp;gt;
                            &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: #ffee62"&gt;&amp;lt;%&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;# &lt;/SPAN&gt;Eval(&lt;SPAN style="COLOR: #a31515"&gt;"Key"&lt;/SPAN&gt;) &lt;SPAN style="BACKGROUND: #ffee62"&gt;%&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;asp&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;:&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;HyperLink&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;
                &amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;ItemTemplate&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;
            &amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;asp&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;:&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;TemplateField&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;
        &amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;Columns&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;
    &amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;asp&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;:&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;GridView&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;
&lt;/SPAN&gt;&lt;/PRE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P&gt;The interesting part here is the Hyperlink databinding, and how it uses the dictionary key.&amp;nbsp; Now let’s see what the code behind has:&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;protected void &lt;/SPAN&gt;Page_Load(&lt;SPAN style="COLOR: blue"&gt;object &lt;/SPAN&gt;sender, &lt;SPAN style="COLOR: #2b91af"&gt;EventArgs &lt;/SPAN&gt;e) {
    &lt;SPAN style="COLOR: #2b91af"&gt;Dictionary&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: blue"&gt;string&lt;/SPAN&gt;, &lt;SPAN style="COLOR: #2b91af"&gt;MetaModel&lt;/SPAN&gt;&amp;gt; models = ASP.&lt;SPAN style="COLOR: #2b91af"&gt;global_asax&lt;/SPAN&gt;.Models;

    &lt;SPAN style="COLOR: green"&gt;// Bind the first grid to the list of models
    &lt;/SPAN&gt;ModelMenu.DataSource = models;
    ModelMenu.DataBind();

    &lt;SPAN style="COLOR: green"&gt;// If we got a model name from the query string, bind the second grid to its tables
    &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;string &lt;/SPAN&gt;dbName = Request.QueryString[&lt;SPAN style="COLOR: #a31515"&gt;"dbname"&lt;/SPAN&gt;];
    &lt;SPAN style="COLOR: blue"&gt;if &lt;/SPAN&gt;(!&lt;SPAN style="COLOR: #2b91af"&gt;String&lt;/SPAN&gt;.IsNullOrEmpty(dbName)) {
        Menu1.DataSource = models[dbName].VisibleTables;
        Menu1.DataBind();
    }
}&lt;/PRE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P&gt;Now try running the complete app (attached below).&amp;nbsp; When you first get to default.aspx, you’ll get the list of models.&amp;nbsp; Once you select one, you’ll also see its tables because the dbname parameter is added to the query string.&lt;/P&gt;
&lt;P&gt;Then try actually clicking on some of the tables for one of the models, and observe that the URL is only targeting that model (i.e. it starts with EF_NW or L2S_NW).&lt;/P&gt;
&lt;P&gt;Hopefully, this gives you an idea of what it takes to use multiple models.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9199694" width="1" height="1"&gt;</description><enclosure url="http://blogs.msdn.com/davidebb/attachment/9199694.ashx" length="632912" type="application/x-zip-compressed" /><category domain="http://blogs.msdn.com/davidebb/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://blogs.msdn.com/davidebb/archive/tags/Dynamic+Data/default.aspx">Dynamic Data</category></item><item><title>Handling database exceptions in Dynamic Data</title><link>http://blogs.msdn.com/davidebb/archive/2008/12/11/handling-database-exceptions-in-dynamic-data.aspx</link><pubDate>Fri, 12 Dec 2008 01:53:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9198977</guid><dc:creator>davidebb</dc:creator><slash:comments>3</slash:comments><comments>http://blogs.msdn.com/davidebb/comments/9198977.aspx</comments><wfw:commentRss>http://blogs.msdn.com/davidebb/commentrss.aspx?PostID=9198977</wfw:commentRss><wfw:comment>http://blogs.msdn.com/davidebb/rsscomments.aspx?PostID=9198977</wfw:comment><description>&lt;P&gt;This post was prompted from a &lt;A href="http://forums.asp.net/t/1357572.aspx" mce_href="http://forums.asp.net/t/1357572.aspx"&gt;forum thread&lt;/A&gt; in which the user wanted to display database errors in a Dynamic Data page, instead of the default behavior that ends up with an unhandled exception (or an AJAX error with partial rendering).&lt;/P&gt;
&lt;P&gt;When using Linq To Sql, this can be done fairly easily in a couple different ways, by wrapping the exception in a ValidationException.&amp;nbsp; To do it globally for a DataContext, you can do something like this:&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;public override void &lt;/SPAN&gt;SubmitChanges(System.Data.Linq.&lt;SPAN style="COLOR: #2b91af"&gt;ConflictMode &lt;/SPAN&gt;failureMode) {
    &lt;SPAN style="COLOR: blue"&gt;try &lt;/SPAN&gt;{
        &lt;SPAN style="COLOR: blue"&gt;base&lt;/SPAN&gt;.SubmitChanges(failureMode);
    }
    &lt;SPAN style="COLOR: blue"&gt;catch &lt;/SPAN&gt;(&lt;SPAN style="COLOR: #2b91af"&gt;Exception &lt;/SPAN&gt;e) {
        &lt;SPAN style="COLOR: blue"&gt;throw new &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;ValidationException&lt;/SPAN&gt;(&lt;SPAN style="COLOR: blue"&gt;null&lt;/SPAN&gt;, e);
    }
}&lt;/PRE&gt;
&lt;P&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;And to do it with more granularity, you can use one of the partial methods on the DataContext.&amp;nbsp; e.g.&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;partial void &lt;/SPAN&gt;DeleteCategory(&lt;SPAN style="COLOR: #2b91af"&gt;Category &lt;/SPAN&gt;instance) {
    &lt;SPAN style="COLOR: blue"&gt;try &lt;/SPAN&gt;{
        ExecuteDynamicDelete(instance);
    }
    &lt;SPAN style="COLOR: blue"&gt;catch &lt;/SPAN&gt;(&lt;SPAN style="COLOR: #2b91af"&gt;Exception &lt;/SPAN&gt;e) {
        &lt;SPAN style="COLOR: blue"&gt;throw new &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;ValidationException&lt;/SPAN&gt;(&lt;SPAN style="COLOR: blue"&gt;null&lt;/SPAN&gt;, e);
    }
}&lt;/PRE&gt;
&lt;P&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;A few notes about this:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;By passing null as the text, it uses the original exception’s text.&amp;nbsp; You very well may want to use a custom error message instead &lt;/LI&gt;
&lt;LI&gt;Instead of doing it ‘blindly’, you may want to look at the database exception and selectively decide to wrap it or not.&amp;nbsp; If you don’t want to wrap it, just use the ‘throw;’ statement to rethrow it unchanged. &lt;/LI&gt;
&lt;LI&gt;There is a small issue in the default templates that you need to fix if you want to handle DB exceptions happening during a Delete: in both list.aspx and details.aspx, you’ll find &lt;EM&gt;CausesValidation="false"&lt;/EM&gt;.&amp;nbsp; You need to either get rid of it or set it to true (which is the default). &lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;But now, let’s try to do the same thing with Entity Framework.&amp;nbsp; Unfortunately, ObjectContext doesn’t have as many useful hooks as Linq To Sql’s DataContext (this will change in the next version), so the techniques above are not available.&lt;/P&gt;
&lt;P&gt;However, there is a fairly easy workaround that can be used, which involves using a custom derived DynamicValidator control.&amp;nbsp; Here are the steps to do this (full sample attached at the end of this post).&lt;/P&gt;
&lt;P&gt;First, let’s create the derived DynamicValidator, as follows.&amp;nbsp; I’ll let the comments speak for themselves:&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: gray"&gt;/// &amp;lt;summary&amp;gt;
/// &lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;By default, Dynamic Data doesn't blindly display all exceptions in the page,
&lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;/// &lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;as some database exceptions may contain sensitive info.  Instead, it only displays
&lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;/// &lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;ValidationExceptions.
&lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;/// &lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;However, in some cases you need to display other exceptions as well.  This code
&lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;/// &lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;shows how to achieve this.
&lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;/// &amp;lt;/summary&amp;gt;
&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;public class &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;MyDynamicValidator &lt;/SPAN&gt;: &lt;SPAN style="COLOR: #2b91af"&gt;DynamicValidator &lt;/SPAN&gt;{

    &lt;SPAN style="COLOR: blue"&gt;protected override void &lt;/SPAN&gt;ValidateException(&lt;SPAN style="COLOR: #2b91af"&gt;Exception &lt;/SPAN&gt;exception) {
        &lt;SPAN style="COLOR: green"&gt;// If it's not already an exception that DynamicValidator looks at
        &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;if &lt;/SPAN&gt;(!(exception &lt;SPAN style="COLOR: blue"&gt;is &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;IDynamicValidatorException&lt;/SPAN&gt;) &amp;amp;&amp;amp; !(exception &lt;SPAN style="COLOR: blue"&gt;is &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;ValidationException&lt;/SPAN&gt;)) {
            &lt;SPAN style="COLOR: green"&gt;// Find the most inner exception
            &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;while &lt;/SPAN&gt;(exception.InnerException != &lt;SPAN style="COLOR: blue"&gt;null&lt;/SPAN&gt;) {
                exception = exception.InnerException;
            }

            &lt;SPAN style="COLOR: green"&gt;// Wrap it in a ValidationException so the base code doesn't ignore it
            &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;if &lt;/SPAN&gt;(ExceptionShouldBeDisplayedInPage(exception)) {
                exception = &lt;SPAN style="COLOR: blue"&gt;new &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;ValidationException&lt;/SPAN&gt;(&lt;SPAN style="COLOR: blue"&gt;null&lt;/SPAN&gt;, exception);
            }
        }

        &lt;SPAN style="COLOR: green"&gt;// Call the base on the (possibly) modified exception
        &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;base&lt;/SPAN&gt;.ValidateException(exception);
    }

    &lt;SPAN style="COLOR: blue"&gt;private bool &lt;/SPAN&gt;ExceptionShouldBeDisplayedInPage(&lt;SPAN style="COLOR: #2b91af"&gt;Exception &lt;/SPAN&gt;e) {
        &lt;SPAN style="COLOR: green"&gt;// This is where you may want to add logic that looks at the exception and
        // decides whether it should indeed be shown in the page
        &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;return true&lt;/SPAN&gt;;
    }
}&lt;/PRE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P&gt;Then you need to make all the pages use it.&amp;nbsp; The simplest way to do it is via a little know but powerful feature: tag remapping.&amp;nbsp; Here is what you need to have in web.config:&lt;/P&gt;&lt;PRE class=code&gt;    &lt;SPAN style="COLOR: blue"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;pages&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: #a31515"&gt;tagMapping&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;
        &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;add &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;tagType&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;=&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt;System.Web.DynamicData.DynamicValidator&lt;/SPAN&gt;" &lt;SPAN style="COLOR: red"&gt;mappedTagType&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;=&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt;MyDynamicValidator&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt;/&amp;gt;
      &amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;tagMapping&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;
    &amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;pages&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;
&lt;/SPAN&gt;&lt;/PRE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P&gt;And then you also need to do the same as the 3rd bullet point above: get rid of &lt;EM&gt;CausesValidation="false"&lt;/EM&gt; in the pages.&lt;/P&gt;
&lt;P&gt;And that’s all!&amp;nbsp; You should now see the error messages directly in the page.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9198977" width="1" height="1"&gt;</description><enclosure url="http://blogs.msdn.com/davidebb/attachment/9198977.ashx" length="590755" type="application/x-zip-compressed" /><category domain="http://blogs.msdn.com/davidebb/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://blogs.msdn.com/davidebb/archive/tags/Dynamic+Data/default.aspx">Dynamic Data</category></item><item><title>Fun with T4 templates and Dynamic Data</title><link>http://blogs.msdn.com/davidebb/archive/2008/11/26/fun-with-t4-templates-and-dynamic-data.aspx</link><pubDate>Thu, 27 Nov 2008 06:18:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9145731</guid><dc:creator>davidebb</dc:creator><slash:comments>14</slash:comments><comments>http://blogs.msdn.com/davidebb/comments/9145731.aspx</comments><wfw:commentRss>http://blogs.msdn.com/davidebb/commentrss.aspx?PostID=9145731</wfw:commentRss><wfw:comment>http://blogs.msdn.com/davidebb/rsscomments.aspx?PostID=9145731</wfw:comment><description>&lt;P&gt;T4 templates have been a pretty popular topic lately.&amp;nbsp; If you have no idea what they are, don’t feel bad, I didn’t either only a couple weeks ago!&amp;nbsp; In a nutshell, it’s a simple template processor that’s built into VS and allows for all kind of cool code generation scenario.&amp;nbsp; For a bunch of information about them, check out the following two blogs:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A href="http://blogs.msdn.com/garethj/default.aspx" mce_href="http://blogs.msdn.com/garethj/default.aspx"&gt;GarethJ’s blog&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://www.olegsych.com/" mce_href="http://www.olegsych.com/"&gt;Oleg Sych’s blog&lt;/A&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;The basic idea is that you can drop a hello.tt file into a project, and it will generate a hello.cs (or hello.anything) file via its template.&amp;nbsp; The template syntax of .tt files is very similar to ASP.NET’s &amp;lt;% … %&amp;gt; blocks, except that they use &amp;lt;# … #&amp;gt; instead.&lt;/P&gt;
&lt;P&gt;For a cool example of what you can do with T4, check out &lt;A href="http://blogs.msdn.com/dsimmons/archive/2008/10/27/using-t4-templates-to-generate-ef-classes.aspx" mce_href="http://blogs.msdn.com/dsimmons/archive/2008/10/27/using-t4-templates-to-generate-ef-classes.aspx"&gt;this post&lt;/A&gt; from Danny Simmons, which&amp;nbsp; shares out a .tt which generates all the Entity Framework classes automatically from an edmx file.&amp;nbsp; What’s really nice is that you can easily customize the template to generate exactly the code that you want, instead of being locked into what the designer normally generates.&lt;/P&gt;
&lt;H3&gt;So how does that have anything to do with Dynamic Data?&lt;/H3&gt;
&lt;P&gt;One weakness we currently have with Dynamic Data is that we don’t have a great way to get started with a custom page.&amp;nbsp; Suppose you start out with a web app in full scaffold mode, and find the need to customize the Details page for Products.&amp;nbsp; The ‘standard’ procedure to do this is:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Create a Products folder under ~/DynamicData/CustomPages&lt;/LI&gt;
&lt;LI&gt;Copy ~/DynamicData/PageTemplates/Details.aspx into&amp;nbsp; it&lt;/LI&gt;
&lt;LI&gt;Modify the copied file to do the customization you need&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;While this generally works, it has one big weakness: you need to start your customization from a ‘generic’ file which knows nothing about your specific table.&amp;nbsp; e.g. you start out with a &amp;lt;asp:DetailsView&amp;gt; control that uses AutoGenerateRows to generate all the fields.&amp;nbsp; So if you want to do any kind of real UI customization, you’ll likely have to do a bunch of repetitive steps, e.g.&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Get rid of the DetailsView and replace it with a FormView (or ListView) so you can get full control over the layout&lt;/LI&gt;
&lt;LI&gt;In the FormView’s item template, you’ll then need to add one &amp;lt;asp:DynamicControl&amp;gt; for each field that you want to display, along with formatting UI between them (e.g. &amp;lt;tr&amp;gt;/&amp;lt;td&amp;gt;).&lt;/LI&gt;&lt;/UL&gt;
&lt;H3&gt;A T4 template to the rescue&lt;/H3&gt;
&lt;P&gt;In a few hours, I was able to put together a quick T4 template that replaces most of those repetitive steps.&amp;nbsp; The steps using this template become simply:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Create a Products folder under ~/DynamicData/CustomPages (as above)&lt;/LI&gt;
&lt;LI&gt;Drop Details.tt into it, and instantly it generates the aspx file, all expanded out with a FormView and all the DynamicControls! &lt;STRONG&gt;This .tt file is attached at the end of this post.&lt;/STRONG&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;While this is cool, there is one thing that is a bit strange about it: you’re left with a .tt file you don’t want in your project:&lt;/P&gt;
&lt;P&gt;&lt;IMG title=image style="BORDER-RIGHT: 0px; BORDER-TOP: 0px; DISPLAY: inline; BORDER-LEFT: 0px; BORDER-BOTTOM: 0px" height=184 alt=image src="http://blogs.msdn.com/blogfiles/davidebb/WindowsLiveWriter/FunwithT4templatesandDynamicData_F7BC/image_13.png" width=303 border=0 mce_src="http://blogs.msdn.com/blogfiles/davidebb/WindowsLiveWriter/FunwithT4templatesandDynamicData_F7BC/image_13.png"&gt; &lt;/P&gt;
&lt;P&gt;And since details.tt file generates details.aspx file, you can’t really change the aspx until you delete the .tt file.&amp;nbsp; Unfortunately, VS makes this more difficult than you would think because the two files are linked to each other.&amp;nbsp; The best steps I found to delete it are:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Right click the .tt file and choose Exclude From Project&lt;/LI&gt;
&lt;LI&gt;Right click the Products folder in open it in Windows Explorer&lt;/LI&gt;
&lt;LI&gt;Delete the .tt file in the explorer&lt;/LI&gt;
&lt;LI&gt;Back in VS, click Show All Files in the solution explorer.&amp;nbsp; You should see the aspx&lt;/LI&gt;
&lt;LI&gt;Now right click it and Include it in the project&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;I know, that’s painful!!&amp;nbsp; Ideally, what we really want to do is use the .tt do to a one time transform, but never actually have it be part of the project.&amp;nbsp; At this point, I’m not yet sure how to do this, but I’m hopeful that there is a way.&amp;nbsp; Suggestions are welcome! :)&lt;/P&gt;
&lt;H3&gt;&lt;/H3&gt;
&lt;H3&gt;How does the template work?&lt;/H3&gt;
&lt;P&gt;In order to perform its task, the template needs to figure out what all the entity type’s fields are for the custom page.&amp;nbsp; Doing this is a bit non-trivial, and what I do here is not as clean as it could be, as this is just a quick prototype.&amp;nbsp; Here is a brief description of what it does:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Based on the folder name, it knows what the Entity Set name is (e.g. Products)&lt;/LI&gt;
&lt;LI&gt;It then locates the app’s assembly in bin (caveat: this only works in Web Apps, not Web Sites!)&lt;/LI&gt;
&lt;LI&gt;It copies it to a temp location and loads it from there, to avoid locking the bin assembly&lt;/LI&gt;
&lt;LI&gt;In the assembly, it finds the DataContext/ObjectContext (it handles both Linq To Sql and Entity Framework)&lt;/LI&gt;
&lt;LI&gt;From the context and the entity set name, and can know what the Entity Type is&lt;/LI&gt;
&lt;LI&gt;Once it has that, it knows the fields and can generate the page!&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;If you look at the t4 files, you’ll see all this logic at the end.&amp;nbsp; That part is certainly quick and dirty, and could use some rewriting.&amp;nbsp; But what comes before it is a pretty clean template that’s easy to tweak to your needs.&amp;nbsp; e.g. &lt;/P&gt;&lt;PRE class=code&gt;                    &lt;SPAN style="COLOR: gray"&gt;&amp;lt;table class="detailstable"&amp;gt;
&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: gold"&gt;&amp;lt;#&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: #f0f8ff; COLOR: #191970"&gt; foreach (var prop in data.Properties) { &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: gold"&gt;#&amp;gt;
&lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;                        &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;tr&amp;gt;
                            &amp;lt;th&amp;gt;
                                &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: gold"&gt;&amp;lt;#=&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: #f0f8ff; COLOR: #191970"&gt; prop.Name &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: gold"&gt;#&amp;gt;
&lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;                            &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;/th&amp;gt;
                            &amp;lt;td&amp;gt;
                                &amp;lt;asp:DynamicControl DataField="&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: gold"&gt;&amp;lt;#=&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: #f0f8ff; COLOR: #191970"&gt; prop.Name &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: gold"&gt;#&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;" runat="server" /&amp;gt;
                            &amp;lt;/td&amp;gt;
                        &amp;lt;/tr&amp;gt;
&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: gold"&gt;&amp;lt;#&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: #f0f8ff; COLOR: #191970"&gt; } &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: gold"&gt;#&amp;gt;
&lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;                    &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;/table&amp;gt;
&lt;/SPAN&gt;&lt;/PRE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P&gt;As you can see, it looks very much like inline code in an aspx file, except that instead of executing at runtime on the web server, it executes in Visual Studio to generate a file that becomes part of the project.&lt;/P&gt;
&lt;H3&gt;What about all the other views?&lt;/H3&gt;
&lt;P&gt;So I’m only talking about Details.tt/Details.aspx.&amp;nbsp; What about the other Dynamic Data views: List, Edit, Insert?&amp;nbsp; Well, those would all work in pretty much the same way, and I simply haven’t had a chance to get to them.&amp;nbsp; For now, I just wanted to get this first T4 file out as a proof of concept that shows the kind of things that can be done.&amp;nbsp; Contributions are welcome! :)&lt;/P&gt;
&lt;H3&gt;Conclusion&lt;/H3&gt;
&lt;P&gt;Clearly, a lot of what I describe here is pretty raw, and it’s only a very early prototype.&amp;nbsp; But I think it should be enough to convey the potential power of design time file generation via T4 templates.&amp;nbsp; Later, I’d like to get better integration with VS.&amp;nbsp; e.g instead of dropping the .tt file in the project and later having to delete it, it’d be nice to get a custom action by right clicking on the CustomPages folder, that would let you generate the aspx file.&amp;nbsp; It would still use T4 under the cover, but you wouldn’t have to see it unless you want to.&lt;/P&gt;
&lt;P&gt;Hopefully, I’ll&amp;nbsp; be writing more about this in the future if there is interest.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9145731" width="1" height="1"&gt;</description><enclosure url="http://blogs.msdn.com/davidebb/attachment/9145731.ashx" length="2664" type="application/x-zip-compressed" /><category domain="http://blogs.msdn.com/davidebb/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://blogs.msdn.com/davidebb/archive/tags/Dynamic+Data/default.aspx">Dynamic Data</category><category domain="http://blogs.msdn.com/davidebb/archive/tags/T4/default.aspx">T4</category></item><item><title>Using User Controls as Page Templates in Dynamic Data</title><link>http://blogs.msdn.com/davidebb/archive/2008/11/25/using-user-controls-as-page-templates-in-dynamic-data.aspx</link><pubDate>Wed, 26 Nov 2008 05:58:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9143163</guid><dc:creator>davidebb</dc:creator><slash:comments>4</slash:comments><comments>http://blogs.msdn.com/davidebb/comments/9143163.aspx</comments><wfw:commentRss>http://blogs.msdn.com/davidebb/commentrss.aspx?PostID=9143163</wfw:commentRss><wfw:comment>http://blogs.msdn.com/davidebb/rsscomments.aspx?PostID=9143163</wfw:comment><description>&lt;P&gt;Dynamic Data has the concept of Page Templates, which are pages that live under ~/DynamicData/PageTemplates and are used by default for all tables.&amp;nbsp; Recently a &lt;A href="http://forums.asp.net/t/1349669.aspx" mce_href="http://forums.asp.net/t/1349669.aspx"&gt;user on the forum&lt;/A&gt; asked whether they could use User Controls instead of Pages for those templates.&lt;/P&gt;
&lt;P&gt;To me, this means potentially two distinct scenarios, and I tried to address both in this post:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;&lt;STRONG&gt;Using routing&lt;/STRONG&gt;: in this scenario, you still want all your requests to go through the routing engine, but have the user control templates somehow get used.&amp;nbsp; The URLs here would still&amp;nbsp; look identical to what they are in a default Dynamic Data app, e.g.&amp;nbsp; /app/Products/List.aspx (or whatever you set them to be in your routes).&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;No routing&lt;/STRONG&gt;: in this scenario, you want the URL to go directly to a specific .aspx page, and then have that page do the right thing to use Dynamic Data through the User Control templates.&lt;/LI&gt;&lt;/OL&gt;
&lt;H3&gt;Creating the User Controls&lt;/H3&gt;
&lt;P&gt;First, let’s look at what will be the same for both cases.&amp;nbsp; Under ~/DynamicData/PageTemplates, I deleted all the aspx files (to prove that they’re not used), and instead created matching ascx files (i.e. User Controls).&amp;nbsp; Those user controls contain essentially the same things that were in the pages, minus all the ‘outer’ stuff (e.g. things that relate to the master page).&lt;/P&gt;
&lt;H3&gt;Making it work using routing&lt;/H3&gt;
&lt;P&gt;Now let’s look specifically at case #1 above, where we want to use routing.&amp;nbsp; First, we need to make a small change to the route to use a custom route handler:&lt;/P&gt;&lt;PRE class=code&gt;routes.Add(&lt;SPAN style="COLOR: blue"&gt;new &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;DynamicDataRoute&lt;/SPAN&gt;(&lt;SPAN style="COLOR: #a31515"&gt;"{table}/{action}.aspx"&lt;/SPAN&gt;) {
    Constraints = &lt;SPAN style="COLOR: blue"&gt;new &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;RouteValueDictionary&lt;/SPAN&gt;(&lt;SPAN style="COLOR: blue"&gt;new &lt;/SPAN&gt;{ action = &lt;SPAN style="COLOR: #a31515"&gt;"List|Details|Edit|Insert" &lt;/SPAN&gt;}),
    Model = model,
&lt;STRONG&gt;    RouteHandler = &lt;SPAN style="COLOR: blue"&gt;new &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;CustomDynamicDataRouteHandler&lt;/SPAN&gt;()
&lt;/STRONG&gt;});&lt;/PRE&gt;
&lt;P&gt;Note how we set RouteHandler to our own custom handler type.&amp;nbsp; Now let see what this type looks like:&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;public class &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;CustomDynamicDataRouteHandler &lt;/SPAN&gt;: &lt;SPAN style="COLOR: #2b91af"&gt;DynamicDataRouteHandler &lt;/SPAN&gt;{
    &lt;SPAN style="COLOR: blue"&gt;public override &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;IHttpHandler &lt;/SPAN&gt;CreateHandler(&lt;SPAN style="COLOR: #2b91af"&gt;DynamicDataRoute &lt;/SPAN&gt;route, &lt;SPAN style="COLOR: #2b91af"&gt;MetaTable &lt;/SPAN&gt;table, &lt;SPAN style="COLOR: blue"&gt;string &lt;/SPAN&gt;action) {
        &lt;SPAN style="COLOR: green"&gt;// Always instantiate the same page.  The page itself has the logic to load the right user control
        &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;return &lt;/SPAN&gt;(&lt;SPAN style="COLOR: #2b91af"&gt;IHttpHandler&lt;/SPAN&gt;)&lt;SPAN style="COLOR: #2b91af"&gt;BuildManager&lt;/SPAN&gt;.CreateInstanceFromVirtualPath(&lt;SPAN style="COLOR: #a31515"&gt;"~/RoutedTestPage.aspx"&lt;/SPAN&gt;, &lt;SPAN style="COLOR: blue"&gt;typeof&lt;/SPAN&gt;(&lt;SPAN style="COLOR: #2b91af"&gt;Page&lt;/SPAN&gt;));
    }
}&lt;/PRE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P&gt;It’s basically a trivial handler which always instantiates the same page!&amp;nbsp; That may look strange, but the idea is that all the relevant information is carried by the route data, which that page can then make use of.&amp;nbsp; Now let’s see what we’re doing in this one page.&amp;nbsp; It’s itself pretty trivial, with just a bit of logic in its Page_Init:&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;protected void &lt;/SPAN&gt;Page_Init(&lt;SPAN style="COLOR: blue"&gt;object &lt;/SPAN&gt;sender, &lt;SPAN style="COLOR: #2b91af"&gt;EventArgs &lt;/SPAN&gt;e) {
    &lt;SPAN style="COLOR: green"&gt;// Get table and action from the route data
    &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;MetaTable &lt;/SPAN&gt;table = &lt;SPAN style="COLOR: #2b91af"&gt;DynamicDataRouteHandler&lt;/SPAN&gt;.GetRequestMetaTable(Context);
    &lt;SPAN style="COLOR: blue"&gt;var &lt;/SPAN&gt;requestContext = &lt;SPAN style="COLOR: #2b91af"&gt;DynamicDataRouteHandler&lt;/SPAN&gt;.GetRequestContext(Context);
    &lt;SPAN style="COLOR: blue"&gt;string &lt;/SPAN&gt;action = requestContext.RouteData.GetRequiredString(&lt;SPAN style="COLOR: #a31515"&gt;"action"&lt;/SPAN&gt;);

    &lt;SPAN style="COLOR: green"&gt;// Load the proper user control for the table/action
    &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;string &lt;/SPAN&gt;ucVirtualPath = table.GetScaffoldPageVirtualPath(action);
    ph.Controls.Add(LoadControl(ucVirtualPath));
}&lt;/PRE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P&gt;The first 3 lines show you what it takes to retrieve the MetaTable and action from the route date.&amp;nbsp; Then the next couple lines load the right user control for the situation.&amp;nbsp; GetScaffoldPageVirtualPath is a simple helper method which has logic to locate the proper ascx:&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;public static string &lt;/SPAN&gt;GetScaffoldPageVirtualPath(&lt;SPAN style="COLOR: blue"&gt;this &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;MetaTable &lt;/SPAN&gt;table, &lt;SPAN style="COLOR: blue"&gt;string &lt;/SPAN&gt;viewName) {
    &lt;SPAN style="COLOR: blue"&gt;string &lt;/SPAN&gt;pathPattern = &lt;SPAN style="COLOR: #a31515"&gt;"{0}PageTemplates/{1}.ascx"&lt;/SPAN&gt;;
    &lt;SPAN style="COLOR: blue"&gt;return &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;String&lt;/SPAN&gt;.Format(pathPattern, table.Model.DynamicDataFolderVirtualPath, viewName);
}&lt;/PRE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P&gt;And that’s basically it for the routed case!&lt;/P&gt;
&lt;H3&gt;Making it work without routing&lt;/H3&gt;
&lt;P&gt;Now let’s look at the non-routed case.&amp;nbsp; Here, the routes are not involved, so the URL goes directly to a page.&amp;nbsp; That page is similar to the one above, but with some key differences.&amp;nbsp; Here is what it does in it Page_Init:&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;protected void &lt;/SPAN&gt;Page_Init(&lt;SPAN style="COLOR: blue"&gt;object &lt;/SPAN&gt;sender, &lt;SPAN style="COLOR: #2b91af"&gt;EventArgs &lt;/SPAN&gt;e) {
    &lt;SPAN style="COLOR: green"&gt;// Get table and action from query string
    &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;string &lt;/SPAN&gt;tableName = Request.QueryString[&lt;SPAN style="COLOR: #a31515"&gt;"table"&lt;/SPAN&gt;];
    &lt;SPAN style="COLOR: blue"&gt;string &lt;/SPAN&gt;action = Request.QueryString[&lt;SPAN style="COLOR: #a31515"&gt;"action"&lt;/SPAN&gt;];
    
    &lt;SPAN style="COLOR: green"&gt;// Get the MetaTable and set it in the dynamic data route handler
    &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;MetaTable &lt;/SPAN&gt;table = &lt;SPAN style="COLOR: #2b91af"&gt;MetaModel&lt;/SPAN&gt;.Default.GetTable(tableName);
    &lt;SPAN style="COLOR: #2b91af"&gt;DynamicDataRouteHandler&lt;/SPAN&gt;.SetRequestMetaTable(Context, table);

    &lt;SPAN style="COLOR: green"&gt;// Load the proper user control for the table/action
    &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;string &lt;/SPAN&gt;ucVirtualPath = table.GetScaffoldPageVirtualPath(action);
    ph.Controls.Add(LoadControl(ucVirtualPath));
}&lt;/PRE&gt;
&lt;P&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;The key difference&amp;nbsp; is that it can’t rely on route data being available, so it needs to get the table and action information from&amp;nbsp; somewhere else.&amp;nbsp; You can come up with arbitrary logic for this, but the most obvious way is to just use the query string (e.g. ?table=Products&amp;amp;action=List).&lt;/P&gt;
&lt;P&gt;Then&amp;nbsp; it does sort of the reverse of the case above, and &lt;STRONG&gt;sets &lt;/STRONG&gt;the MetaTable into the route handler.&amp;nbsp; Even though routing is not used, Dynamic Data tries to get the MetaTable from DynamicDataRouteHandler, so having it there allows many things to just work.&lt;/P&gt;
&lt;P&gt;And finally, it loads the user control using the exact same steps as above.&amp;nbsp; And that’s that!&lt;/P&gt;
&lt;P&gt;The code is attached below.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9143163" width="1" height="1"&gt;</description><enclosure url="http://blogs.msdn.com/davidebb/attachment/9143163.ashx" length="607841" type="application/x-zip-compressed" /><category domain="http://blogs.msdn.com/davidebb/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://blogs.msdn.com/davidebb/archive/tags/Dynamic+Data/default.aspx">Dynamic Data</category></item><item><title>ProcessGeneratedCode: A hidden gem for Control Builder writers</title><link>http://blogs.msdn.com/davidebb/archive/2008/11/19/a-hidden-gem-for-control-builder-writers.aspx</link><pubDate>Thu, 20 Nov 2008 03:57:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9126826</guid><dc:creator>davidebb</dc:creator><slash:comments>13</slash:comments><comments>http://blogs.msdn.com/davidebb/comments/9126826.aspx</comments><wfw:commentRss>http://blogs.msdn.com/davidebb/commentrss.aspx?PostID=9126826</wfw:commentRss><wfw:comment>http://blogs.msdn.com/davidebb/rsscomments.aspx?PostID=9126826</wfw:comment><description>&lt;p&gt;If you’ve ever written any non-trivial ASP.NET control, you’re probably familiar with the concept of a Control Builder.&amp;#160; Basically, it’s a class that you associate with your control and that affects the way your control gets processed at parse time.&amp;#160; While ControlBuilder has been around since the ASP.NET 1.0 days, a very powerful new feature was added to it in 3.5 (i.e. VS 2008).&amp;#160; Unfortunately, we never had a chance to tell people about it, and a web search reveals that essentially no one knows about it!&amp;#160; Pretty unfortunate, and obviously, the point of this post is to change that. :-)&lt;/p&gt;  &lt;p&gt;So what is this super cool feature?&amp;#160; Simply put, it lets the ControlBuilder party on the CodeDom tree used for code generation of the page.&amp;#160; That means a ControlBuilder can inspect what’s being generated, and make arbitrary changes to it.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Warning&lt;/strong&gt;: this post assumes some basic knowledge of CodeDom.&amp;#160; If you are not familiar with it, you may want to get a basic introduction to it on MSDN or elsewhere before continuing.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h2&gt;How do you use this?&lt;/h2&gt;  &lt;p&gt;To use this feature, all you have to do is override the new ProcessGeneratedCode() method on ControlBuilder.&amp;#160; here is what this method looks like:&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: green"&gt;//
// Summary:
//     Enables custom control builders to access the generated Code Document Object
//     Model (CodeDom) and insert and modify code during the process of parsing
//     and building controls.
//
// Parameters:
//   codeCompileUnit:
//     The root container of a CodeDOM graph of the control that is being built.
//
//   baseType:
//     The base type of the page or user control that contains the control that
//     is being built.
//
//   derivedType:
//     The derived type of the page or user control that contains the control that
//     is being built.
//
//   buildMethod:
//     The code that is used to build the control.
//
//   dataBindingMethod:
//     The code that is used to build the data-binding method of the control.
&lt;/span&gt;&lt;span style="color: blue"&gt;public virtual void &lt;/span&gt;ProcessGeneratedCode(&lt;span style="color: #2b91af"&gt;CodeCompileUnit &lt;/span&gt;codeCompileUnit, &lt;span style="color: #2b91af"&gt;CodeTypeDeclaration &lt;/span&gt;baseType, &lt;span style="color: #2b91af"&gt;CodeTypeDeclaration &lt;/span&gt;derivedType, &lt;span style="color: #2b91af"&gt;CodeMemberMethod &lt;/span&gt;buildMethod, &lt;span style="color: #2b91af"&gt;CodeMemberMethod &lt;/span&gt;dataBindingMethod);&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;So basically you get passed a bunch of CodeDom objects and you get to party on them.&amp;#160; It may seem a bit confusing at first to get passed so many different things, but they all make sense in various scenarios.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;The CodeCompileUnit is the top level construct, which you would use for instance if you wanted to generate new classes. &lt;/li&gt;

  &lt;li&gt;Then you have the two CodeTypeDeclarations, which represent the classes that are generated for this page.&amp;#160; The reason there are two has to do with how the page is generated.&amp;#160; First, there is a partial base class just has control declaration, and gets merged with the code behind class the user writes (in Web Sites, Web Applications are a bit different).&amp;#160; Then we derive another class from it, which has the bulk of the code that makes the page run.&amp;#160; I know this seems confusing, so let me give you a rule of thumb: &lt;strong&gt;when in doubt, use baseType&lt;/strong&gt; rather than derivedType. &lt;/li&gt;

  &lt;li&gt;Finally, we have the two CodeMemberMethods, which represent methods that relate to the particular control that’s being built.&amp;#160; One is for the method that builds the control (e.g. assigns its properties from the markup, …), and the other one deals with data binding. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Tip to make more sense of all that stuff&lt;/strong&gt;: a great way to learn more about the code ASP.NET generate is simply to look at it!&amp;#160; To do this, add debug=”true” on your page, add a compilation error in there (e.g. &amp;lt;% BAD %&amp;gt;) and request the page.&amp;#160; In the browser error page, you’ll be able to look at all the generated code.&lt;/p&gt;

&lt;h3&gt;&amp;#160;&lt;/h3&gt;

&lt;h2&gt;How about a little sample to demonstrate?&lt;/h2&gt;

&lt;p&gt;Let’s take a look at a trivial sample that uses this.&amp;#160; It doesn't do anything super useful but does demonstrate the feature.&amp;#160; First, let’s write a little control that uses a ControlBuilder:&lt;/p&gt;

&lt;pre class="code"&gt;[&lt;span style="color: #2b91af"&gt;ControlBuilder&lt;/span&gt;(&lt;span style="color: blue"&gt;typeof&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;MyGeneratingControlBuilder&lt;/span&gt;))]
&lt;span style="color: blue"&gt;public class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;MyGeneratingControl &lt;/span&gt;: &lt;span style="color: #2b91af"&gt;Control &lt;/span&gt;{
    &lt;span style="color: green"&gt;// Control doesn't do anything other than generate code via its ControlBuilder
&lt;/span&gt;}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;Now in the ControlBuilder, let’s implement ProcessGeneratedCode so that it spits out a little test property:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: green"&gt;// Spit out a property that looks like:
//protected virtual string CtrlID_SomeCoolProp {
//    get {
//        return &amp;quot;Hello!&amp;quot;;
//    }
//}
&lt;/span&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;prop = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;CodeMemberProperty&lt;/span&gt;() {
    Attributes = &lt;span style="color: #2b91af"&gt;MemberAttributes&lt;/span&gt;.Family,
    Name = ID + &lt;span style="color: #a31515"&gt;&amp;quot;_SomeCoolProp&amp;quot;&lt;/span&gt;,
    Type = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;CodeTypeReference&lt;/span&gt;(&lt;span style="color: blue"&gt;typeof&lt;/span&gt;(&lt;span style="color: blue"&gt;string&lt;/span&gt;))
};

prop.GetStatements.Add(&lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;CodeMethodReturnStatement&lt;/span&gt;(&lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;CodePrimitiveExpression&lt;/span&gt;(&lt;span style="color: #a31515"&gt;&amp;quot;Hello!&amp;quot;&lt;/span&gt;)));

baseType.Members.Add(prop);&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;So&amp;#160; it just generates a string property with a name derived from the control ID.&amp;#160; Now let’s look at the page:&lt;/p&gt;

&lt;pre class="code"&gt;    &lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;test&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: #a31515"&gt;MyGeneratingControl &lt;/span&gt;&lt;span style="color: red"&gt;runat&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;server&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;ID&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;Foo&amp;quot; /&amp;gt;
&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;And finally, let’s use the generated property in code.&amp;#160; The simple presence of the this tag allows me to write:&lt;/p&gt;

&lt;pre class="code"&gt;Label1.Text = Foo_SomeCoolProp;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;And the really cool things is that Visual Studio picks this up, giving you full intellisense on the code generated by your ControlBuilder.&amp;#160; How cool is that! :)&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Full runnable sample is attached to this post.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h2&gt;What about security?&lt;/h2&gt;

&lt;p&gt;At first glance, it may seem like this feature gives too much power to ControlBuilders, letting them inject arbitrary code into the page that’s about to run.&amp;#160; The reality is that it really doesn’t let an evil control do anything that it could have done before.&amp;#160; Consider those two cases:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Full trust: if the Control and ControlBuilder are running in full trust, then they can directly do anything that they want.&amp;#160; They gain nothing more from&amp;#160; generating code that does bad things &lt;/li&gt;

  &lt;li&gt;Partial trust: if the Control and ControlBuilder are running in partial trust, then they can’t do much damage themselves directly, and can attempt to do additional damage indirectly via code they generate.&amp;#160; However, if the app is running in partial trust (as is typical in hosted environments), then the dynamically generated page code also runs in partial trust.&amp;#160; So effectively, it can’t do any more than the control could do directly. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h2&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;ProcessGeneratedCode is a pretty powerful feature, giving your ControlBuilders full control over the code generation.&amp;#160; It’s also a pretty advanced feature, and you can certainly shoot yourself in the foot with it if you’re not careful.&amp;#160; So be careful!&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9126826" width="1" height="1"&gt;</description><enclosure url="http://blogs.msdn.com/davidebb/attachment/9126826.ashx" length="3830" type="application/x-zip-compressed" /><category domain="http://blogs.msdn.com/davidebb/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://blogs.msdn.com/davidebb/archive/tags/Dynamic+Data/default.aspx">Dynamic Data</category></item><item><title>A ‘Many To Many’ field template for Dynamic Data</title><link>http://blogs.msdn.com/davidebb/archive/2008/10/25/a-many-to-many-field-template-for-dynamic-data.aspx</link><pubDate>Sun, 26 Oct 2008 08:50:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9016514</guid><dc:creator>davidebb</dc:creator><slash:comments>31</slash:comments><comments>http://blogs.msdn.com/davidebb/comments/9016514.aspx</comments><wfw:commentRss>http://blogs.msdn.com/davidebb/commentrss.aspx?PostID=9016514</wfw:commentRss><wfw:comment>http://blogs.msdn.com/davidebb/rsscomments.aspx?PostID=9016514</wfw:comment><description>&lt;p&gt;Unlike Linq To Sql, Entity Framework directly supports Many to Many relationships.&amp;#160; I’ll first describe what this support means.&lt;/p&gt;  &lt;p&gt;In the Northwind sample database, you have Employees, Territories and EmployeeTerritories tables.&amp;#160; EmployeeTerritories is a ‘junction’ table which has only two columns: an EmployeeID and a TerritoryID, which creates a Many to Many relationship between Employees and Territories.&lt;/p&gt;  &lt;p&gt;When using Linq To Sql, all three tables get mapped in your model, and you need to manually deal with the EmployeeTerritories junction table.&amp;#160; But when using Entity Framework, the EmployeeTerritories junction table is not part of your model.&amp;#160; Instead, your Employee entity class has a ‘Territories’ navigation property, and conversely your Territory entity class has an ‘Employees’ navigation property.&amp;#160; What Entity Framework does under the cover to make all this work is pretty amazing!&lt;/p&gt;  &lt;p&gt;Unfortunately, in ASP.NET Dynamic Data’s initial release (as part of Framework 3.5 SP1), we didn’t have time to add proper support for such Many to Many relationships, and in fact it behaves in a pretty broken way when it encounters them.&lt;/p&gt;  &lt;p&gt;The good news is that it is possible to write a field template that adds great support for this, and that is exactly what this blog post is about.&amp;#160; I should note that a couple of our users have written such field templates before (in particular, see &lt;a href="http://blog.tanngle.com/articles/2008/08/28/many-to-many-fieldtemplates-with-dynamic-data-and-entity-framework" mce_href="http://blog.tanngle.com/articles/2008/08/28/many-to-many-fieldtemplates-with-dynamic-data-and-entity-framework"&gt;this post&lt;/a&gt;).&amp;#160; In fact, that’s what got me going to write one! :)&lt;/p&gt;  &lt;p&gt;One difference is that I set mine out to be completely generic, in the sense that it doesn’t assume any specific database or table.&amp;#160; e.g. it works for Northwind’s Employees/Territories (which my sample includes), but works just as well for any other database that uses Many to Many relationships.&lt;/p&gt;  &lt;p&gt;In read-only mode, it shows you a list of links to the related entities.&amp;#160; e.g. when looking at a Territory, you’ll see links to each of the Employees that work there.&lt;/p&gt;  &lt;p&gt;&lt;img style="display: inline" title="Details mode" alt="Details mode" src="https://blogs.msdn.com/blogfiles/davidebb/WindowsLiveWriter/AManyToManyfieldtemplateforDynamicData_13862/image_3.png" width="399" height="224" /&gt; &lt;/p&gt;  &lt;p&gt;In edit mode, it gets more interesting: it displays a list of checkboxes, one for each Employee in the database.&amp;#160; Then, whether the Employee works in this territory is determined by whether the checkbox is checked.&amp;#160; Pretty much what you’d expect!&lt;/p&gt;  &lt;p&gt;&lt;img style="display: inline" title="Edit mode" alt="Edit mode" src="https://blogs.msdn.com/blogfiles/davidebb/WindowsLiveWriter/AManyToManyfieldtemplateforDynamicData_13862/image_4.png" width="465" height="224" /&gt; &lt;/p&gt;  &lt;p&gt;I won’t go into great details about &lt;strong&gt;how&lt;/strong&gt; it works here, but if you are interested, I encourage you to download the sample and look at the code, which I commented pretty well.&amp;#160; The key things to look at are:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;The field templates ManyToMany.ascx (used for read-only) and ManyToMany_Edit.ascx (used for Edit). &lt;/li&gt;    &lt;li&gt;The AutoFieldGenerator, which automatically uses those field templates for Many to Many relationships. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Enjoy, and let me know if you have feedback on this.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9016514" width="1" height="1"&gt;</description><enclosure url="http://blogs.msdn.com/davidebb/attachment/9016514.ashx" length="1036878" type="application/x-zip-compressed" /><category domain="http://blogs.msdn.com/davidebb/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://blogs.msdn.com/davidebb/archive/tags/Dynamic+Data/default.aspx">Dynamic Data</category><category domain="http://blogs.msdn.com/davidebb/archive/tags/Entity+Framework/default.aspx">Entity Framework</category></item><item><title>Dynamic Data Filtering project up on CodePlex</title><link>http://blogs.msdn.com/davidebb/archive/2008/08/22/dynamic-data-filtering-project-up-on-codeplex.aspx</link><pubDate>Sat, 23 Aug 2008 03:39:58 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8889309</guid><dc:creator>davidebb</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/davidebb/comments/8889309.aspx</comments><wfw:commentRss>http://blogs.msdn.com/davidebb/commentrss.aspx?PostID=8889309</wfw:commentRss><wfw:comment>http://blogs.msdn.com/davidebb/rsscomments.aspx?PostID=8889309</wfw:comment><description>&lt;p&gt;Josh Heyse has just released a very cool extension to ASP.NET Dynamic Data which supports much fancier filtering than is available is the core Dynamic Data.&amp;#160; The core idea is that filters can contribute arbitrary LINQ expression trees to the Select query performed by the data source.&amp;#160; So for instance you can have a Range filter which checks that a column is between two values, or a Search filter which performs sub-string matching (e.g. StartsWith, EndsWith or Contains).&amp;#160; All that is made available with very little effort from the user.&lt;/p&gt;  &lt;p&gt;It's all &lt;a href="http://www.codeplex.com/DynamicDataFiltering"&gt;available on CodePlex&lt;/a&gt;, so check it out!&amp;#160; Start with the included AdventureWorks sample to get an idea what it's all about.&amp;#160; Great job Josh!&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8889309" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/davidebb/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://blogs.msdn.com/davidebb/archive/tags/Dynamic+Data/default.aspx">Dynamic Data</category></item><item><title>Using ASP.NET Dynamic Data with ObjectDataSource</title><link>http://blogs.msdn.com/davidebb/archive/2008/06/18/using-asp-net-dynamic-data-with-objectdatasource.aspx</link><pubDate>Thu, 19 Jun 2008 02:37:38 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8619209</guid><dc:creator>davidebb</dc:creator><slash:comments>6</slash:comments><comments>http://blogs.msdn.com/davidebb/comments/8619209.aspx</comments><wfw:commentRss>http://blogs.msdn.com/davidebb/commentrss.aspx?PostID=8619209</wfw:commentRss><wfw:comment>http://blogs.msdn.com/davidebb/rsscomments.aspx?PostID=8619209</wfw:comment><description>&lt;h3&gt;Support for LINQ based O/R mappers&lt;/h3&gt;  &lt;p&gt;Out of the box, ASP.NET Dynamic Data has support for both Linq To Sql and Entity Framework.&amp;#160; In addition, it has a provider model which allows additional O/R mappers to be supported.&amp;#160; For instance, we have a sample provider that supports ADO.NET Data Services (aka Astoria).&amp;#160; There is also a &lt;a href="http://weblogs.asp.net/fbouma/archive/2008/05/01/dynamic-data-and-3rd-party-o-r-mappers-is-a-fact.aspx"&gt;provider for LLBLGen&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Note that all those scenarios are some things in common:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;They are based on some form of data context&lt;/strong&gt;: it's called various things in the different O/R mappers (DataContext, ObjectContext, DataServiceContext), but essentially it's a class that has a property for each Entity Set. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;They support LINQ&lt;/strong&gt;: the Entity Set properties on the data context class implement IQueryable&amp;lt;T&amp;gt;, which allows LINQ to be used on them. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h3&gt;Support for scenarios that use ObjectDataSource&lt;/h3&gt;  &lt;p&gt;While having this extensibility is great, it doesn't cover a whole range of scenarios where users have their own data layer, with no LINQ and no data context in sight.&amp;#160; For a simple example of such scenario, see the sample attached to this &lt;a href="http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.objectdatasource.dataobjecttypename.aspx"&gt;MSDN page&lt;/a&gt;.&amp;#160; The key aspects are:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;Entity class: &lt;/strong&gt;you have a strongly typed some entity class (NewData in the MSDN sample).&amp;#160; It just defines the fields you care about, with no real&amp;#160; logic attached. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Business layer class: &lt;/strong&gt;you have a class that has various methods to perform your CRUD operations (the class is named AggregateData in that sample). &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;ObjectDataSource:&lt;/strong&gt; your page uses an ObjectDataSource to have ASP.NET interact with your entity and business layer classes.&amp;#160; You tell the data source exactly which method to call for each CRUD operation. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Quite a few people use this technique, as it is very flexible and can work with fairly arbitrary business layer.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;So how does this all work when you want to use Dynamic Data in this type of scenarios?&lt;/strong&gt;&amp;#160; It actually integrates very nicely, by using some simple functionality that's available as part of the &lt;a href="http://www.codeplex.com/aspnet/Release/ProjectReleases.aspx?ReleaseId=14475"&gt;Dynamic Data Futures on CodePlex&lt;/a&gt;.&amp;#160; If you download that solution, it includes a fully functional sample based on the MSDN sample above.&lt;/p&gt;  &lt;p&gt;Here is more details on what it all looks like.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;The business layer class&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;This remains pretty unchanged, except that you have the ability to throw an exception when you see invalid data come in, e.g.&lt;/p&gt;  &lt;blockquote&gt;   &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;public class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;AggregateData &lt;/span&gt;{

    // Unchanged pieces omitted

  &lt;span style="color: blue"&gt;  public &lt;/span&gt;&lt;span style="color: #2b91af"&gt;DataTable &lt;/span&gt;Select() {
        &lt;span style="color: blue"&gt;return &lt;/span&gt;(table == &lt;span style="color: blue"&gt;null&lt;/span&gt;) ? CreateData() : table;
    }
  
    &lt;span style="color: blue"&gt;public int &lt;/span&gt;Insert(&lt;span style="color: #2b91af"&gt;NewData &lt;/span&gt;newRecord) {
&lt;strong&gt;        &lt;span style="color: blue"&gt;if &lt;/span&gt;(newRecord.Name.Length &amp;lt; 3) {
            &lt;span style="color: blue"&gt;throw new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ValidationException&lt;/span&gt;(&lt;span style="color: #a31515"&gt;&amp;quot;The name must have at least 3 characters&amp;quot;&lt;/span&gt;);
        }
&lt;/strong&gt;
        table.Rows.Add(&lt;span style="color: blue"&gt;new object&lt;/span&gt;[] { newRecord.Name, newRecord.Number, newRecord.Date });
        &lt;span style="color: blue"&gt;return &lt;/span&gt;1;
    }
}&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;Here, it's saying that the name must have at least 3 characters.&amp;#160; What's really nice is that the exception you throw here gets shown exactly where you expect it: in the ASP.NET validation summary.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Entity class&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let's now look at the entity class.&amp;#160; Again, it's mostly unchanged from the original, except that we now have the ability to annotate it using Dynamic Data attributes:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;public class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;NewData &lt;/span&gt;{
    [&lt;span style="color: #2b91af"&gt;RegularExpression&lt;/span&gt;(&lt;span style="color: #a31515"&gt;@&amp;quot;[A-Z].*&amp;quot;&lt;/span&gt;, ErrorMessage=&lt;span style="color: #a31515"&gt;&amp;quot;The name must start with an upper case character&amp;quot;&lt;/span&gt;)]
    [&lt;span style="color: #2b91af"&gt;Required&lt;/span&gt;]
    [&lt;span style="color: #2b91af"&gt;DisplayName&lt;/span&gt;(&lt;span style="color: #a31515"&gt;&amp;quot;The name&amp;quot;&lt;/span&gt;)]
    &lt;span style="color: blue"&gt;public string &lt;/span&gt;Name { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }

    [&lt;span style="color: #2b91af"&gt;Range&lt;/span&gt;(0, 1000)]
    [&lt;span style="color: #2b91af"&gt;UIHint&lt;/span&gt;(&lt;span style="color: #a31515"&gt;&amp;quot;IntegerSlider&amp;quot;&lt;/span&gt;)]
    [&lt;span style="color: #2b91af"&gt;DefaultValue&lt;/span&gt;(345)]
    &lt;span style="color: blue"&gt;public int &lt;/span&gt;Number { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }

    [&lt;span style="color: #2b91af"&gt;DataType&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;DataType&lt;/span&gt;.Date)]
    [&lt;span style="color: #2b91af"&gt;UIHint&lt;/span&gt;(&lt;span style="color: #a31515"&gt;&amp;quot;DateAjaxCalendar&amp;quot;&lt;/span&gt;)]
    [&lt;span style="color: #2b91af"&gt;Required&lt;/span&gt;]
    &lt;span style="color: blue"&gt;public &lt;/span&gt;&lt;span style="color: #2b91af"&gt;DateTime &lt;/span&gt;Date { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }
}&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;I won't go over the details of what each attribute means, as they are the standard Dynamic Data attributes and they're fairly self-explanatory.&amp;#160; The key point is that everything works exactly in the same way as they would when you use Dynamic Data with Linq To Sql: the rendering goes through the field templates, the UIHint is used to select the template, the validation attributes become ASP.NET validators, ...&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The aspx page&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Finally, let's look at the ASP.NET page.&amp;#160; Again, it's not all that different from the original sample:&lt;/p&gt;

&lt;pre class="code"&gt;    &lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;asp&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: #a31515"&gt;ValidationSummary &lt;/span&gt;&lt;span style="color: red"&gt;ID&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;ValidationSummary1&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;runat&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;server&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;EnableClientScript&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;true&amp;quot;
        &lt;/span&gt;&lt;span style="color: red"&gt;HeaderText&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;List of validation errors&amp;quot; /&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;asp&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: #a31515"&gt;DynamicValidator &lt;/span&gt;&lt;span style="color: red"&gt;runat&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;server&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;ID&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;DetailsViewValidator&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;ControlToValidate&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;DetailsView1&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;Display&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;None&amp;quot; /&amp;gt;

    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;asp&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: #a31515"&gt;DetailsView &lt;/span&gt;&lt;span style="color: red"&gt;ID&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;DetailsView1&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;runat&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;server&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;AllowPaging&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;True&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;AutoGenerateInsertButton&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;True&amp;quot;
        &lt;/span&gt;&lt;span style="color: red"&gt;DataSourceID&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;ObjectDataSource1&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;EnableModelValidation&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;true&amp;quot;&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;asp&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: #a31515"&gt;DetailsView&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;asp&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: #a31515"&gt;DynamicObjectDataSource &lt;/span&gt;&lt;span style="color: red"&gt;ID&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;ObjectDataSource1&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;runat&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;server&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;DataObjectTypeName&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;DynamicDataFuturesSample.NewData&amp;quot;
        &lt;/span&gt;&lt;span style="color: red"&gt;InsertMethod&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;Insert&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;SelectMethod&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;Select&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;TypeName&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;DynamicDataFuturesSample.AggregateData&amp;quot;&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;asp&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: #a31515"&gt;DynamicObjectDataSource&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;The most notable change is that ObjectDataSource became a DynamicObjectDataSource, and that we added a DynamicValidator.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;So let's see it run!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;Here is what it looks like with the above metadata:&lt;/p&gt;

&lt;p&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="534" alt="image" src="http://blogs.msdn.com/blogfiles/davidebb/WindowsLiveWriter/Using.NETDynamicDatawithObjectDataSource_C3F3/image_7.png" width="514" border="0" /&gt; &lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;Some notable things:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;The header for the name says 'the name' thanks to the DisplayName on the Name property &lt;/li&gt;

  &lt;li&gt;It complains that the name doesn't start with an upper case, per the RegularExpression attribute &lt;/li&gt;

  &lt;li&gt;The Number's UI shows up as an AJAX slider, thanks to the UIHint &lt;/li&gt;

  &lt;li&gt;Likewise, the Date UI uses an AJAX calendar &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h3&gt;Conclusion&lt;/h3&gt;

&lt;p&gt;Even though it wasn't a scenario that we originally intended to cover, it turns out that using Dynamic Data with ObjectDataSource scenarios is quite easy and works very well.&amp;#160; It really opens up a whole new range of scenarios that don't force users to switch to a different O/R mapper.&lt;/p&gt;

&lt;p&gt;It does have a notable limitation: it is not meant to support the full site scaffolding that you get with Linq To Sql or Entity Framework.&amp;#160; This comes from the fact that without a data context, there is no easy way to know what the set of relevant tables is, and what relationships they have with each other.&amp;#160; Of course, you still get the scaffolding aspect at the page level, in so far as the UI for your DetailsView/GridView is completely model driven, which is the main appeal of Dynamic Data.&lt;/p&gt;

&lt;p&gt;One of our users Dan Meineck just &lt;a href="http://www.meineck.net/2008/06/aspnet-dynamic-data-new-feature-in.html"&gt;blogged about this&lt;/a&gt; as well, so check out what he had to say!&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8619209" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/davidebb/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://blogs.msdn.com/davidebb/archive/tags/Dynamic+Data/default.aspx">Dynamic Data</category></item><item><title>ASP.NET Dynamic Data on CodePlex</title><link>http://blogs.msdn.com/davidebb/archive/2008/06/18/asp-net-dynamic-data-on-codeplex.aspx</link><pubDate>Wed, 18 Jun 2008 10:09:41 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8614797</guid><dc:creator>davidebb</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/davidebb/comments/8614797.aspx</comments><wfw:commentRss>http://blogs.msdn.com/davidebb/commentrss.aspx?PostID=8614797</wfw:commentRss><wfw:comment>http://blogs.msdn.com/davidebb/rsscomments.aspx?PostID=8614797</wfw:comment><description>&lt;p&gt;Today, ASP.NET Dynamic Data moved from its current home on &lt;a href="http://code.msdn.microsoft.com/dynamicdata"&gt;Code Gallery&lt;/a&gt; to its new home on &lt;a href="http://www.codeplex.com/aspnet"&gt;CodePlex&lt;/a&gt;.&amp;#160; Note that this is part of a general ASP.NET CodePlex project, so you'll see other features mentioned in there, like MVC and AJAX.&amp;#160; This doesn't mean that those features tie with Dynamic Data any more than they did before; they're just sharing a home on the same CodePlex project.&lt;/p&gt;  &lt;p&gt;There are a couple different things related to Dynamic Data that are available there, and since there is room for confusion I'll try to help make sense of it all.&lt;/p&gt;  &lt;h3&gt;The 'core' Dynamic Data&lt;/h3&gt;  &lt;p&gt;The first piece is Dynamic Data itself.&amp;#160; This will ship later this summer as part of Framework 3.5 SP1, but until that happens you need to install preview bits.&amp;#160; In order to get the latest preview, you first need to install &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=CF99C752-1391-4BC3-BABC-86BC0B9E8E5A&amp;amp;displaylang=en"&gt;VS 2008 SP1 Beta&lt;/a&gt;.&amp;#160; This comes with an outdated build of Dynamic Data, so you then need to install the &lt;a href="http://www.codeplex.com/aspnet/Release/ProjectReleases.aspx?ReleaseId=14474"&gt;update&lt;/a&gt; from CodePlex.&amp;#160; This is the same update that we had on Code Gallery, so if you already installed that, you don't need to do it again.&lt;/p&gt;  &lt;p&gt;Once Framework 3.5 SP1 officially ships, there will no longer be a need for this.&amp;#160; Note that for all practical purpose, &lt;strong&gt;this update is identical to what the final release will be in SP1&lt;/strong&gt;.&amp;#160; We are now completely locked down, and have not made a change in 3 weeks.&amp;#160; It just takes a little more time for the whole VS SP1 stack to finish up and be out the door.&lt;/p&gt;  &lt;p&gt;Note that even though this is on CodePlex, we are not at this time making the sources of the 'core' Dynamic Data available.&amp;#160; I certainly hope that we will be able to in the future, but that has to go through some lawyers and other fun things.&lt;/p&gt;  &lt;h3&gt;The Dynamic Data Futures&lt;/h3&gt;  &lt;p&gt;The second important piece that's available on CodePlex is the &lt;a href="http://www.codeplex.com/aspnet/Release/ProjectReleases.aspx?ReleaseId=14475"&gt;Dynamic Data Futures&lt;/a&gt; (previously calls 'Dynamic Data &lt;em&gt;Extensions&lt;/em&gt;').&amp;#160; At this time, these Futures are basically a big VS solution that contain both a library of new features (Microsoft.Web.DynamicData.dll), and a couple web sites that show them in action.&lt;/p&gt;  &lt;p&gt;Unlike the Dynamic Data 'core', this 'Futures' piece is fully available in source form.&amp;#160; The solution first builds Microsoft.Web.DynamicData.dll, and then builds the various samples that rely on it.&lt;/p&gt;  &lt;p&gt;Note that those Futures do not &lt;em&gt;replace&lt;/em&gt; the core Dynamic Data, but instead run on top of it.&amp;#160; So it shouldn't be looked at as being the 'next version' of Dynamic Data, but rather as being some extra functionality that will be available on top of the Framework 3.5 SP1 release.&lt;/p&gt;  &lt;p&gt;This project serves a few different purposes:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;It gives us a place to experiment with new features that we didn't have time to put in SP1.&amp;#160; Some of those will eventually make their way into the next version of Dynamic Data, while others are likely to remain samples.&amp;#160; Obviously, we'd love to get feedback on those (the &lt;a href="http://forums.asp.net/1145.aspx"&gt;forum&lt;/a&gt; is the right place for that). &lt;/li&gt;    &lt;li&gt;It lets us address some issues that are in the SP1 release and couldn't be fixed in time. &lt;/li&gt;    &lt;li&gt;It has some great samples for Dynamic Data users to look at and learn how to achieve various results.&amp;#160; Note that a few of the samples that were previously separate are now included in there (e.g. Scott Hunter's &lt;a href="http://blogs.msdn.com/scothu/archive/2008/06/17/dynamic-data-dbimage-sampleupdated.aspx"&gt;DbImage sample&lt;/a&gt;). &lt;/li&gt; &lt;/ul&gt;  &lt;h3&gt;What happens next&lt;/h3&gt;  &lt;p&gt;The 'Futures' project is very much work in progress, and we are actively adding things to it.&amp;#160; So you should expect to see fairly frequent updates on CodePlex.&lt;/p&gt;  &lt;p&gt;Please give this a try and let us know how it goes on the &lt;a href="http://forums.asp.net/1145.aspx"&gt;forum&lt;/a&gt;!&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8614797" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/davidebb/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://blogs.msdn.com/davidebb/archive/tags/Dynamic+Data/default.aspx">Dynamic Data</category></item></channel></rss>