Using Dynamic Data Controls In Your Existing Project

by bigcarlito Tuesday, October 07, 2008

Just about every site I've ever created has needed some screens to manage the data in certain tables - whether it's users, products, or in my most recent case forums.  I always overlook the time it takes to make a basic CRUD (CReate-Update-Delete) screen. 

There really is a lot of work that goes into these types of screens: Get the data, hook the data up to a grid, format the grid and the fields in the grid, create a details view, format the details view and the detail fields, hook the details view up to the grid, enable editing of the fields, validate the inputs on save, save or insert the data, refresh the grid after saving, and on and on it goes.  PHEW! 

"Uh, excuse me Mr. Project Manager, how long did I estimate for this task again?" :-) 

Dynamic Data To The Rescue

After installing Visual Studio 2008 SP1, you may have noticed a new web application project called Dynamic Data Web Application.  A Dynamic Data web application provides a framework for quickly and easily creating CRUD screens for any tables in your database.

However, an entire web application dedicated to managing the data in a database is not very practical.  In a typical software project, whatever CRUD screens you need are usually just a small piece of the entire application.

The good news is that Dynamic Data is fairly easily integrated into your existing projects as well.  Props to Scott Hanselman for explaining clearly how to do this

So here's a summary of exactly how I went about adding screens for managing the Forums table in my existing application:

Step 1: Add Dynamic Data To Your Project

There are a few specific things you'll need to do to add Dynamic Data to your Web Forms or MVC project:

I. Add a reference to System.Web.DynamicData 

II. Add dynamic data controls to the <controls> element of your web.config

<pages>
    <controls>
        <add tagPrefix="asp" namespace="System.Web.DynamicData" 
assembly="System.Web.DynamicData, Version=3.5.0.0, 
Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>  
    </controls>
 

III.  Register your model in Global.asax

protected void Application_Start()
{
   MetaModel model = new MetaModel(); 
   model.RegisterContext(typeof(SocialDataContext), 
new ContextConfiguration() { ScaffoldAllTables = false });
   RegisterRoutes(RouteTable.Routes);
}

IV.  Add the DynamicData folder and contents to your project

As suggested by Scott H., the best way to do this is to go create a brand new Dynamic Data Web Application project off in another directory.  Be sure to name the new project the exact same name as your current project so namespaces will all match up.  Once created, copy the DynamicData folder and all it's contents over to your project directory and include the entire thing in your project.

 

Step 2: Create A Web Form and add a DynamicDataManager

Pretty simple, create your web form and and add the DynamicDataManager control to it:

<asp:DynamicDataManager ID="DynamicDataManager1" runat="server" />  

Step 3: Add A GridView

Next step is to add a grid that will contain the table data. The only really interesting part here is the columns of the gridview - they are controls of type DynamicControl. These smart controls look at the type of data they are given and automatically determine the best way to display it:

<!-- The Data -->
<asp:LinqDataSource ID="DataSourceItems" runat="server" 
ContextTypeName="Social.Models.SocialDataContext" EnableDelete="True" 
EnableInsert="True" EnableUpdate="True" TableName="Forums" 
OrderBy="DisplayOrder, ForumName">
</asp:LinqDataSource>
<!-- The Grid -->
<asp:GridView ID="gvItems" runat="server" AllowPaging="True" AllowSorting="True" 
AutoGenerateColumns="False" DataSourceID="DataSourceItems" 
onselectedindexchanged="gvItems_SelectedIndexChanged">
<Columns>
<asp:CommandField ShowSelectButton="True" HeaderStyle-Width="60" />
<asp:TemplateField HeaderText="Forum" SortExpression="ForumName">
<ItemTemplate>
<asp:DynamicControl ID="DynamicControl1" runat="server" DataField="ForumName" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Category" SortExpression="ForumCategory.ForumCategory1">
<ItemTemplate>
<asp:DynamicControl ID="DynamicControl2" runat="server" DataField="ForumCategory" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Sort" SortExpression="DisplayOrder">
<ItemTemplate>
<asp:DynamicControl ID="DynamicControl3" runat="server" DataField="DisplayOrder" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<!-- An 'Add New' Button -->
<div class="addrow">
<asp:LinkButton ID="btnInsert" runat="server" onclick="btnInsert_Click">Add New
</asp:LinkButton>
</div>

Step 4: Add The Details View

Next up we'll add the details view where the user will be able to update any editable properties of the selected item or add a new item.  Again the interesting part (and the part you'll change when you make your own page) are the DetailsView columns.

