Out of box null validation: dataset / lgen

Posts   
 
    
thnk2wn
User
Posts: 31
Joined: 05-Jul-2008
# Posted on: 28-Oct-2008 15:47:45   

Runtime Library Version: 2.6.8.1013

.NET 3.5, Adapter, General2008, Oracle 9i

I have attached a sample prototype app where I am doing simple databinding and expecting basic out of the box validation for null fields that are required etc. on a new entity. At runtime I have an LGEN form version and a DataSet form version launch.

Below are the issues I currently have with the LGEN version that I do not have with the DataSet Version

1) Startup: LGEN version controls are not empty and are set to default values. For example, UltraDateTimeEditor fields default to today's date instead of null, combobox defaults to first value in the list. In dataset version the controls are blank.

2) Startup: Error providers do not appear on LGEN version as they do on dataset version.

3) "Unfriendly" error messages when clearing a field. I.E. w/LGEN it's "Object of type System.DBNull cannot be converted to type System.DateTime" as opposed to "Field [X] is required" w/dataset implementation.

If I turn of "Enable just my code debugging" I do see the following exception:

System.ArgumentException occurred Message="The control's value cannot be set outside the range determined by the 'MinValue' and 'MaxValue' properties." Source="Infragistics2.Win.UltraWinEditors.v8.2" StackTrace: at Infragistics.Win.UltraWinEditors.UltraDateTimeEditor.InternalSetDateTime(DateTime newVal) InnerException:

Which happens b/c required (non-nullable) date fields are System.DateTime.MinValue and control's MinDate is 1/1/1753. But again this problem is not present w/dataset implementation.

Am I missing the boat here or is there custom validation framework level code I have to implement to get similar results with LLBLGEN? I was thinking these basics would be out of the box but I do not mind rolling custom code I just could use some direction in implementing. Thanks

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39861
Joined: 17-Aug-2003
# Posted on: 28-Oct-2008 18:06:13   

As you're using infragistics controls, we can't help you, as they in general are unwilling to implement proper non-dataset binding code. It already took a long time before they even wanted to implement ITypedList, a mandatory interface for databinding!

If you can illustrate similar behavior with vanilla .NET controls instead of infragistics controls, we will look into it.

For example: that the controls aren't empty is simply not our fault: if there's data, you'll get data, if there's not, (e.g. new entity), the control should not display anything. A DateTime entity field isn't defaulted to today's date, so if infragistics thinks they should display today's date because the type is Nullable<DateTime> (which isn't a type supported by datasets, hence the issue), we can't fix it as it's not something we can change.

In general about 'Unfriendly' error messages: it's the default error message. if you want better ones, implement a validator.

About this error: the error you're seeing is not happening with datasets because they don't have support for Nullable<T>, and infragistics apparently has no notion of that type being in the .NET framework as well... disappointed

I mean: 'DBNull.Value'... that's not a valid value for Nullable<DateTime>, no matter what you want. Of COURSE you'll get an error, but we can't do something about that, because the control should realize it's not bound to a dataset but to a normal object.

About the DateTime.MinValue... a NEW entity has no values in its fields. If the field is of type DateTime and not nullable, and a control READS it, what kind of value should be returned? So the framework returns a default value. These default values are in HelperClasses\TypeDefaultValue.cs. This is generated with a template you can override if you want to (bind a different template to TemplateID SD_TypeDefaultValueIncludeTemplate). Still, this won't solve your problem, as the Column value for an empty cell which isn't nullable is simply empty string for a datatable. Of course, we can't return an empty string from a DateTime typed property. Often controls can be set to a 'default value for null', not sure if infragistics offers this feature.

I'm not sure what infragistics offers in the case of pre-/post bind events, but with normal controls I have no problem binding entities to it...

Of course, binding a new object to controls will force the controls to read the properties of the bound object. If you bind an object with non-nullable value typed fields, these properties WILL return a value. (dataset returns untyped values!) So these values will be shown in the controls. It's then a matter of telling the control that the value they get back initially is a value to ignore.

