Field Validation

Posts   
 
    
tedh
User
Posts: 34
Joined: 14-Dec-2006
# Posted on: 05-Jan-2007 16:05:52   

I just want to make sure I'm not overlooking something.

For on-screen WinForms field validation with SelfServicing we are to override: bool ValidateFieldValue(IEntityCore involvedEntity, int fieldIndex, object value)

But this method provides a pass/fail notification only. So if a validation can fail for more than one reason it is hard to provide different error messages to the user based on the reason for the fault.

A solution to this problem is presented by Joseph Chancellor in his book on LLBLGenPro 1.x. Here he uses a custom validation logic routine (ValidatePropertyAssignment) instead of ValidateFieldValue (which was not available in 1.x). The ValidatePropertyAssignment provides references to a ControlToValidate an ErrorMessage and an ErrorProvider which provides a feedback mechanism to the Gui.

I am currently using this approach, but this solution also presents some difficulties. The problem is determining in which Event to trigger ValidatePropertyAssignment eg: Leave, ValueChanged, Validating, etc. Each WinForms control has its own peculiarities regarding firing of events and the potential to bypass validation depending on how the field is exited. The advantage of using ValidateFieldValue is that it is guaranteed to execute when an Entity property changes.

Is there the possiblility for additional overloads to ValidateFieldValue to provide some added flexibility?

Thanks

Walaa avatar
Walaa
Support Team
Posts: 14946
Joined: 21-Aug-2005
# Posted on: 05-Jan-2007 16:22:36   

Copied from the LLBLGen Pro manual "Using the generated code -> Validation per field or per entity":

IDataErrorInfo implementation The .NET interface IDataErrorInfo is now implemented on EntityBase and EntityBase2. Two methods have been added to the entities: SetEntityError and SetEntityFieldError, which allows external code to set the error of a field and/or entity. If append is set to true when calling SetEntityFieldError, the error message is appended to an existing message for that field using a semi-colon as separator.

Entity field validation, which is triggered by SetNewFieldValue(), sets the field error if an exception occurs or when the custom field validator fails. The error message is appended to an existing message.

So inside your ValidateFieldValue implimentation you can set the error message that you want, using SetEntityError or SetEntityFieldError

tedh
User
Posts: 34
Joined: 14-Dec-2006
# Posted on: 05-Jan-2007 19:19:46   

Hi Walaa,

Thanks for the reply. I tried to use SetEntityFieldError. My code sample is below.

My validation is not working. The result is that I am able to update the field NextInvoiceNo to any valid integer value, but I have put in a constraint that NextInvoiceNo must be less than 100. In the debugger I have verified that the routine below is executed inlcuding the SetEntityFieldError statement.

I have used SetEntityFieldError successfully with Infragistics grids, but in this case the field is being displayed in a Infragistics UltraTextEditor. What I want is to display the error message in an ErrorProvider. Is there something else I have to do in my code to get this working?

I am also realizing that the check I have included to verify that the keyed entry is a valid integer is unneccessary because LLBLGen is doing this automatically. However if I want to display an ErrorProvider message to tell the user what the problem is then my duplicate check may have some value. Is this correct?

Thanks

        public override bool ValidateFieldValue(IEntityCore involvedEntity, int fieldIndex, object value)
        {
             bool IsValid = true;

              switch ((SystemManagerFieldIndex)fieldIndex)
            {

                case SystemManagerFieldIndex.NextInvoiceNo:

                    involvedEntity.SetEntityFieldError(SystemManagerFields.NextInvoiceNo.Name, string.Empty, false);

                    int intTest;
                    if (int.TryParse(value.ToString(), out intTest) != true)
                    {
                        involvedEntity.SetEntityFieldError(SystemManagerFields.NextInvoiceNo.Name, 
                            "Next Invoice No must be an integer", false);
                        IsValid = false;
                    }

                    if ((int)value >= 100)
                    {
                         involvedEntity.SetEntityFieldError(SystemManagerFields.NextInvoiceNo.Name, 
                            "Next Invoice No must be < 100", false);
                        IsValid = false;
                    }
                    break;

                 default:
                    break;
            }

            return IsValid;
}
bclubb
User
Posts: 934
Joined: 12-Feb-2004
# Posted on: 06-Jan-2007 04:18:23   

