How do you remove a Validation Rule?

How do you remove a Validation Rule?

Old forum URL: forums.lhotka.net/forums/t/2047.aspx


JoeFallon1 posted on Friday, December 29, 2006

I use split classes and Codegen as much of my Base class as possible. Whenever I have a Status field I add a rule like this: (for Active and De-active values.)

ValidationRules.AddRule(AddressOf ContainsValidValue, New ValidValuesRuleArgs("Status", "A", "D"))

But in a recnet case, it turns out that both A and D are not part of the list of status values.

so in my developer level class I would like to call

Protected Overrides Sub AddBusinessRules()
 
MyBase.AddBusinessRules()

  'Here is where I want to remove the rule above and add a new one below.
  'But I do not see a ValidationRules.RemoveRule method.

  'Status
  ValidationRules.AddRule(AddressOf StatusContainsValidValue, New PNIRuleArgs("Status"))

End Sub

I do not see a way to remove the rule.

Any tips?

Rocky - does it make sense to have such a method?

Short term - I can always codegen things differently. But I would like a longer term solution.

Joe

RockfordLhotka replied on Friday, December 29, 2006

I suppose it would be possible to remove a rule - though you'd need to know its full name. In 2.1 now, that is possible, because of the new rule://method/property?arg1=val1 scheme for naming rules. That URI is the rule's unique name, and would allow removal of a specific rule.

I'm not sure that would help you necessarily though, as you'd have to be able to create that full URI to identify the specific rule to be removed. Unless I supported a wildcard scheme by which you could remove rule://method/property?* or something like that.

xal replied on Friday, December 29, 2006

Here's what I think, not everybody will agree of course...

Rules are part of the object, or now that we have type rules, they apply to a type any instance of a class.
In a way similar as to people have "rules" incorporated and know when to apply them or not, it's in the rule where you decide whether it's valid or not. Part of that "is valid or not" is knowing whether the rule applies to the object or not, and we do that based on the data contained within the object.
There are many situations where the rule does not apply if certain property contains the value "x", and in those scenarios it would be painful to have the rules removed and added back if that property gets a value <> "x".

So, as a general rule, I do this:

Private Shared Function ValidateSomething(target as MyClass, e as RuleArgs) As Boolean
    If target.CertainProperty = "x" Then
       Return True
    End If
    If target.SomeOtherProperty = 2 Then
       e.Description = "Value cannot be 2"
       Return False
    End If
    Return True
End Function


Another important thing to keep in mind here is that if you use type rules, removing a rule will apply to ALL your live objects, not just the current one... So if that's the way you want to go, you MUST use instance rules.

My 2 cents.

Andrés

JoeFallon1 replied on Saturday, December 30, 2006

Andres,

I am using Type rules. The real problem is that I codegen the rule for Status (and assumed that A and D would be in  the list of valid values) and now I have to either:

1. Comment out the rule in my Gen level class (which will work for now but if the class is ever re-generated then it is posisble that the rule would not be commented out in the future.)

2. Remove the rule in my developer level class and add a new rule for the Status field which uses the correct values.

So I do not need Instance rules - the rule I Generated is "bad code" and now I need to remove it for the Type and add back a new rule.

As I said, modifying the code gen process to not create the rule in the first place is a better idea - but I am looking for a different solution right now. I want to be able to use RemoveRule as easily as AddRule.

Thanks.

Joe

 

xal replied on Saturday, December 30, 2006

And you don't have a "codegen file" you can alter so that you can change the rule in there and regenerate the code?
What are you using to generate code?

Andrés

JoeFallon1 replied on Saturday, December 30, 2006

Yes - I do have Codesmith templates which I may have to alter.

But, that is not the point of the question.

I would appreciate suggestions/comments about the the need/ability to remove rules if applied in a codegen class and you need/want to assign a different rule in the developer level class.

Assuming the need to do so is valid - what is required in the framework to create a method called RemoveRule? What would it have to know and be able to do?

Thanks.

Joe

 

xal replied on Saturday, December 30, 2006

Well, considering my position on rules which, again, not everybody will agree with, I think what you're trying to do is a workaround to a code generation issue.
If it's just a workaround you're trying to do, you may as well comment out the generated function and create one with the same name in your partial class. That way if you ever regenerate, you'll get a compile time error, which you can easily fix. Still, not as good as removing the rule or making your code generator output what you want, but it doesn't rely on a framework change that _might_ never happen....

Andrés

DansDreams replied on Saturday, December 30, 2006

Joe, I'd have to agree with Andres here.  I don't understand why you're looking for a band-aid when you've already identified the problem is you're generating "bad" code.

RRorije replied on Tuesday, January 02, 2007

Just my 2 cents,

You could also alter your templates to add the particular rule in a seperate function that can be overriden. By default the rule will be added, but in particular cases, you could replace the rule with something else, by inheriting this function in your custom (not generated) class.

JoeFallon1 replied on Tuesday, January 02, 2007

I like the idea of being able to Override a separate function. The default behavior of the function would be to call the Shared rule. But if I Override it then I can write anything I need.

Thanks - I will try to implement it.

I tried it out for the Rule but since Shared methods are not Overridable it did not work. Then I moved everything to Instance Rules which are not Shared and I could override it. But I didn't like that.

So I left the original rule in place but coded an overridable function to get the list of valid values.
That works nicely and I will add that to my template. Thanks for the idea.

ValidationRules.AddRule(AddressOf ContainsValidValue, New ValidValuesRuleArgs("Status", GetValidValues))

etc.

Public Overridable Function GetValidValues() As String()
 
Return New String() {"A", "D"}
End Function

In the Developer level class I use:

Public Overrides Function GetValidValues() As String()
 
Return New String() {"A", "X", "H", "V", "N", "I", "R", "L", "O", "P"}
End Function

Joe

 

Copyright (c) Marimer LLC