Visual Guard Expression Language

Visual Guard Expression Language

Visual Guard provide an expression language used in condition of security actions or to calculate dynamically the value of a property modified by a security action. The language supports setting and getting of property values, property assignment, method invocation, logical and arithmetic operators, named variables.

Note: Visual Guard expression language is available only when the version 2.7 (or higher) of Visual Guard assemblies are referenced in your application.

This document covers the features of the expression language. 

operators Description Example
== equality 0 == 0
!= inequality 1 != 0
> greater than 1 > 0
>= greater than or equal 1 >= 1
< less than 0 < 1
<= less than or equal 1 <= 1
is checks if an object is compatible with a given type '1' is string
like compares a string against a pattern 'Abc' like '[A-Z]b*'
between checks if a numeric or string value is between two values 1 between {0,2}
'efg' between {'abc', 'xyz'}
matches checks if a string value matches a regular expression '5.00' matches '^-?\d+(\.\d{2})?$'
= Assignment (not available in condition) myValue = 1
and logical or conditional AND operator (compatible with integer, enum or boolean types) 1 == 1 and 'a' == 'a'
MyEnum.Value1 and MyEnum.Value2
1 and 2
or logical or conditional OR operator (compatible with integer, enum or boolean types) 1 == 1 or 'a' == 'b'
MyEnum.Value1 or MyEnum.Value2
1 or 2
! logical negation operator  (compatible with integer, enum or boolean types) !true
!1
!MyEnum.Value1
? : ternary operator. returns the value of the first expression if the condition is true, otherwise return the value of the second expression. 1 == 1?'abc':'def'
?? ?? operator returns the left-hand operand if it is not null, or else it returns the right operand. MyStringValue??'def'
+ computes the sum of 2 operands (compatible with number, string or datetime types) 1 + 1
'abc' + 'efg'
date('1974-08-24') + 5
- subtracts the second operand from the first (compatible with number, datetime types) 1-1
date('1974-08-24') - 5
date('2004-08-14') - date('1974-08-24')
* computes the product of its operands. 1 * 2
/ divides its first operand by its second 10 / 5 
% computes the remainder after dividing its first operand by its second 5 % 2
^ raises first number to the power of the second one. 2 ^ 5
new used to create objects and invoke constructors new System.Collections.ArrayList()
new int[] {1,2,3}
null represents a null (Nothing in VB.Net) reference
T() Used to obtain the System.Type object for a type T(System.String)
T(System.String, mscorlib)
T(MyNamspace.MyClass[], myassembly)
C() Converts an expression to a specifed type (equivalent to DirectCast in VB.Net or cast operator in C#) C(Controls[0], T(System.Windows.Forms.Button))
C( _employees[0],T(Sample.Employee))

Language Reference

The Visual Guard expression language is based on the C# syntax and is case sensitive.

Literal expressions

The types of literal expressions supported are strings, dates, numeric values (int, real, and hex), boolean and null. String are delimited by single quotes ('). To put a single quote itself in a string you need to double this single quote. The following listing shows simple usage of literals. Typically they would not be used in isolation like this, but as part of a more complex expression, for example using a literal on one side of a logical comparison operator.

myString == 'Hello World' // returns true if myString is equal to "Hello World"
myString == 'Tony''s Pizza' // returns true if myString is equal to "Tony's Pizza"
avogadrosNumber == 6.0221415E+23 // returns true if avogadrosNumber is equal to 6.0221415E+23
maxValue == 0x7FFFFFFF  // returns true if maxValue is equal to 2147483647
myDate == date('1974/08/24') // returns true if myDate is equal to August 24, 1974
myDate == date('19740824T031030', 'yyyyMMddTHHmmss') // returns true if myDate is equal to August 24, 1974 at 03:10:30 AM
myBoolean == true // return tue if myBoolean value is equal to true
nullValue == null // returns true if nullValue is equal to null

Numbers support the use of the negative sign, exponential notation, and decimal points. By default real numbers are parsed using Double.Parse unless the format character "M" or "F" is supplied, in which case Decimal.Parse and Single.Parse would be used respectfully. As shown above, if two arguments are given to the date literal then DateTime.ParseExact will be used. Note that all parse methods of classes that are used internally reference the CultureInfo.InvariantCulture.

Relational operators

The relational operators; equal, not equal, less than, less than or equal, greater than, and greater than or equal are supported using standard c# operator notation. These operators take into account if the object implements the IComparable interface.

2 == 2 // true
date('1974-08-24') != DateTime.Today  // true
2 < -5.0 // false
DateTime.Today <= date('1974-08-24') // false
'Test' >= 'test' // true

In addition to standard relational operators, Visual Guard Expression Language supports some additional, such as in, like and between, as well as is and matches operators, which allow you to test if object is of a specific type or if the value matches a regular expression.

3 in {1, 2, 3, 4, 5}  // true
'Abc' like '[A-Z]b*'  // true
'Abc' like '?'  // false
1 between {1, 5}  // true
'efg' between {'abc', 'xyz'}  // true
'xyz' is int  // false
{1, 2, 3, 4, 5} is IList  // true
'5.0067' matches '^-?\\d+(\\.\\d{2})?$'  // false
'5.00' matches '^-?\d+(\.\d{2})?$'  // true

Note that the Visual Basic and not SQL syntax is used for the like operator pattern string.

Boolean Logical operators

The boolean logical operators that are supported are and, or, and ! (not). Their use is demonstrated below

true and false // returns false
true or false  // returns true
true and !true // returns false

and and or operators are equivalent to && and || in C# syntax or to AndAlso and OrElse in VB.Net.

Enumeration Logical operators

The enumeration logical operators that are supported are and, or, and ! (not). The following examples are based on the sample enum 'Sample.Access'.

namespace Sample 
{
    [Flags]
    public enum Access
    { 
        NoAccess = 0,
        Read = 1,
        Write = 2,
        Create = 4,
        ReadWrite = Read | Write,
        AllAccess = ReadWrite | Create
    }
}

Expression samples:

Sample.AllAccess and Sample.Write // Returns Sample.Write
Sample.Read or Sample.Write // Returns Sample.ReadWrite
Sample.AllAccess and !Sample.Create // Returns Sample.ReadWrite

Integer Logical operators

The integer logical operators that are supported are and, or, and ! (not). Their use is demonstrated below

3 and 1 // returns 1
1 or 2 // returns 3
!1 // returns -2 (equivalent to '~1' in c# or 'Not 1' in VB.Net)

Ternary operators You can use the ternary operator for performing if-then-else conditional logic inside the expression.
2 > 1?'abc':'def' // returns 'abc'
'a' != 'b'?'abc':'def' // returns 'def'

Mathematical operators

The addition operator can be used on numbers, string, dates. Subtraction can be used on numbers and dates. Multiplication and division can be used only on numbers. Other mathematical operators supported are modulus (%) and exponential power (^). Standard operator precedence is enforced. These operators are demonstrated below

1 + 1 // 2
'test' + ' ' + 'string' //'test string'
date('1974-08-24') + 5 // 8/29/1974            
1 - 3; // -2
1000.00m - 1e4 // 9000.00
date('2004-08-14') - date('1974-08-24') // returns a TimeSpan equals to 10948.00:00:00
-2 * -3 // 6
2.0 * 3e0 * 4 // 24
6 / -3 // -2
8.0 / 4e0 / 2 // 1
7 % 4 // 3
8.0 % 5e0 % 2 // 1
-2 ^ 4 // 16
1+2-3*8^2/2/2 // -45 

Types

In many cases, you can reference types by simply specifying type name:

1 is int // returns true
DateTime.Today // returns a datetime object containing the current date
new string[] {'abc', 'efg'} // returns an array of strings
System.DateTime == date // returns true
date('2004-08-14').GetType() == T(System.DateTime, mscorlib) // returns true

By default, Visual Guard look for a type in mscorlib then look for the type in all loaded assemblies. If the assembly is not loaded when the expression is parsed, you need to use the special expression T(typeName, assemblyName). this special expression allows to resolve name conflict and the performance at runtime is better.

Constructors

Constructors can be invoked using the new operator. Examples of using constructors are shown below:

new DateTime(1974, 8, 24) // returns a DateTime object equals to the specified date
new System.Collections.ArrayList(new object[]{'a', 1, date('2004-08-14')}) // returns an ArrayList object containing a string, an int and a datetime.            
new T(System.Collections.ArrayList, mscorlib)(10) // returns an ArrayList object

Variables

Variables can be referenced in the expression using the syntax #variableName. These variables are defined by Visual Guard and passed as argument to the expression.

For example, Visual Guard defines a #Principal variable for expression associated to Visual Guard security actions. This variable will contains the principal corresponding to the current user.

The '#this' variables

There is a special variable that is always defined and can be referenced within the expression #this. The #this variable can be used to explicitly refer to the object for which the expression that is currently being evaluated:

#this is System.Collections.IList // returns true when the object for which the expression is evaluated implements the IList interface

For expression attached to Visual Guard security actions (i.e.: used as condition or to calculate the value of a property), #this is equal to the target of the action.

Properties, Arrays, Lists, Dictionaries, Indexers

Visual Guard expression language allows to navigate through properties or fields of objects or call methods. You just have to use a period to indicate a nested member. By default Visual Guard can access to public and private members of a class. If your application does not have ReflectionPermission for all members, Visual Guard will access only to public members.

The following examples are based on the sample classes 'Customer' and 'Company'.
namespace Sample
{
    public class Employee
    {
            private int _employeeId;
            private string _firstName;
            private string _lastName;
            private Company _company;
	        private MaritalStatus _maritalStatus;

	        public Customer(Datetime dateOfBirth, string firstName, string lastName)
	        {
	                ....
	        }
	        public int Id
	        {
	            get { return _employeeId; }
	        }
	        public string FirstName
	        {
	            get { return _firstName; }
	            set { _firstName = value; }
	        }
	        public string LastName
	        {
	            get { return _lastName; }
	            set { _lastName = value; }
	        }
	        public Company Company
	        {
	            get { return _company; }
	            set { _company = value; }
	        }
	        public MaritalStatus Status
	        {
	            get { return _maritalStatus; }
	            set { _maritalStatus = value; }
	        }
	        public static Employee[] GetEmployees()
	        {
	            ...
	        }
    }
    public enum MaritalStatus
    {
        Married,
        Divorsed,
	    Single
    }
    public class Company
    {
        private string _name;
        private ArrayList _employees;
        public Company(string name)
        {
            ....
        }
        public string Name
        {
            get { return _name; }
            set { _name = value; }
        }
	    public int AddEmployee(Employee employee)
        {
            ...
        }
        public int RemoveEmployee(Employee employee)
        {
            ...
        }
        public Employees[] GetEmployees()
        {
            ...
        }
	    public Employee this[int employeeId]
        {
            ...
        }
    }
}        
For all examples, the expression is evaluated with a Company object as context.

Properties and methods

The two following examples are equivalent and returns the number of employees of the company for which the expression is evaluated:

GetEmployees().Length 
or
#this.GetEmployees().Length

This example returns true if the name of the company start with 'A':
#this.Name.StartsWith('A')

This example used the private field _employees and returns an ArrayList object:
#this._employees

This example used the private field _employees and returns the number of items of list:
_employees.Clear()

Arrays, Lists, Dictionaries, Indexers

The contents of arrays, dictionaries and lists are obtained using square bracket notation. The following example returns the name of the employee with the id equal to '1':
#this[1].Name
or
[1].Name

The following example returns true if the employees '1' is divorced:
#this[1].Status == Sample.MaritalStatus.Divorced

The following example returns true if the company as more than 1000 employees:
GetEmployees().Length > 1000

The following example used the private member '_employees' and returns the name of the first employee:
_employees[0].Name

Note: since _employees is an ArrayList object, the values returns by _employees[0] is an object. At design time, Visual Guard console generates a warning indicating that the 'Name' property is not a member of 'System.Object'. In our case, we can ignore this warning because we are sure that _employees variable contains only Employee object. If you want to suppress this warning at design time, you use the C() keyword to cast this value to Employee type:
C( _employees[0],T(Sample.Employee)).Name


Static (Shared) members 

This example used the GetEmployees static (Shared in VB.Net) method of the Employee class and returns the number of employees.
Sample.Employee.GetEmployees().Length

You can also used the following syntax if the full name of the type is in conflict with a member or a class:
T(Sample.Employee, sampleassembly).GetEmployees().Length

See Also

Using an expression in a condition of a security action

Using an expression to modify the value of a property