I know this has been done before, but I wanted to post some of the code that I used to do this. My goal was to take some of the simple business rules such as required, value range, string length, and regex expressions and express them as client validated rules so the postback does not occur before validation.
Can anything tell me if there is a better or more efficient way than this?
First, I had to get the rules from the data source. Then I took the string() of rule descriptions and converted it to the RuleDescription class (until it is built into the call for getting the descriptions).
Then I iterated through the rules and matched known rule types with validation controls and created them. I extended FormView control for my test of this functionality.
Sorry if you are C# folks. I usually write in C#, but this time it had to be VB.NET
The following code gets the data from the CSLA data source.
The next block goes in the CreateChildControls of the custom control. Keep in mind that if the code is called more than once, your code must be smart enough to not create multiples of the same validators (I checked for the existing control ID and reset all the properties to what they should be):If
Not dataSource Is Nothing Then ' Instantiate Object Dim result As Type = Nothing If Not String.IsNullOrEmpty(dataSource.TypeAssemblyName) Then ' explicit assembly name providedresult = Type.GetType(
String.Format("{0}, {1}", dataSource.TypeName, dataSource.TypeAssemblyName), True, True) ElseIf dataSource.TypeName.IndexOf(",") > 0 Then ' assembly qualified type name providedresult = Type.GetType(dataSource.TypeName,
True, True) End If' Read rules and save them in a collection
If (Not result Is Nothing) Then Dim obj As Object = result.Assembly.CreateInstance(result.FullName) Dim method As MethodInfo = result.GetMethod("GetRules") If Not method Is Nothing Then Return CType(method.Invoke(obj, Nothing), String()) End If End IfEnd If
Protected Overrides Sub CreateChildControls() MyBase.CreateChildControls() ' Get the CSLA business rules Dim rules As String() If ViewState("RuleList") Is Nothing Thenrules = GetRuleList()
ViewState(
"RuleList") = rules Elserules =
CType(ViewState("RuleList"), String()) End If ' The rule description class is not serializable, so we have to recreate it based on the CSLA Rule string() Dim ruleList As New System.Collections.Generic.List(Of RuleDescription) For Each rule As String In rulesruleList.Add(
New RuleDescription(rule)) Next
AddRulesToPage(ruleList)
End Sub
Posting all of the code is not neccesary, so the following is just a snip of the functionality (I skipped lines including error handling, comments, and other specific implementation:
For Each rule As RuleDescription In ruleList
Dim baseRule As BaseValidator = Nothing
Dim validatedControl As Control = FindControl(rule.PropertyName + suffix) If Not validatedControl Is Nothing Then Dim ruleType As SupportedRuleType = CType([Enum].Parse(GetType(SupportedRuleType), rule.MethodName, True), SupportedRuleType) Select Case ruleType Case SupportedRuleType.StringRequiredbaseRule = GetRequiredRule(validatedControl, rule, ruleType, caption)
Case SupportedRuleType.StringMinLength, SupportedRuleType.StringMaxLengthbaseRule = GetLengthRule(validatedControl, rule, ruleType, caption)
Case SupportedRuleType.IntegerMaxValue, SupportedRuleType.IntegerMinValue, SupportedRuleType.MaxValue, SupportedRuleType.MinValuebaseRule = GetValueRule(validatedControl, rule, ruleType, caption)
Case SupportedRuleType.RegExMatchbaseRule = GetRegExRule(validatedControl, rule, ruleType, caption)
End Select' Set common rule properties
If
Not baseRule Is Nothing ThenSetCommonRuleProperties(validatedControl, baseRule)
' If the validator is not already on the page, then add it. Some validators are used by multiple rules If (Not control.Parent.Controls.Contains(baseRule)) ThenvalidatedControl.Parent.Controls.AddAt(validatedControl.Parent.Controls.IndexOf(validatedControl) + 1, baseRule)
End If End If End IfNext ' Rule
Each call to Get___Rule returns the specific configured validation rule. Each rule has different requirements and properties set so I have not found a way to combine the methods.
Thanks for posting the snippet of code. I am trying to do the same thing that you discuss in this post.
Any chance of you attaching the complete code? It would be GREATLY appreciated!
Thanks,
Curtis
I know this is months old, but Can someone help me on this? Where does the code that gets the data from the CSLA datasource need to go?
Plus, what is this "SupportedRuleType"? Is this something that only relates to VB?
Plus, how is the SetCommonRuleProperties() function implemented???
Any help would be greatly appreciated! :P
Kay', I got most of that figured out now except 1 thing, I could really use some help regarding what "SupportedRuleType" is, it's the only thing I'm stuck with now.... I can't seem to find it anywhere in the Csla framework, and there's no documentation about this anywhere. Can someone lend a hand? :/
The only thing I can find in CSharp that possibly could be used is the CommonRules class..... but it's of static tye and can't be used like is shown here.... anyone?
Perhaps I'm talking alone here, but I have made progress with working around this mysterious "SupportedRuleType" class. However now I have a new question :)
Can anyone tell me how to overcome this issue with the FindControl( rule.PropertyName ) line in the AddRulesToPage function??? I can't seem to find any of the controls to validate in my Extended Contol at runtime and I'm at a loss on how else this could be done :(
Any help would be greatly appreciated. If I get this working I can post all my code in Csharp for all to benefit. I feel I'm getting closer if I could just overcome this.
p.s. rule.PropertyName is returning correctly.
Copyright (c) Marimer LLC