Had some fun this morning as we’re trying to get a simple framework set up for a web app, that others can understand, using out-of-the-box functionality if possible. I tried to avoid the normal tendency to put the ‘architecture hat‘ on and overcook it. If you can’t be bothered to read all of this then just scroll to the bottom for the ‘take home’ on binding against typed datasets with null values.
We started off the prototype with a typed Dataset (including a couple of DB tables, and key relationships between each), a table adapter for each table, and a DetailsView at the front end, bound to an objectdatasource, which in turn talks to a business object that calls the TableAdapter. That’s a lot for one sentence so from top to bottom…
DetailsView –> ObjectDataSource –> BusinessService –> TableAdapter –> Database
This all sounds pretty straightforward, and it is – unless (as in this case) you decide to have your business object pass back a single (strongly typed) DataRow for your front end to bind against. This seemed reasonable at the time because I only ever want to show one row here.
You’ll basically get a StrongTypingException for every null field you try and bind, because by default a null field value will raise an exception when accessed through its generated property.
We got distracted for a while exploring this as the natural tendency is to think ‘ah – I’ll make sure it doesn’t raise the exception’ – treating the symptom rather than the cause.
It turns out that any non-string field in a typed dataset table can’t have a default of null (or anything other than ‘raise exception’). If you stuff in a _null value directly in the XSD your fields will disappear from the public properties (rather curiously) when you compile – so that’s not an ‘enterprise’ option.
I tried changing the return type in my business method to a generic DataRow to try and force the data binding to NOT use the strongly typed properties (getting warmer but still no dice. I knew I was missing something really simple…
I then stumbled across a post (bottom of the page) that illustrated databinding will use different methods to bind based on what interfaces it finds. The binding mechanism basically has no choice but to use the strongly typed public properties on a strongly typed or generic DataRow, as there’s no way for it to successfully enumerate the values. If you bind against almost anything else you’ll most likely have no issues (it appears the databinding doesn’t rely solely on ITypedList). We’re now binding against a typed DataTable (rather than generic DataView) and all’s fine. If you want (rather) more info on ITypedList then look here.
So…
Don’t databind against a typed (or untyped) DataRow!