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)) |
The Visual Guard expression language is based on the C# syntax and is case sensitive.
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
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
.
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.
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.
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
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)
2 > 1?'abc':'def' // returns 'abc' 'a' != 'b'?'abc':'def' // returns 'def'
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
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
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 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.
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
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.
The two following examples are equivalent and returns the number of employees of the company for which the expression is evaluated:
GetEmployees().Lengthor
#this.GetEmployees().Length
#this.Name.StartsWith('A')
#this._employees
_employees.Clear()
#this[1].Nameor
[1].Name
#this[1].Status == Sample.MaritalStatus.Divorced
GetEmployees().Length > 1000
_employees[0].Name
C( _employees[0],T(Sample.Employee)).Name
Sample.Employee.GetEmployees().Length
T(Sample.Employee, sampleassembly).GetEmployees().Length