Great Data Grids I Have Known
And other tales from the code-generation front lines
Data table displays are the
workhorses of transaction-
based Web applications.
So why are they so
hard to build, especially
since .NET provides a built-in
ASP.NET DataGrid control? The
reason is that, like all databound
controls, data grid applications
are not standard or necessarily
predictable. Building them is so
hard precisely because they
demand custom treatment for
each new application.
Consider the difficulty of fulfilling
each of these pretty standard
requirements:
Complex displays: Very few
enterprise-class applications
use the simple tabular displays
that the default ASP.NET
DataGrid control was designed
to support. Instead, most applications
have complex display
requirements, resulting from
filtered, multitable joins that
require multiple data elements
to be displayed within a single
cell. Some applications even
demand tables to be displayed
within enclosing table cells, i.e.,
tables within tables.
Data entry: For some applications,
it's convenient to embed
data entry within the data grid,
much like an entire spreadsheet
table is active for data entry.
The default ASP.NET data grids
don't particularly lend themselves
to having more than one
cell active for input at a time.
Large data sets: Many applications
deal with large data sets –
sometimes even millions of
rows in an enterprise application.
Currently, the ASP.NET
DataGrid control pulls the
entire result set from the database
into the application server,
where the data is then
manipulated and served up.
This approach is very inefficient
for most applications. It
forces the developer to re-create
functionality that already
exists, such as filtering and
sorting. These operations are
already built into the database,
and are well-established, welloptimized,
and mature.
Custom data validation: Most
enterprise applications demand
some amount of customized
data input processing – custom
data validation, boundary-value
checking, custom data types,
and context-sensitive error
messages. The defaults live in
the Validator controls of
ASP.NET and are customized by
overriding the base classes or
subclasses for each control.
The task of customizing data
validators is one of those "creeping"
tasks – while not difficult
coding per se, it quickly becomes
mind-numbing when you consider
that every editable field on
every page of your application
has two to three relevant
Validators that may require customization.
In fact, one of the most enduring
problems of writing user
interfaces is figuring out how to
display large amounts of custom
data efficiently and intuitively
without bewildering the user. The
problem becomes particularly
thorny when the interface must
reflect hierarchical relationships
within the data that the user
needs to modify.
However, while ASP.NET and
Visual Studio .NET have certainly
made Web application development
simpler, efficiently creating
intuitive, application-appropriate
data grids still involves significant
hand-coding and a mastery of the
.NET Framework. And you must
ask yourself whether investing a
lot of effort in customizing
DataGrid controls is really the
best use of your time.
The Code Generation Alternative
There is an alternative to
building custom DataGrid cond
trols by hand: code generation.
This article describes how
advanced automatic code generation
can quickly create customized
DataGrid controls for the
.NET Framework that let developers
effectively solve the problems
of complex displays, sophisticated
data entry, and large data sets.
Complex Displays
The most sophisticated of
today's code generators generate
databound applications based on
code generation instructions you
provide within your application's
HTML. These instructions can
take the form of XML-based "code
generation tags" that specify the
individual databound controls
you want within the page – the
DataGrid controls, filter controls,
search facilities, and navigation
controls. When the code generator
is run, it converts these code
generation commands into a
combination of presentationlayer
ASPX pages containing the
actual controls, application-layer
code-behinds and application
logic, and database-layer SQL
statements and transaction management code.
The sample job application
site shown in Figure 1 was generated
using the Iron Speed
Designer code generator with
code generation tags inserted into
an HTML layout page file. Each
job application is a row in the
data grid and includes two additional
tables within the row –
employment history and education.
The code generation tags are
illustrated in Figure 2.
Figure 1
Figure 2
When you consider the difference
in time and programming
effort to insert one code generation
tag into an HTML page as
opposed to hand-coding all the
ASPX, C#, or Visual Basic codebehinds
– plus SQL statements for
each control – it is easy to see
how quickly a code generator
saves you significant time.
Some of the advanced functions
enterprise-class code generators
can handle include:
Displaying data in a data grid
or table view (ranging from
simple row-and-column tables
to sophisticated tables within
tables)
Parent-child relationships
(one-to-many and many-tomany
tables)
Filtering and sorting (especially
in combination with
other page controls)
Multitable joins (from the
same database or across
multiple databases)
Databound controls (e.g.,
search, sort, navigation)
Template-driven columns
(e.g., box columns, uneven
column height, multiple
databases)
Custom pagination (e.g.,
alphabetical, non-evenly distributed,
etc.)
Generation of custom SQL
statements
Data Entry
Many data grids serve their
purpose as simple tabular data
displays. However, many CRM,
contact management, and other
back-office Web applications
also need to offer forms input
functionality to application users.
ASP.NET offers some shortcuts
to make fields editable.
However, making an entire data
grid editable or allowing editing
of template columns (using
dropdown menus, for example),
requires an advanced knowledge
of ASP.NET. A state-of-theart
code generator will allow
you to make individual data
grids or entire forms editable
without hand coding (see Figure
3). Dropdown lists, radio buttons,
and other controls should
also be options for any data grid.
Figure 3
Efficiently Managing Large Result Sets
The standard ASP.NET
DataGrid control fetches the
entire result set from a database
query into the .NET application
layer, even if that result set has
millions of rows. This leaves the
application layer to do the
heavy lifting – sorting and filtering
– activities best left to the
database rather than the application. Manipulating large
datasets in the application layer
can have huge resource implications
for applications.
To minimize the data transmission
load and the application's
memory storage requirements,
many application developers
employ database cursor management
– a conventional, wellestablished
database technique –
to manage the number of records
downloaded from the database
with each data grid page request.
A code generator can generate
cursor-management code that
retrieves one page of data at a
time, and only when requested,
rather than retrieving the entire
data set.
Managing the "state" of your
application pages without dragging
down performance is one of
the most difficult challenges for
Web application developers.
When cursor management is
employed (see Figure 4), the
application program doesn't
attempt to maintain the data set.
When the next page (or any other
page) is requested, the generated
application program simply passes
the request to the database
layer, where the appropriate SQL
query is run again to request the
needed page's data. The query
parameters include the page
number requested and the batch
size, which is the number of
records per page.
Figure 4
Moreover, the SQL query is
rerun so that any records added
or deleted since the previous page
fetch are properly accounted for.
By contrast, if the cursor were
simply maintained, any data
updates would not be reflected
when going from page to page.
Custom Data Validation
In .NET, data validation is
done using a series of validation
server controls, or "validators,"
for each editable field value that
is displayed in a page. These validators
are attached to various
Forms controls. Three basic validators
are required for nearly
every editable field:
RequiredFieldValidator: Set to
"True" to ensure that a value is
always entered; set to "False"
to make a field noncompulsory
FieldValueControl: Verifies
that an appropriate value has
been entered (i.e., a string or a number)
RecordControlCustomValidator:
A "hook" that allows you to customize
a particular Required-FieldValidator for nondefault
situations
Note that additional validators
may be needed for some fields. For
example, if you set a limit of 11
characters for a phone number, you
need to add a FieldValueTextLength
Validator to ensure that an error
message is generated if the phone
number is not entered correctly.
Full-featured code generators will
generate these three required validators
for each field, as well as others
(like FieldValueTextLength) as
needed.
Let's look at a simple example.
Note: This example uses Visual
Basic .NET code, but the process
is very similar if using C#.
The real action happens in the
RecordCustomControlValidator,
where we customize and extend
the default validation. This specific
example extends the base
RecordControlValidator for the
"city" field to enforce a requirement
that the city entered matches
the shipping address for this record.
In .NET, the base record control
has two methods that allow
custom validation:
initValidatorControl: To
change default color, error
message, etc.
validateData: To add custom validation logic
Override these methods to add
your own custom logic.
In an application generated by
Iron Speed Designer, two classes
are generated: the first is a "generated
class" that is updated with
each regeneration; and the second
is a "safe class" that is never
regenerated and preserves your
custom logic.
Example: Edit Customers Page - Validate city field
EditCustomersRecord.aspx
EditCustomersRecord.safe.aspx.vb
EditCustomersRecord.gen.aspx.vb
Data Validation: In the City field
validation example shown in Listing
1, we add additional logic to the "safe
class" in order to override the
validateData function. A safe class is
generated once and never overwritten.
Thus, it does not have to be
rewritten for future applications if
your code generator can adopt
it and make it available for future
development efforts
After acquiring the City field, we
compare it to "Mountain View". If the
City is not Mountain View, then we
return "False," generating an error message
and keeping the user on the page.
If the validator returns "True," the user
proceeds to the next page.
Note that the custom validation
function is called every time the
user clicks any button that requires
validation. Thus, the "submit" button
calls the custom control, runs
the validation, and, if "True", continues
the process. The "cancel" button
returns "False" and aborts the
process.
This example is made simpler by
the fact that it builds on generated
code. Clearly, using a code generator
to automate the composition of the
several generated validators for each
field (usually the three discussed
earlier: RequiredField, FieldValue,
and RecordControl Custom
Validator) saves you significant
amounts of work. The generated
code can then be extended and
modified for fields that require further
customization, as illustrated in
our City field customization example.
When selecting a code generator,
also make sure that your custom
validations can be reused for subsequent
applications, in order to
leverage code assets across your
entire organization.
This Ain't Your Father's Code Generation
Generated code can and should
match the caliber of code written by
senior developers – the developers
you wish you could clone. Some of
the scalability and performance
enhancements provided by today's
code generators include the ability
to run on multiple servers, concurrency
management, and optimized
application performance in a .NET environment.
In summary, code generation
offers the following benefits:
Shaves weeks or months off
development cycles by eliminating
the need to hand-code much
of an application's infrastructure
programming.
Allows .NET developers to build
sophisticated data grids, Web
Forms, and page layouts without
hand-coding and without the limitations
imposed by the ASP.NET
DataGrid control.
Gives developers more flexibility
to accommodate last-minute
change requests.
Preserves modifications and code
extensions, accelerating development
of custom enterprise-class
applications, and quick reuse of
unique and proprietary intellectual
property contained in custom-
developed code libraries.
Getting advanced custom features
"for free" from your code
generator is more efficient than
hand-coding ASP.NET from
scratch. Make sure the code generator
you choose (or build yourself
) achieves the level of performance
and quality described
in this article.
Author Bio
Alan Fisher is cofounder and chairman of Iron Speed, Inc., maker of Iron Speed Designer, the popular application-generation software for rapidly building Microsoft .NET Web
applications. The challenge of building enterprise-class Web applications from scratch inspired Alan and his partners to launch Iron Speed to simplify and accelerate Web application development, particularly for the growing number of .NET Web application developers.
editor@ironspeed.com
Listing 1
'This Handler implements server side validation logic for the
'V_CityFieldCustomValidator control
Private Sub V_CityFieldCustomValidator_ServerValidate(ByVal source As
Object, ByVAl args As System.Web.UI.WebControls.ServerValidat
eEventArgs) _
Handles V_CityFieldCustomValidator.ServerValidate
'get the value to validate
Dim value As String = Me.V_CityFieldCustomValidator.
GetValueToValidate()
If (value <> "Mountain View")) Then
Me.V_CityFieldCustomValidator.ErrorMessage = "Please
move to Mountain View."
args.IsValid = False
End If
End Sub
All Rights Reserved
Copyright © 2004 SYS-CON Media, Inc.
E-mail:
info@sys-con.com