The architecture of your project can make or break it. It determines how fast you can add components, your dev time, time to fix bugs, etc. That being said, one architecture component in particular I have struggled with is how to build the architecture for binding to data controls of an ASP.NET page. These types of controls include GridViews, Repeaters and FormViews to name a few. By struggled with, I mean not that it is a hard exercise to do by any means, but rather the opposite. It is so incredibly easy to bind information to these controls, and so many ways to do it. Which leads me to the problem:
Which binding method do I use for this project? Some methods provide greater functionality with decreased flexibility. Others provide great reusability with poor performance.
The following outlines what I consider to be the major 4 methods of ASP.NET control binding: Direct Binding, DataTables, XSD’s, and Custom Objects / DataReaders.
Example Notes: Attached here and at the end of the article is the example solution that demonstrates the very basic functionality and code of each binding method. Note that it is a Visual Studio 2008 Solution and project file: Download BindingExamples Solutions . All screenshots and examples are used from this Solution. All pages have a final result of the screenshot above. SQL scripts and stored procedures found in this project as well.
When I say “Direct Binding”, what I am referring too is binding a GridView to an SqlDataSource which is in turn, bound directly to a stored procedure (or SQL query if you so choose). The markup code for this is nice and simple:
The best thing about the direct binding method is its simplicity. Not only is there ZERO coding involved, but the Visual Studio Wizard will walk you right through the entire process from adding the SqlDataSource, to creating the query with the “Query Builder”. To begin the wizard… you can grab a GridView object from your toolbar throw it on the page and hover over it to get the click through arrow, and choose Configure Data Source:
After you have bound and configured your data source that is it, the GridView should now be working. So now lets spell out the good and bad of this method.
The Scoop: The idea of directly binding your gridviews (through object data sources) to a database is extremely nice for smaller projects that require a straight CREATE, UPDATE, DELETE and of course VIEW web interface. If the application is simply a means for input data, and you need to expose the data basically how it looks in the database, then this method might be the best for you. As well for small projects this is ideal since you can provide advanced viewing features like paging, sorting, theming, etc, very very fast and cost effectively to the client. The key is to keep in mind this solution provideds almost no flexibility for additional business logic or reuseability.
Binding a DataTable to a GridView is also quite easy. However, by using a DataTable you are given the advantage of being able to develop the source of the DataTable on your own. Its source could be a Database server, however, it could be something completely different. You could create a DataTable filled with information from your MembershipProvider API, or you may have a dynamic set of information to show. In these scenario’s you’ll have to create a DataTable and programmatically bind it to a GridView. This has the advantage of keeping your Business Logic separate from your Presentation Logic, which is a key design principle in larger scale applications.
Quick run through on how to do it… Once again you can throw a GridView control object onto your ASP.NET markup page. In this example you don’t need an object data source when dynamically binding to the gridview.
To bind the DataTable you will have to write a big of code:
The key to dynamic binding is that you will have to rebind the data on any postback manually. Depending on what you are doing this may more difficult than not. In this example, I have filled a DataTable from a SQLDataReader which reads the results from a Stored Procedure. However, as mentioned the DataTable itself could arrive from anywhere in your system for binding. If you have a DataTable that differs from the output you want to show you will have to manually add the columns to the markup on the gridview and set the “AutoGenerateColumns” property to false (it is default set to true).
The Scoop: Dynamic Binding with DataTables provides a massive degree of flexibility, however also requires a great degree of custom code and work around any additional features. Your project may require dynamic columns, or use DataTables, in which case you may have no choice but to use DataTables. This may be your main que to start binding with DataTables.
The XSD (or Visual Studio DataSets) are very much a different beast (if I may say so). The XSD originated in Visual Studio 2005, so its a relatively new piece of the Framework. It essentially allows you to create DataTables and DataSet components in a visual way. You simply walk through its Wizard designing like you would a Database. You can create a DataSet just like any other item:
After you’ve created you DataSet1.xsd, all you have to do is right click anywhere in the gray and select “Add Table Adapter”:
Once you follow the wizard through your matching TableAdapter should look similar to above. Much like a DataTable you will see the fields and types that belong to that adapter, and also available methods that were created for retrieving that data. Depending on your selections in the Wizard you will have generated components for a complete “Fill” dataset that allows for updating, inserting, deleting, and viewing:
The Wizard will even allow you to configure Optimistic Concurrency on the adapter (checks that the data its changing is newest before making changes).
Once you have your DataSet and TableAdapters created you can then bind your ObjectDataSource as a Object to this TableAdapter which will show up in your IntelliSense list. Here is the markup:
Thats it you are done now. This method also requires writing zero code. Additionally, you could also write a Bussiness Object layer in this example, that would serve the ObjectDataSource and read from the TableAdapter programmatically. I will hopefully blog about this process in the future and provide some examples. Until then here are some examples of that method:
The Scoop: Again, XSD’s provide streamlined development process. However, you may pay the price later because of the low flexibility of business logic incorporated in the XSD. This is a great intermediate solution or step up if the Direct Binding method doesn’t quite meet your criteria.
There is still something to be said for writing your own custom code for a project without using XSD or datasets. By using some custom objects you get maximum flexibility as well as strongly typed objects with the greatest performance. In using custom objects, most people don’t even know that they can bind a List or Collection object (or anything that inherits from IEnumerable interface) to a GridView, or repeater, etc. In fact you even get some nice intelliSense on the markup page in Visual Studio 2008 when referring to the object. Here is a quick rundown on how to implement it:
First off, we will need a custom object. In my example I have a simple employee class:
Of course you don’t have to specify the specific columns if you set “AutoGenerateColumns” to true. However, I wanted you to see how you can refer to an object in the template section (for your custom implementations). Next take a look at how you can bind the objects:
Pretty simple eh? Yet effective!!! This is my favourite since it allows you implement this functionality on any system while still maintaining ultimate control over your custom object and data model structure. It still has the caveats mentioned with binding a DataTable since it is still dynamic binding of the object.
The Scoop: The custom methodology really really rocks in my opinion when you need performance, since it give you complete control over all area’s of the project with next to no overhead from any of the components that you would get on a DataTable, and especially on a XSD. However, when dealing with a CRUD situation, it can be quite tedious and monotonous to have to write additional code for something that you can get out of the box using another method.
What to say to sum it all up? In the end, each of these methods provides their own advantages and disadvantges. It should be your requirements, scalability, and project type that dictates which one of these methods to use.
Keep in mind that you can always use a combination of these methods. Perhaps, using an ObjectDataSource class that implements a custom data access layer is the way to go. Once you understand the tools at each level and how to piece your presentation to your bussiness logic / data access together while still maintaining that level of separation your best choice of architecture for binding will be quite apparant.