Web Rule Basics

Web Rule is an ASP.NET and MVC server component that allows creation, modification, validation and evaluation of complex business rules, as well as creation and execution of complex rule-based data filters for virtually all established LINQ providers. Using its web interface, business users can create rules or filters by selecting options from a series of context-sensitive drop-down menus. This IntelliSense-like approach is unique to web-based business rule management. With Web Rule integrated into your project, the most complex business rules can be authored without any knowledge of programming languages.

The concept of Web Rule is quite simple: create a business rule online using the Rule Editor, save it anywhere as an XML document, and evaluate any number of instances of your source object against that rule in any .NET code using one of the Evaluator classes.

Web Rule also has a feature which will surely change your view of reporting and data filtering. This feature, known as Rule-Based Data Filtering, comes with all versions of Web Rule.

Web Rule is not an environment. It simply provides a way to create and evaluate rules. Contrary to most traditional business rule management systems that run as independently installed processes, Web Rule is a server component that is designed to be an internal part of your new or existing ASP.NET or MVC web application, or at least the rule authoring part of it. As such, it does not include rule debugging, versioning, rule access authorization mechanisms or any other functionality to help manage your rules. Your web application is your environment. If needed, all of that functionality can be implemented by using standard APIs and tools that are built into the .NET framework and Web Rule.

While the above is true for rule authoring, rule evaluation is a bit different. Once rules are created and are ready to be used, Web Rule provides an extremely easy way to evaluate your rules against source objects by any .NET process, service or program, not just web applications. You can have any number of Windows, WCF or any other types of services, running in different parts of the world, all receiving data from different sources. Those services can retrieve XML rules from your common storage and evaluate them against incoming objects, inspecting the result of each execution and acting accordingly, or let actions inside of each execution type rule determine the further processing of the object.

More details on this matter are provided in this topic.

Another unique feature of the Web Rule control is its use of parentheses to prioritize evaluation of each condition in the rule. This dramatically simplifies the rule creation and modification process.

