GUI Validation and Entity Validators

Posts   
 
    
GavinSinai
User
Posts: 3
Joined: 27-Sep-2007
# Posted on: 27-Sep-2007 15:29:59   

Hi

We are in the process of evaluating ORM tools and LLBLGen Pro seems to be the best tool to use. We would like to use Entity validation using the dependency injection mechanism. We have the following interesting design issues

(1) Validation should be done at the Entity level, so that the whole application can benefit from it (2) We appreciate that validation exceptions are useful to stop transactions (3) We would also like databound controls to be validator aware.

How does one go about this? Is there a way of doing validation so that one doesn't have to implement validation twice, i.e. the validation rule is written once and both .NET GUI Validators (ASP.NET/WinForms) and Entity Validators are aware of the rule.

An additional complication is that we will use Infragistics WinForms controls. (I am aware that the LLBLGen team do not recommend the Infragistics Web controls).

Regards

Gavin

Walaa avatar
Walaa
Support Team
Posts: 14995
Joined: 21-Aug-2005
# Posted on: 27-Sep-2007 16:26:38   

(2) We appreciate that validation exceptions are useful to stop transactions

Throwing an ORMEntityValidationException in the validation code makes sure any transaction currently in progress will be terminated.

(1) Validation should be done at the Entity level, so that the whole application can benefit from it. (3) We would also like databound controls to be validator aware.

These are almost the same point, right? - Field Validation works when an entity field is SET to a different/new value. So if your GUI controils are "2-way" bound to an entity/entityCollection Inputs from the user will be validated and false inputs will be rejected. - And can call entity.ValidateEntity to validate the entire entity at any given point of time. - The .NET interface IDataErrorInfo is implemented on the entities. So in your validation code you can call entity.SetEntityError() & entity.SetEntityFieldError() to set error information, that can later be read in the GUI using an ErrorProvider control.

GavinSinai
User
Posts: 3
Joined: 27-Sep-2007
# Posted on: 27-Sep-2007 18:01:47   

OK Thats great. I have done everything you have said.

(1) The Validator's BeforeSave() method throws an ORMEntityValidationException (2) The field validator uses SetEntityFieldError() and returns false if the field concerned is not valid.

Everything works except for the fact that:

Field Validation forbids a field from holding invalid values. Thats ok, but corresponding databound fields(e.g. gridview cells) are also forbidden from holding those values. As the user navigates away from the gridview field s/he has just modified, the field value reverts back to the original value.

E.g. invalid phone number, all the user may need to do is remove an invalid character, now they have to re-enter the phone number.

Its clear that the entity can't contain invalid data, but the grid view cell most certainly can (along with an error icon to indicate that the cell is not in a valid state). If the grid view is forced to be synchronized with the entity, then the user experiences data loss (which really isn't a good thing).

How to balance the integrity of the entity versus the useability of the application? Is there a best practise?

Regards

Gavin

Max avatar
Max
User
Posts: 221
Joined: 14-Jul-2006
# Posted on: 28-Sep-2007 10:01:55   

GavinSinai wrote:

OK Thats great. I have done everything you have said.

(1) The Validator's BeforeSave() method throws an ORMEntityValidationException (2) The field validator uses SetEntityFieldError() and returns false if the field concerned is not valid.

Everything works except for the fact that:

Field Validation forbids a field from holding invalid values. Thats ok, but corresponding databound fields(e.g. gridview cells) are also forbidden from holding those values. As the user navigates away from the gridview field s/he has just modified, the field value reverts back to the original value.

E.g. invalid phone number, all the user may need to do is remove an invalid character, now they have to re-enter the phone number.

Its clear that the entity can't contain invalid data, but the grid view cell most certainly can (along with an error icon to indicate that the cell is not in a valid state). If the grid view is forced to be synchronized with the entity, then the user experiences data loss (which really isn't a good thing).

How to balance the integrity of the entity versus the useability of the application? Is there a best practise?

Regards

Gavin

Hi, I'm in the same situation, we are using LLBLGen 2.5 and WinForms / Infragistics 6.3 (I need to do the upgrade to 7.2 one of these day... simple_smile

the possibility to hold the invalid data is a configuration you need to do on the ultragrid properties:

on the UgCellDataError event, you need to set the following event properties

e.StayInEditMode = True
e.RaiseErrorEvent = True 'tell the ultragrid to generate the [Error] event

and, on the ultragrid [error] event

    If e.DataErrorInfo IsNot Nothing Then
        'don't show ultragrid message box error
        e.Cancel = True

        'if ther is no error setted on this column...
        If DirectCast(e.DataErrorInfo.Cell.Row.ListObject, System.ComponentModel.IDataErrorInfo).Item(e.DataErrorInfo.Cell.Column.Key) = "" Then
            'use the error generated by the ultragrid (this happen when you set an inossible date like "30/02/2000" in a datepicker control or similar things)
            DirectCast(e.DataErrorInfo.Cell.Row.ListObject, EntityBase2).SetEntityFieldError(e.DataErrorInfo.Cell.Column.Key, e.ErrorText, False)
        End If
    End If

other things we do: *) on the AfterCellCancelUpdate event, we reset the error on the entity column

DirectCast(e.Cell.Row.ListObject, EntityBase2).SetEntityFieldError(e.Cell.Column.Key, "", False)

*) setup the grid to show the error set by the validator

mUGrid.DisplayLayout.Override.SupportDataErrorInfo = SupportDataErrorInfo.RowsAndCells

Anyway, we hardly force this type of per-field validation, because in this case the user is locked in the current field and cant go out without correcting the data. We, instead, prefer to do all the checking in the beforeEntitySave event, so the user can't save the entity with wrong data, but with a single click can see all the error (the single click is when the user click the SAVE button simple_smile .

GavinSinai
User
Posts: 3
Joined: 27-Sep-2007
# Posted on: 28-Sep-2007 13:40:06   

Thanks ... that seems to be the "best practise" I was looking for.