The DynamicField controls peek at the datatype of the field they are bound to and provide the appropriate input control for that datatype.  Not only that, but validation is built in as well!  Pretty neat, eh?

<!-- Details -->
<asp:Panel ID="PanelDetails" runat="server" Visible="false">
<!-- Input Fields -->
<asp:DetailsView ID="dvItem" runat="server" 
AutoGenerateRows="False" DataKeyNames="ForumID" DataSourceID="DataSourceDetails" 
AutoGenerateDeleteButton="True" AutoGenerateEditButton="True" 
AutoGenerateInsertButton="True" onitemdeleted="dvItem_ItemDeleted" 
onitemupdated="dvItem_ItemUpdated" oniteminserted="dvItem_ItemInserted"> 
<Fields>
<asp:DynamicField DataField="ForumID" HeaderStyle-Width="150" HeaderText="Forum ID:" />
<asp:DynamicField DataField="ForumName" HeaderText="Forum Name:" />
<asp:DynamicField DataField="ForumDesc" HeaderText="Description:" />
<asp:DynamicField DataField="DisplayOrder" HeaderText="Sort:" />
<asp:DynamicField DataField="ForumCategory" HeaderText="Category:" />
<asp:DynamicField DataField="IsPrivate" HeaderText="Private:" />
<asp:DynamicField DataField="ParentForum" HeaderText="Parent:" />
</Fields>
</asp:DetailsView>
<!-- Details DataSource -->
<asp:LinqDataSource ID="DataSourceDetails" runat="server" 
ContextTypeName="Social.Models.SocialDataContext" EnableDelete="True" 
EnableInsert="True" EnableUpdate="True" TableName="Forums" 
Where="ForumID == @ForumID">
<WhereParameters>
<asp:ControlParameter ControlID="gvItems" DefaultValue="-1" Name="ForumID" 
PropertyName="SelectedValue" Type="Int32" />
</WhereParameters>
</asp:LinqDataSource>
</asp:Panel> 

In software development, it often is all the little things that take up the most time.  The old saying 'the last 20% is 80% of the work' certainly is true in my experience.  Dynamic Data is a huge timesaver in that regard, it handles all the little details of a common but typically painstaking task.

Step 5: Handle A Few Events

Finally, in the code behind, we'll handle a few of the events to make the flow of work a little smoother.  Notice how little code is required to make this fully featured CRUD screen:

    protected void Page_Load(object sender, EventArgs e)
    {
      DynamicDataManager1.RegisterControl(gvItems);
      DynamicDataManager1.RegisterControl(dvItem);
    }
    protected void gvItems_SelectedIndexChanged(object sender, EventArgs e)
    {
      PanelDetails.Visible = true;
    }
    protected void btnInsert_Click(object sender, EventArgs e)
    {
      dvItem.ChangeMode(DetailsViewMode.Insert);
      PanelDetails.Visible = true;
    }
    protected void dvItem_ItemInserted(object sender, DetailsViewInsertedEventArgs e)
    {
      RefreshGrid();
    }
    protected void dvItem_ItemDeleted(object sender, DetailsViewDeletedEventArgs e)
    {
      RefreshGrid();
    }
    protected void dvItem_ItemUpdated(object sender, DetailsViewUpdatedEventArgs e)
    {
      RefreshGrid();
    }
    private void RefreshGrid()
    {
      gvItems.DataBind();
      gvItems.SelectedIndex = -1;
    }

So How Do I Use This?

For anyone wanting to use this, here's what you need to change to suit your situation:

  1.  Edit the grid's datasource to pull data from your table in your DataContext
  2.  Update the grid's columns - most importantly the DataField properties - to match the fieldnames (or in this case LINQ properties) from your table
  3.  Update the details datasource pull the specific record from your table based on the key field from grid
  4.  Update the details view to include all the columns that cannot be null or that you want to be editable by the user

That's it!  Pretty much everything else is handeled through the magic of Dynamic Data!

A Dynamic Data app also comes with a lot of scaffolding for mapping URLs to tables and dynamically generating entire CRUD pages.  The purpose of this post was simply to show how to use the Dynamic Data controls in your existing projects with minimal changes to how the rest of your project does things. Hope it was helpful!
Share/Save/Bookmark     kick it on DotNetKicks.com

URL Rewriting Extension For BlogEngine

by bigcarlito Tuesday, August 05, 2008

In my latest project I decided to incorporate BlogEngine.Net for managing the content.  While it certainly does have some things I don't like, all in all it's an excellent basic content system.  I love the control over the HTML that you get with the theme system, the flexibility provided by extensions and widgets, and the integration with Windows Live Writer - truly a job well done by Mads and the BE.NET team!