Below is the list of elements behind Web Rule technology that you need to understand in order to successfully author and evaluate business rules:

  • Business Rule. Web Rule supports two types of rules:

    • Evaluation type:

      Check if ( A is equal to [10] or B has any value ) and C is greater than A
    • Execution type:

      If ( A is equal to {[2] + B} or C is less than A ) and B has no value then Do else Do Not

    Supporting multiple rule types gives applications and rule authors much greater flexibility in fine-tuning business processes. Make sure to read their respective topics here and here.

    Each rule consists of rule elements which we will refer to throughout this website:

    • Flow: Elements if, else if and else are flow elements. The if element is required in any rule, and the others are optional. Flow elements divide each rule into sections. Obviously, evaluation type rules can have only one if flow element. Therefore, rules of this type always have only one section. Execution type rules can be divided into multiple sections; each section must have its own action. The action will be invoked only if the entire section evaluates to True. There can be only one if, one else and any number of else if flow elements per each execution type rule. It's clear that these flow elements represent the flow of a programming language. To complicate things a bit more, each rule section can be divided into levels by using parentheses. See the definition of Clauses below to find out why all these definitions are important. The default English display names of all flow elements can be changed by using custom Help XML files.
    • Fields: Elements A, B and C in the examples above are rule fields. They represent properties of the source object, in-rule methods or reusable rules. By default, each field or method displays its name as declared in the class. This can be changed by decorating fields and in-rule methods with the FieldAttribute or MethodAttribute respectively and setting their DisplayName properties to any label in any language.
    • Operators: Elements is equal to, has any value and alike are rule operators. They represent equation operators =, <, > and others. By default, operators are displayed as English phrases such as is greater or equal to instead of which makes them easier for non-technical users to work with. The default display names of all operators can be changed by using custom Help XML files.
    • Values: Elements [10], {[2] + B} are field values. Rule authors can use calculations, input or other fields to set field values in rules. Values do not have their own attribute class. Their settings, such as minimum or maximum allowed value, case sensitivity, date format, and so on, are normally controlled by the FieldAttribute or MethodAttribute.
    • Conditions: Condition is a combination of field-operator-value. Each rule section must contain at least one condition, otherwise the rule is considered invalid (because such a rule doesn't make sense.)
    • Clauses: Evaluation type rules use only two clauses - and and or. These correspond to the && and || operators of most programming languages. A single level of a rule section can contain only and or or clauses but never both of them. To illustrate the last phrase, imagine the following rule:
      Check if
      	A is equal to B or B contains "abc" and C is not equal to A or
      		( C has no value and A starts with "xyz" or A doesn't end with "opq" )
      A level is a collection of one or more conditions that gets evaluated as a whole unit (see the definition of Flow above for details). Typically, each part of a section separated with parentheses is a single level. The entire section is a single level if that section doesn't have parentheses. In this rule, there is only one section (because it's an evaluation type rule) that contains two levels - the "main" level, and the "child" level separated from the main level with parentheses. As currently written, the rule above would not pass Web Rule's automatic validation because there are clauses of different types on each level. Try to "evaluate" this rule in your head and you'll see that it returns the worst thing in business rules - an unpredictable result. Unpredictable for the rule author, that is. The author either has to add some parentheses or change clauses to make this rule valid. Let's do all that so you can see the difference:
      // Changing clauses...
      
      Check if
      	A is equal to B or B contains "abc" or C is not equal to A or
      		( C has no value and A starts with "xyz" and A doesn't end with "opq" )
      
      // ... or adding proper level separation
      
      Check if
      	A is equal to B or ( B contains "abc" and C is not equal to A ) or
      		( C has no value and ( A starts with "xyz" or A doesn't end with "opq" ))
      The point of this example is to show two things: that it's illogical to use clauses of different types on the same level, and that Web Rule takes care of this by checking clauses and levels when a rule author tries to save or update a rule.

      The execution type rules also include a then clause. It "attaches" a particular rule action to a single flow section. The default display names of all clause elements can be changed by using custom Help XML files.
    • Actions: Rule actions are used only in execution type rules. They are public void methods of the source object or any other .NET public class. Action methods can be instance or static, have overloads and be parameterless, or take any number of parameters of value types or source object types. By default they are displayed as declared names of methods they represent. If a method has multiple overloads, set a unique value of the DisplayName property of ActionAttribute for each overload that you'd like to use as rule action. Decorate unwanted overloads with ExcludeFromEvaluation attribute. Parameterless actions display no signatures (no parentheses) and appear in the UI as regular fields - no need to bother rule authors with parameters if they are not needed. The Do and Do Not elements in the sample rule shown at the beginning of this topic are examples of parameterless actions. All aspects of rule actions can be controlled by ActionAttribute, ExternalActionAttribute and ParameterAttribute classes.
    • In-Rule Methods: In-rule methods play the same role as rule fields except they are actually methods of source objects or any other .NET public class. In-rule methods are invoked by Web Rule during rule evaluation. Rules of both evaluation and execution type can use in-rule methods. The .NET methods they represent must return a value type (except for System.Guid and nullable enum). They can be instance or static methods, have overloads and be parameterless, or have any number of parameters of value types (except for System.Guid and nullable enum) or parameters of the source object's type. As with rule actions, if a method has multiple overloads, set a unique value of the DisplayName property of MethodAttribute for each overload that you'd like to use as in-rule method. Decorate unwanted overloads with ExcludeFromEvaluation attribute. Parameterless in-rule methods display no signatures (no parentheses), so they appear as regular rule fields to the rule author. All aspects of in-rule methods can be controlled by MethodAttribute, ExternalMethodAttribute, ParameterAttribute, and ReturnAttribute classes.

    Most of the traditional rule engines treat each condition as a single rule, combining those rules into rulesets. One of the goals of a ruleset is to handle the evaluation priority of each rule. So, a typical ruleset would look like this:

    ruleset:
    	// rule # 1
    	priority: 10
    	when: color = "red"
    	then: action 2
    
    	// rule # 2
    	priority: 1
    	when: color = "green"
    	then: action 1
    
    	// rule # 3
    	priority: 100
    	when: color is undefined
    	then: action 3
    end
    

    Because Web Rule handles the evaluation priority of each condition automatically by using parentheses and/or flow elements, there is no need to combine conditions in rulesets (you can store multiple rules in a single XML file called ruleset, but that's a subject of a different topic.) In Web Rule, everything inside the rule area is a rule. This simplifies rule authoring and makes it much easier to use for non-programmers. The above rule would look very different in the Rule Editor:

    if color is equal to "green" then action 1
    else if color is equal to "red" then action 2
    else action 3
    
  • Source Object. Source objects are .NET classes your rules are evaluated against. In the BRE community these objects are also known as fact sources, fact objects, or just facts. Any .NET public class can serve as Web Rule source object, provided that it meets the following simple rules:

    • For evaluation type rules, the source object itself, its base class or any of its public members has to declare at least one public property of value type. Web Rule "scans" the source object for those properties and uses them as rule fields.

    • In addition to that, the execution type rules require a source object or its base class to declare at least one public void method or reference at least one external action that could be used as rule action.

    Although perfectly acceptable, you would rarely use a plain .NET class as a source object for your rules. Almost all its members can be greatly customized by using attributes included in the CodeEffects.Rule.Attributes namespace. Please read the topics on source objects and attributes for details.

  • Asp.RuleEditor and Mvc.RuleEditor classes. These classes encapsulate most of the functionality for rule authoring (but not rule evaluation) in ASP.NET and MVC respectively.

    The CodeEffects.Rule.Asp.RuleEditor is used in ASP.NET pages and controls. It inherits from the standard System.Web.UI.WebControls.Panel, giving developers an easy way to add the Rule Editor to any control collection on their pages. Download the ASP.NET demo project to see the full implementation of this class. The minimal markup that registers CodeEffects.Rule assembly and adds Rule Editor to an ASP.NET page is very simple:

    <%@ Register assembly="CodeEffects.Rule"
    	namespace="CodeEffects.Rule.Asp" tagprefix="rule" %>
    
    <rule:RuleEditor ID="RuleEditor1" runat="server"
    	SourceAssembly="AssemblyName"
    	SourceType="SourceObjectTypeFullName" />
    

    Asp.RuleEditor class uses some members of its base type and implements many of its own properties and methods. Read the class topic to get details on each member. Only three properties are required when you add control to the page:

    • Server ID. Like any ASP.NET server control, Rule Editor must have its own ID.

    • SourceAssembly. This is the full name of the assembly that declares the type of source object. The easiest way to get this name is to right-click the source object's assembly in the References folder of your project and select Properties. The value you are looking for is listed as (Name) on the Properties panel. Alternatively, you can get this value as Assembly.GetAssembly( SourceObjectType ).FullName.

    • SourceType. This is the full name of the source object's .NET type. Typically, it's namespace + "." + type name. You can also get it as sourceObjectInstance.GetType().FullName.

    The CodeEffects.Rule.Mvc.RuleEditor is used in ASP.NET MVC applications. Normally, it's accompanied by an instance of the Models.RuleModel class as a property of the view's model or object in ViewBag. Download the ASP.NET MVC demo project to see both classes in action. The MVC code required for the Rule Editor is more complicated than its ASP.NET sibling. This is because MVC pattern is not really a "component friendly" environment:

    <div>
    	@{
    		Html.CodeEffects().RuleEditor()
    			.Id("ruleEditor")
    			.SaveAction("Save""Post")
    			.DeleteAction("Delete""Post")
    			.LoadAction("Load""Post")
    			.Rule(ViewBag.Rule)
    			.Render();
    	}
    </div>
    
    @{
    	Html.CodeEffects().Scripts().Render();
    }

    At the very minimum, the MVC.RuleEditor has to instantiate at least these properties:

    • ID. MVC uses this ID to serialize RuleModel in certain actions.
    • Actions. Unless the Rule Editor is used in Ajax application or its Toolbar is disabled, MVC.RuleEditor must specify actions to load, save and delete the rules and controller that declares those actions.
    • Rule model. Controller has to create an instance of RuleModel class and pass it to the view.
  • Evaluation classes are declared in the CodeEffects.Rule.Core namespace. Those classes provide the rule evaluation functionality. The extremely simple implementation of rule evaluation hides its truly remarkable capabilities. Make sure to read the details in the rule evaluation-related topic.

    string rule = ruleEditor.GetRuleXml();
    Evaluator<SourceObjectType> evaluator = new Evaluator<SourceObjectType>(rule);
    bool success = evaluator.Evaluate(sourceObjectInstance);