The value is also type safe since NextInvoiceNo is of type int most likely. As far as Validator isn't working. Do you mean that the message isn't being displayed and the value is being changed or just that the message isn't being displayed?

tedh
User
Posts: 34
Joined: 14-Dec-2006
# Posted on: 06-Jan-2007 05:02:09   

If I key in the number 75 it is accepted and persisted correctly.

If I key in the number 250 it does not get persisted (because it is greater than 100). The value 250 shows on the screen ( the screen does not revert to the previous value). Also no error message shows and I am positioned to the next field on the screen.

Chester
Support Team
Posts: 223
Joined: 15-Jul-2005
# Posted on: 07-Jan-2007 01:23:44   

tedh wrote:

If I key in the number 75 it is accepted and persisted correctly.

If I key in the number 250 it does not get persisted (because it is greater than 100). The value 250 shows on the screen ( the screen does not revert to the previous value). Also no error message shows and I am positioned to the next field on the screen.

I'm not clear about whether you've attempted to persist the entity or not. If you move from one control to another in the UI, validation on your object isn't going to fire. If you are persisting, then have you tried setting a breakpoint in the debugger to see whether your validation is getting fired?

tedh
User
Posts: 34
Joined: 14-Dec-2006
# Posted on: 09-Jan-2007 23:09:40   

I still have the problem above. Let me try this from a different angle.

My application is WinForms and I am displaying a single Employee entity on a form (no grid). SelfServicing .Net 2.0.

Below I have provided code for ValidateFieldValue(). I have to validate that each Employee has a unique EmployeeCode. So in the validation code I create a new EmployeeEntity with the proposed EmployeeCode and I check if the returned entity has Fetched fields, in which case I have a duplicate. What I want to see is my error message displayed right beside the EmployeeCode TextBox on my form (it is really a Infragistics UltraTextEditor).

When I run this code and key in a duplicate EmployeeCode and tab out of the EmployeeCode field I definitely see the validation code execute in the debugger and the SetEntityFieldError statement is executed. However on the form I don't see any error message and all that happens is that I am positioned to the next field on the form.

I think that my validation code is in line with the documented examples so my question is what else do I have to do to get this to work? Do I need an ErrorProvider Control on my Form (I have tried with and without), do I need to include some logic on my Form.

Hopefully this clarifies my problem.

Thanks

       public override bool ValidateFieldValue(IEntityCore involvedEntity, int fieldIndex, object value)
        {

            bool isValid = true;
            string errorMessage = string.Empty;

            EmployeeEntity entity = involvedEntity as EmployeeEntity;

            involvedEntity.SetEntityFieldError(entity.Fields[fieldIndex].Name, string.Empty, false);


    switch ((EmployeeFieldIndex)fieldIndex)
    {

        case EmployeeFieldIndex.Code:

                    if (entity.IsNew)
                    {

                        // Check that EmployeeEntity.Code is not a Duplicate
                        EmployeeEntity e = new EmployeeEntity(value.ToString());
                        if (e.Fields.State == EntityState.Fetched)
                        {
                            errorMessage = "Duplicate employee code";
                            entity.SetEntityFieldError(EmployeeFields.Code.Name, errorMessage, true);
                            isValid = false;
                        }
                    }
                
                    break;

                 default:
                    break;
            }

            return isValid;
        }
Walaa avatar
Walaa
Support Team
Posts: 14946
Joined: 21-Aug-2005
# Posted on: 10-Jan-2007 08:40:31   

Now you have the error stored for you but then you have to display it in the appropriate time (event).

You can grab the error and display it in a label or any other control. An you can do this in the loose focus event of the Code textbox.

tedh
User
Posts: 34
Joined: 14-Dec-2006
# Posted on: 10-Jan-2007 15:13:21   

Where is the error message stored. I have tried looking in the debugger in the Entity instance, the Code textbox and the error provider without any luck.

Thanks

Walaa avatar
Walaa
Support Team
Posts: 14946
Joined: 21-Aug-2005
# Posted on: 10-Jan-2007 16:00:09   

