About Links Archives Search Feed Albums of Note

ASP.NET 4.0 Part 15, Data Enhancements

Welcome to part 15 of my tour through ASP.NET 4.0 [http://blog.hmobius.com/post/2010/02/09/ASPNET-40-Cometh.aspx]. In this episode, we’re going to look at how webforms developers can make more use of both Dynamic Data 4.0 and Entity Framework 4.0 thanks to several new features baked into ASP.NET 4.0.

For those of you unfamiliar with these two products, Entity Framework [http://msdn.microsoft.com/en-gb/data/aa937723.aspx] is the ‘enterprise-level’ data modeller (O/RM) technology, aimed at larger applications where LINQ2SQL was aimed at small ones. Dynamic Data [http://www.asp.net/dynamicdata/] meanwhile is a rapid development tool used to create a basic scaffolding for a website based on the schema of the database that supports. Almost a CSS-like construct based on the type of data in a field rather than the type,class or id of an HTML element.

It’s odd how both Dynamic Data (DynData) and the Entity Framework (EF)  were both released in .NET 3.5 SP1 almost as a tester to garner public reaction to Microsoft’s efforts thus far with both projects. And it’s fair to say that mistakes / omissions were made in those v1 releases which are now being corrected. EF was vilified in comparison to other, more mature OR/M frameworks for many reasons including

DynData, which sat on top of EF, suffered from both EF’s shortcomings and some of its own including.

Needless to say, both DynData 4.0 and EF 4.0 address these issues and many more. It’s now fair to say that both technologies are well beyond where their first versions perceptibly fell short.

EnableDynamicData One of the goals of ASP.NET 4.0 was to make DynData’s scaffolding available to both Webforms and MVC. As noted earlier, DynData v1 was a project of its own that couldn’t be easily retrofitted into an existing website, be it using Webforms or MVC. To remedy this, ASP.NET 4.0 now includes a new method called EnableDynamicData that you can use on any page in a website or web application.

Consider the scenario where you’ve a FormView or GridView allowing you to update, add to or delete records from a database. Typically, the controls auto-generate columns containing textboxes and maybe a checkbox. Users can add in invalid text, dates, values outside desired ranges etc. So you disable auto-generation and template the columns yourself with a calendar control for dates, say, and validation controls. And then you do the same thing for various other data-bound controls based on the same tables of data. Rather than setting all columns and rows yourself on each control, the EnableDynamicData method tells ASP.NET to generate those customized input and validation controls itself using the DynData scaffolding generated against the database and annotations you may give it as a (central) template.

Let’s take an example.

Your page code should look like this.

<%@ Page Language=“C#” AutoEventWireup=“true” CodeFile=“Default.aspx.cs” Inherits="_Default" %>

<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”> Demo
 <asp:GridView runat="server" DataSourceID="entityDs" ID="gvwProducts">       <Columns>         <asp:CommandField ShowDeleteButton="True" ShowEditButton="True" />       </Columns>     </asp:GridView>     <asp:EntityDataSource runat="server" ID="entityDs"           ConnectionString="name=AdventureWorksLT2008_DataEntities"           DefaultContainerName="AdventureWorksLT2008_DataEntities"           EnableDelete="True" EnableFlattening="False"           EnableUpdate="True" EntitySetName="Products"          EntityTypeFilter="Product"> </asp:EntityDataSource>        </div>   </form> </body> </html>

If you run this page and try to update any of the currency-based fields for an item now listed in the grid (eg. StandardCost or ListPrice) with a non-currency value such as the string ‘abc’, you’ll get the following Yellow Screen Of Death message.

Error while setting property ‘StandardCost’: ‘Cannot convert the value of parameter ’StandardCost’ to the type ‘System.Decimal’.’.

Of course, if we were to manually generate the columns in the GridView, we could add in validation to ensure that only valid currency values are sent to the database. But let’s not and enable the dynamic data framework on the GridView and see what happens. It’s a single line of code added to your page’s codebehind.

public partial class _Default : System.Web.UI.Page { protected void Page_Init(object sender, EventArgs e) { gvwProducts.EnableDynamicData(typeof(AdventureWorksLT_DataModel.Product)); } }

If you run the page again and try to make the same page, you’ll see that some validation is performed pre-save and so clicking Update on the grid doesn’t produce the previously seen yellow screen of death.

Admittedly, it’s not earth-shatteringly useful as the invalid value is simply highlighted by an asterisk to its side with the actual error message that StandardCost is a required value hidden in a tooltip, but by adding a ValidationSummary control to the page, things become much clearer. And we’re leveraging the Dynamic Data framework to generate validation for us, which we can always amp up by adding instructions centrally to the entity model such as an appropriate error message. For example,

namespace AdventureWorksLT_DataModel { [MetadataType(typeof(ProductMetadata))] public partial class Product { }

public class ProductMetadata { [RegularExpression(@“1{1,}.[0-9]{2}$”, ErrorMessage=“Value should be greater than 0.00”)] public decimal StandardCost { get; set; } } }

Run the page again and you’ll see that a RegularExpressionValidator is now added to the RequiredFieldValidator already there.

There are loads of new features in Dynamic Data 4.0 that we can now leverage in WebForms and MVC including. 

  • Primary keys are now identified as primary keys and are not shown as an editable field * New field templates for URLs and email addresses. * Many-to-many relationships are now handled as a field template

Entity templates are another new feature in Dynamic Data 4.0. Whereas field templates deal with single field types, entity templates deal with objects as a whole, be they contained in a single table or spanned across many. Let’s say we’ve a website in which the information for an auction item is restricted based on whether you’re an admin, the seller or a buyer. An entity template means you can control what each role sees at the object level rather than reiterating it across several pages where that object is bound to controls.

Entity and field templates are available to both MVC and Webforms.

QueryExtender If there’s one problem with LINQ-based DataSource controls (for example, LinqDataSource and EntityDataSource) in .NET 3.5 it’s that filtering on the data isn’t supported declaratively by the data source. You have to take control of the query being sent to the database, add the filtering yourself and then passing the query back to the data source, usually by handling the OnQueryCreated event.

protected void dsProducts_QueryCreated(object sender, QueryCreatedEventArgs e) { if (!String.IsNullOrWhiteSpace(txtFilterName.Text)) { e.Query = from p in e.Query.Cast<AdventureWorksLT_DataModel.Product>() where p.Name.StartsWith(txtFilterName.Text.Trim()) select p; } }

In .NET 4.0 however, there is now a solution - the new QueryExtender control. Let’s take an example and reuse the page we’ve got going. It already pulls down the contents of the Products table from the AdventureWorks table. Let’s add a simple textbox which let’s you set the start of the product’s name to search for.

 Name starts with:     <asp:TextBox ID="txtFilterName" runat="server">Sport</asp:TextBox>     <asp:Button ID="btnGo" runat="server" Text="Go" />     <br />     <asp:GridView runat="server" DataSourceID="entityDs" ID="gvwProducts"> ...

To include the filtering in the page, we add the QueryExtender to the page as follows.

Et voila. As the page loads, the QueryExtender informs the EntityDataSource and filters the data it presents us based on the contents of the text box.

Summary There’s a heck of a lot of new and interesting stuff going on in and around the world of data in .NET. Besides the advancements to the Dynamic Data and Entity Frameworks, there’s also a new version of ADO Data Services (now known as WCF data services [http://msdn.microsoft.com/en-us/data/bb931106.aspx]), the introduction of data storage in the cloud with SQL Azure Services [http://www.microsoft.com/windowsazure/sqlazure/] and client-side data binding with AJAX Data Templates [http://msdn.microsoft.com/en-us/magazine/cc972638.aspx].

In our look at one small corner of it all, we saw how the EnableDynamicData method allows us to leverage the Dynamic Data Framework to act as a CSS-like form presentation and validation rules template for all our templated, data bound controls - a level of integration between Dynamic Data and Webforms/MVC previously unavailable.

We also saw how we can leverage the new QueryExtender control against LinqDataSource and EntityDataSource controls to act as dynamic filters for the data they retrieve.

  1. 0-9↩︎

Posted on April 7, 2010   #ASP.NET     #Geek Stuff  

← Next post    ·    Previous post →