IDataErrorInfo issue

Posts   
 
    
tomahawk
User
Posts: 169
Joined: 02-Mar-2005
# Posted on: 20-Dec-2008 02:17:45   

v2.6.08.0911

Hi, I'm using the following code for an empty string check, leveraging LLBLGen's IDataErrorInfo support.

Here is the validation code:

    
[DependencyInjectionInfo(typeof(CL.DAL.EntityClasses.EmailEntity), "Validator", ContextType=DependencyInjectionContextType.Singleton)]
    public class EmailValidator : ValidatorBase
    {
        public override bool ValidateFieldValue(IEntityCore involvedEntity, int fieldIndex, object value)
        {
            bool toReturn = true;
            switch ((EmailFieldIndex)fieldIndex)
            {
                case EmailFieldIndex.EmailAddress:
                    if (String.IsNullOrEmpty((string)value))
                    {
                        involvedEntity.SetEntityFieldError(((EntityField2)involvedEntity.Fields[fieldIndex]).Name, "This is a required field.", true);
                        toReturn = false;
                    }
                    break;
                default:
                    toReturn = true;
                    break;
            }
            return toReturn;
        }
    }

Here is the scenario:

  1. User sets EmailAddress to empty string.
    ((IDataErrorInfo)this)["EmailAddress"] = "This is a required field"

  2. User sets EmailAddress to "asdf". ((IDataErrorInfo)this)["EmailAddress"] = ""

  3. User sets EmailAddress to empty string. ((IDataErrorInfo)this)["EmailAddress"] = "This is a required field"

  4. User sets EmailAddress to "asdf". ((IDataErrorInfo)this)["EmailAddress"] = "This is a required field"

The result after 4 should be that the error info is cleared. My validator is not getting called, presumably because "asdf" was never changed, it stayed that way in the entity after 2 & 3, which is fine. But the Error info must be cleared after 4, otherwise my UI still thinks there is an error.

On a call to SetValue, where the value is the same, can you please clear the info? This should be ok, as the value must be valid, or it wouldn't have made it into the entity to begin with.

Thanks, Josh

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 20-Dec-2008 03:16:18   

That's because LLBLGen doesn't detect any change in the field, then no validated is fired. See, this is how it works:

  1. You modify a field.
  2. LLBLGen detects a change, so it calls validating methods to see if everything is OK.
  3. Your validation routines detects a breaking rule, so return false, then LLBLGen WILL NOT CHANGE THE FIELD VALUE (isn't valid), and a error message is set (by your code, of course).
  4. You back to your original field value, but the value indeed remains as original (see point 3). So, as no change is detected, no validation is fired.

So, that's the way it is and it's ok in my opinion (validation logic doesn't have to do strictly with IDataError interfaces). To workaround this, please try pasting the following on the EmailEntity code (either on CODE_REGIONS or partial class):

protected override void OnSetValue(int fieldIndex, object valueToSet, out bool cancel)
{
    if (Fields[fieldIndex].CurrentValue != null)
    {
        if (Fields[fieldIndex].CurrentValue.Equals(valueToSet)
            && !string.IsNullOrEmpty(((System.ComponentModel.IDataErrorInfo)this)[Fields[fieldIndex].Name]))
        {
            SetEntityFieldError(Fields[fieldIndex].Name, string.Empty, false);
        }
    }

    base.OnSetValue(fieldIndex, valueToSet, out cancel);
}

This should clean the error if the user enter the same (valid) value.

David Elizondo | LLBLGen Support Team
tomahawk
User
Posts: 169
Joined: 02-Mar-2005
# Posted on: 20-Dec-2008 04:15:12   

Thank you for the workaround, but I need this behavior for all entities, which means I have to write a custom template now.

Without this code, LLBLGen IDataErrorInfo support is, in my opinion, incomplete. With the case I describe the IDataErrorInfo support fails, as the errors are in an incorrect state. The code you present I would actually consider a fix, not a workaround.

Can this code be integrated into LLBLGen's runtime SetValue function, or do you see a reason this isn't correct?

Thanks, Josh

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39613
Joined: 17-Aug-2003
# Posted on: 21-Dec-2008 11:46:10   

The workaround can be implemented in a partial class of CommonEntityBase, which is an empty class which is generated between the generated entity classes and the base class.

I indeed see your point. It's a bit of a problem, where the fix should be placed and how: a) calling the validator again? or b) clearing the error info.

Both require that the framework knows that external code set the error info (why otherwise call the validator, the value won't change anyway, and why clear the error info, the value is already set. )

Though I think option b is the better one, as calling the validator is simply not something logical to do (as the value won't be changed anyway as the current value is the same, so it's valid). Clearing the error info for the particular field is indeed something which should remove a lot of headaches I think. simple_smile

It's funny, I ran into this recently with llblgen pro v3 where these kind of things (IDataErrorInfo etc.) is oursourced to specialized classes and member variables are stored in special member classes which are undo/redo aware. Anyway, everything worked fine, till a valid value was entered again, and I ran into the similar scenario, that I somehow had to clear the error info. I didn't make the link back to the runtime code which had the same 'flaw'.

I'll try to add the clear-error info call to the value setter.

Frans Bouma | Lead developer LLBLGen Pro
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39613
Joined: 17-Aug-2003
# Posted on: 23-Dec-2008 11:44:47   

Fix is available in the next build (buildnr 12232008 or higher)

Frans Bouma | Lead developer LLBLGen Pro