During A Redesign, Think About Search Visitors

So I have an existing site More...

Share/Save/Bookmark     kick it on DotNetKicks.com

Your Search Rankings Just Dropped One Position

by bigcarlito Thursday, July 24, 2008

 

image
Just a quick note - yesterday Google (somewhat) quietly announced that Google Knol is now accepting contributions from anyone with a Google login.  Basically it’s a Google Wikipedia that allows contributors to earn a portion of the profits from ads displayed on each page.  They claim that it is more focused on More...
Share/Save/Bookmark     kick it on DotNetKicks.com

Google Analytics For SEO Tip #1 - Keyword Research

by bigcarlito Wednesday, July 23, 2008

Google Analytics is a great free tool for monitoring your web traffic.  Most every webmaster would probably agree that it's important to have some kind of statistical tracking on your website, but few that I know actually *use* the data for anything useful. 

So here are a couple ideas to get you thinking how Google Analytics can help you improve your site's search rankings:More...

Share/Save/Bookmark     kick it on DotNetKicks.com

Railing on .NET

by bigcarlito Thursday, July 17, 2008

To get myself in the habit of posting more, I'm going to try to do a little Friday humor every week.  Today we have some hilarious stuff from the Ruby on Rails community.  Credit goes to Alex Rudloff for the original link that got me off on this tangent.

Commercial #1: Ruby on Rails vs. .NET



And here's the other one, joking about the costs of .NET development: More...
Share/Save/Bookmark     kick it on DotNetKicks.com

Using jQuery To Call ASP.NET Page Methods and Web Services

by bigcarlito Wednesday, July 16, 2008

I'm a HUGE fan of jQuery.  In fact in my latest project, I've removed the ScriptManager from my ASP.NET pages entirely.  Originally I was including both jQuery and the ScriptManager on my pages because I just couldn't live without the ease and simplicity of calling page methods with ASP.NET AJAX. 

Well, with a little help from Dave Ward and Rick Strahl, I realized that calling ASP.NET page methods (and web services) from jQuery is really pretty simple. More...

Share/Save/Bookmark     kick it on DotNetKicks.com

Programmers Are The Best (Internet) Marketers

by bigcarlito Sunday, July 13, 2008

Starving ProgrammerJohn Reese, a very established Internet marketer, just released part 3 of his Traffic Secrets 2.0 pre-release videos.  The purpose of these videos is to build hype for his new traffic building e-course.  Personally, I rarely spend money on those kinds of Internet marketing products, but that's not the point of my post. 

All three videos are light on specifics, but they do explain some of the general tactics that his course is based on.  If your current marketing techniques are starting to not work as well as they used to, take a look at these videos as I think they do a nice job of summarizing what I believe are the most current techniques that are still working to promote sites and improve search rankings. More...

Share/Save/Bookmark     kick it on DotNetKicks.com

Five Common ASP.NET SEO Mistakes

by bigcarlito Tuesday, July 08, 2008

Search Engine RobotSo you've finally finished your next masterpiece of a website.  Everything is tested and working great.  The user interface is immaculate and the design is truly something to behold.  Time to push it live and start rolling in the money, right?  Well, there is one more user demographic that you still need to satisfy - the search engines!  Unless, of course, you don't *need* any of that free targeted search traffic??

One of the strengths of ASP.NET development with Visual Studio is the relative ease in which you can create a functional dynamic site.  At the same time, one of it's weaknesses is the relative ease in which you can create a functional dynamic site that is confusing, if not completely unusable, by a search engine robot.

Here's a checklist of five common mistakes that ASP.NET and the Viewstate/Postback model of development make it far too easy for unsuspecting developers to make: More...

Share/Save/Bookmark     kick it on DotNetKicks.com

The Link Page Report Card

by bigcarlito Sunday, July 06, 2008
Share/Save/Bookmark     kick it on DotNetKicks.com

Deploying ASP.NET Applications With Dispatch

by bigcarlito Wednesday, March 05, 2008

As a web developer with many sites, it quickly became a major time consuming problem to keep them all updated with the latest code.  Visual Studio has never had a good solution for deploying the necessary files (and only the necessary files) directly to a web server. 

Sure, they provide a feeble attempt at an FTP synchronization tool, but this tool has never really proved to be anything more than an integrated FTP client, leaving the developer to manually upload the files that need to be uploaded, updating configuration files for the remote server, and most importantly, ensuring that nothing gets overwritten that shouldn't be.  More...

Share/Save/Bookmark     kick it on DotNetKicks.com