Frans Bouma | Lead developer LLBLGen Pro
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39861
Joined: 17-Aug-2003
# Posted on: 28-Oct-2008 18:49:09   

I tried a vanilla DateTimePicker with an empty entity, and bound it through a bindingsource, set the value to MinValue and it defaulted to 'today'. When I set the value to some valid value, it worked too.

This to illustrate that control vendors are sometimes the ones where things go haywire wink

I should have added: you can also initialize an entity in an override to OnInitialized (where you should test on this.Fields.State != EntityState.New, and if that's the case, set the field values)

Frans Bouma | Lead developer LLBLGen Pro
thnk2wn
User
Posts: 31
Joined: 05-Jul-2008
# Posted on: 28-Oct-2008 19:15:45   

Hmm. It just seems hard to believe that between one of top control vendors and one of the top data access vendors that something so basic as this would not just work.

I know other LLBLGEN customers have used Infragistics successfully and extensively but I am not sure as to what extent of work was involved. Maybe I can ask around if no luck there I can always reinvent the wheel.

I may try contacting Infragistics but not holding my breath there.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39861
Joined: 17-Aug-2003
# Posted on: 28-Oct-2008 20:48:27   

thnk2wn wrote:

Hmm. It just seems hard to believe that between one of top control vendors and one of the top data access vendors that something so basic as this would not just work.

Well, I can't tell you what to believe or not, of course, but I can tell you this: I think a year ago or so we were fed up after years of telling customers to work around crappy ITypedList support in infragistics controls. (If a grid doesn't obey ITypedList, it will simply reflect over the type and display all properties in the grid as a column, so you'd get all properties of the entity base class as a property, also , in selfservicing scenario's it would trigger lazy loading...) So we told infragistics that if they didn't fix it pronto, we would advice all our thousands of customers to avoid infragistics at all. That helped. Well, sort of. It first took months before they started and when they started, I literaly had to explain the engineer twice how to implement ITypedList and how it works. Admitted, Microsoft's ITypedList documentation isn't that deep, but then again, I'm not in the control vendor business, and even I know how it works... They seem to have implement it in the current version of their control set.

Let's look at a tiny example in your post: cannot convert DBNull.Value to DateTime. That's just silly, isn't it? simple_smile I mean: you bind an entity to a control and the entity has a property of type 'DateTime'. Sure, it is bound through ITypedList, and IListSource, like DataTable (which uses IListSource to bind a DataView, we use IListSource to bind an EntityView(2)) but that doesn't mean the object bound is a datarow, so DBNull.Value is never a valid value for a property typed as DateTime, the control cannot and should not pass DBNull.Value to the object's property. The fact that it tries to do so, is showing the state of some of their code, which in other areas probably shines, but this is clearly unacceptable.

I know other LLBLGEN customers have used Infragistics successfully and extensively but I am not sure as to what extent of work was involved. Maybe I can ask around if no luck there I can always reinvent the wheel.

Well, about the DateTime.MinValue... you can work around that with the template. Otherwise: the entity property has to return a value, so the bound control will receive that value and display it. That's not something that's odd, it's simply a given with binding an entity to a control, or binding any object to a control.

It's just that control vendors have sometimes codepaths specially for datasets which they think are the core objects used with their controls. Even Microsoft. I've to look it up, but we had an edge case in the past where binding a DataView directly would make the datagrid behave differently than a DataTable (which binds through a DataView!). Go figure. simple_smile

databinding is a great thing to have, but there are many pitfalls. Unfortunately, we can't write special code for every control out there, so instead we write code which works with the .NET controls shipped in .NET and we write code which obeys the standard interfaces for databinding, like IBindingList, IListSource, ITypedList, IEditableObject. There's a lot of code in the entity base classes for just these interfaces. That a control vendor then drops teh ball somewhere... I wished it was differently and something I could change so I could fix it myself and everyone here could benefit. Sadly that's not always the case.

Frans Bouma | Lead developer LLBLGen Pro