DataErrorInfoErrorsPerField property of the entity. Please refer to the LLBLGen Pro reference manual.

tedh
User
Posts: 34
Joined: 14-Dec-2006
# Posted on: 10-Jan-2007 17:57:51   

Thank you. I found DataErrorInfoErrorsPerField.

Now as for the positioning of my logic, Infragistics does not have a Lose Focus event for the UltraTextEditor. They do have a Leave event but it seems that the ValidateFieldValue() method executes after this event.

Do you know what is the suitable event to use for Infragistics components? Also will this event also work for other Infragistics controls such as the UltraCalendarCombo?

Thanks

Walaa avatar
Walaa
Support Team
Posts: 14946
Joined: 21-Aug-2005
# Posted on: 11-Jan-2007 06:30:41   

Unfortunatly I'm not familier with the Infragistics controls, maybe someone here can help you out.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39588
Joined: 17-Aug-2003
# Posted on: 11-Jan-2007 11:57:55   

ValidateFieldValue is executed when the value is actually set. So any event which is raised from the control before a value is set is suitable.

Frans Bouma | Lead developer LLBLGen Pro
tedh
User
Posts: 34
Joined: 14-Dec-2006
# Posted on: 11-Jan-2007 14:53:19   

Hi Otis,

I think you mean the opposite.

I am referring to the logic to display the error messages with an error provider control. The error messages are saved in ValidateFieldValue so any logic to display those messages would have to be in an event that follows.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39588
Joined: 17-Aug-2003
# Posted on: 12-Jan-2007 10:39:39   

OK, though isn't that done via an 'ErrorProvider' control on the form? (that's a .net control), as the entity implements IDataErrorInfo, so it should provide the error message to the ErrorProvider control automatically.

Frans Bouma | Lead developer LLBLGen Pro
tedh
User
Posts: 34
Joined: 14-Dec-2006
# Posted on: 12-Jan-2007 12:55:20   

Otis wrote:

OK, though isn't that done via an 'ErrorProvider' control on the form? (that's a .net control), as the entity implements IDataErrorInfo, so it should provide the error message to the ErrorProvider control automatically.

Hi Otis,

This is what I am really trying to get to. I would really like if when I set SetEntityError and SetEntityFieldError that the messages would automatically appear in the ErrorProvider control that displays on my screen. However my understanding from Walaa is that these errors are stored in the Entity in the DataErrorInfoErrorsPerField property and that I must write my own logic to get these to display in an ErrorProvider. This means that I would have to write logic to iterate through the errors in DataErrorInfoErrorsPerField and figure out what controls were displaying the data and then loading the ErrorProvider. This is less than an automatic approach. At the moment I am finding it easier to use the methodology as outlined in Chancellor's book. Of course I might be missing something as I'm new to LLBLGenPro.

Walaa avatar
Walaa
Support Team
Posts: 14946
Joined: 21-Aug-2005
# Posted on: 12-Jan-2007 16:14:11   

Using an ErrorProvider on the form, should automatically display the errors you set.

However my understanding from Walaa is that these errors are stored in the Entity in the DataErrorInfoErrorsPerField property and that I must write my own logic to get these to display in an ErrorProvider

Sorry for the mis-understanding. I was suggesting this to be used if you don't want to use an error provider. I must have been lost between the posts.flushed

Anthony
User
Posts: 155
Joined: 04-Oct-2006
# Posted on: 23-Mar-2010 02:11:25   

I am doint he above but when i set SetEntityFieldError the message is not displayed next to the control.

It is going through the OnValidateFieldValue logic fine.

Do i have to modify the app.config....all i have is <add key="buildInValidationBypassMode" value="0"/>

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 23-Mar-2010 03:56:26   

You have to tell us more info (runtime library version, code snippet, etc: http://www.llblgen.com/TinyForum/Messages.aspx?ThreadID=7720) and, if you don't mind, please open a new thread as this is a very very old one. Don't hijack older threads.

David Elizondo | LLBLGen Support Team
Anthony
User
Posts: 155
Joined: 04-Oct-2006
# Posted on: 24-Mar-2010 04:20:32   

llblgen v2.6,adapter,vb.net,winforms..sorry wont hijack thread again