Home
    Shop
    Advertise
    Write For Us
    Affiliate
    Newsletter
    Contact

Expression Builders in ASP.NET 2.0

ASP.NET introduced new declarative expression syntax which allows you to substitute values into page at run time called Expression builders. You can make extensive use of expressions for referencing string resources for localization, connection strings and application settings from configuration file.

 

Expressions are evaluated at run time when the declarative elements of the page are parsed, and the value represented by the expression is substituted for expression syntax.

A common use of expressions is in data source controls to reference a connection string. Rather than including the connection string directly in the data source control as a property value, you can use an expression that specifies where the connection string is in the configuration file. At run time, the expression is resolved by reading the connection string from the configuration file. You can use expressions for any property setting that you want to resolve at run time rather than set as a static value.

Expression builders allow property values to be set and retrieved in a control during page parsing. When the page parser encounters an expression in the format.

<%$ prefix:value %>, it creates an expression builder based on prefix and passes the value to the expression builder for evaluation. The expression builder then returns the requested value to the page.

Benefits of expression builders

  • You can avoid writing lengthy code to set property values at run time. Expression builders allows to include dynamic information using one declarative statement.

  • A single Expression builder can be referenced across multiple pages. All changes to expression can be made at a central location. Ex: Expression builder for connection strings.

  • Expression builders are extensible. You can define custom Expressions that call your custom expression handler to return a value that will be substituted at run time.

  • Expression builder syntax is language neutral. You can same syntax across universal .Net languages

  • Expression builder offers both design time support as well as parse-time support. Design time support means you can built expression using Expression Dialog when accessed using properties window of control.

Expression builder can also be constructed to support no-compile feature of ASP.NET 2.0. That means, run time instantiates the expression builder and evaluates expression even before you compile the application. You can place expression builder into App_Code folder. There is sample Expression Builder Visual Studio .NET project, used in this tutorial.

Syntax for Expression builders

The syntax for Expression builders is as follows:

<%$ expression prefix: expression value %>

The dollar sign ($) indicates to ASP.NET that an expression follows. The expression prefix defines the type of expression, such as AppSettings, ConnectionStrings, or String resources. Following the colon (:) is the actual expression value that ASP.NET will substitute at run time.

 <asp:Button ID="Button1" runat="server" Text='<%$Appsettings:ButtonName %>'/>
               
<appSettings>
             <add key="ButtonName" value="ExpressionBuilder"/>
</appSettings>


ExpressionBuilder Output Listing

Above listing shows how we can use Expression builders to set the control property.

Types of Expression builders

ASP.NET 2.0 is shipped with three different built in Expression builders.

AppSettingsExpressionBuilder: This Expression retrieves user defined key-value pairs defined in AppSettings section of configuration file.

ConnectionStringsExpressionBuilder: This Expression retrieves connection strings defined in ConnectionStrings section of configuration file.

ResourceExpressionBuilder: This deals with referencing string resources when localizing applications. Appropriate values are substituted at run time based on locale.

AppSettingsExpressionBuilder: You can reference an Expression value from Appsettings section of configuration file as shown in above example.

ConnectionStringsExpressionBuilder: As name says, you can define expressions for ConnectionStrings and use them to set connection string properties for controls like Data source controls. Below listing shows defining declarative expression for ConnectionString property of SqlDataSource control.

<asp:SqlDataSource ID="SqlDataSource1" ConnectionString='<%$ConnectionStrings:ExpNorthwindConnection %>' runat="server"></asp:SqlDataSource>

The expression references a connection string named "ExpNorthwindConnection" that is defined in the connectionStrings element of the Web.config file as shown below. Each connection string is given a name, which you can use in an expression to reference it within your ASP.NET pages.

<connectionStrings>
           <add name="ExpNorthwindConnection"
          connectionString="Data Source=localhost;Integrated Security=SSPI;Initial Catalog=Northwind;User ID=sa;Password=sa"
          providerName="System.Data.SqlClient" />
      </connectionStrings >

CustomExpressionBuilder

The ExpressionBuilder class is the base class for ExpressionBuilders. When we define our own CustomExpressionBuilder class, we need to implement ExpressionBuilder class and override the GetCodeExpression method.

Implementation of CustomExpressionBuilder involves several steps:

Define CustomExpressionBuilder

As mentioned above, to develop a custom ExpressionBuilder we should extend the ExpressionBuilder abstract class and override the GetCodeExpression Method.

public class CustomXmlExpressionBuilder : ExpressionBuilder

The GetCodeExpression returns the expression to be evaluated when the Page parser finds a declarative expression and calls the required ExpressionBuilder. This method returns an expression of type CodeExpression and part of the CODEDom. The reason behind using the CodeDom is that, during the Page parsing, when a declarative expression is found, the corresponding ExpressionBuilder executes the GetCodeExpression and the return value is just a CodeExpression that will be embedded into the compiled ASP.NET class and then all together compiled and executed. The resulting class is stored in the ASP.NET Temporary folder. Since the ExpressionBuilder is language neutral, the GetCodeExpression must be language neutral and the CodeDom must be integrated with any language set for the web application.

public override CodeExpression GetCodeExpression(BoundPropertyEntry entry, object parsedData, ExpressionBuilderContext context)
        {
            CodeTypeReferenceExpression thisType = new CodeTypeReferenceExpression(base.GetType());
 
            CodePrimitiveExpression expression = new CodePrimitiveExpression(entry.Expression.Trim().ToString());
 
            string evaluationMethod = " GetXmlKeyValue";
 
            return new CodeMethodInvokeExpression(thisType, evaluationMethod, new CodeExpression[] { expression });
        }

The first line of this method gets a reference to the CustomXmlExpressionBuilder class because we are going to invoke GetCodeExpression from this class that will evaluate the required expression.

Then, it creates a new expression based on the KEY specified in the declarative expression on the page which will be used as an input to the method that will evaluate the required expression.

A method name that will do the real evaluation is stored in a string variable. Finally, the method returns the expression that will invoke a method named GetXmlKeyValue, which is a static method responsible for evaluating the expression. The CodeMethodInvokeExpression class has been used for this purpose and takes as input the type on which to execute the method specified the method name, as well as an array of type CodeExpression that represents the parameters of the method called

In Nutshell, the GetCodeExpression returns a CodeDOM method invocation expression so that this method invocation will be added to the page compiled class and executed later on when the whole page executes.

We have mentioned the method GetXmlKeyValue which is responsible for loading the data based on the key specified in the declarative expression. The implementation of that method is as follows.

public static string GetXmlKeyValue(string expression)
        {
                        XmlDocument xmlSettingDoc = (XmlDocument)HostingEnvironment.Cache["XmlSettings"];
 
                        if (xmlSettingDoc == null)
            {
                            xmlSettingDoc = new XmlDocument();
 
                            string settingsFile = HostingEnvironment.MapPath("~/XmlFile.xml");
 
                                xmlSettingDoc.Load(settingsFile);
 
                CacheDependency settingsDepend = new CacheDependency(settingsFile);
 
                                HostingEnvironment.Cache.Insert("XmlPath", xmlSettingDoc, settingsDepend);
            }
 
            string getXPATHKey = String.Format("//add[@key='{0}']", expression);
 
                        XmlNode wantedRecord = xmlSettingDoc.SelectSingleNode(getXPATHKey);
 
                        if (wantedRecord != null)
                return wantedRecord.Attributes["value"].Value;
 
                        return "Unable to Process Expression";
        }

The GetXmlKeyValue method evaluates the declarative expression by accessing the XmlFile.xml file and retrieving the value corresponding to the key specified in the above mentioned expression.

The method simply loads the XmlFile.xml file into an XmlDocument. If this file has been loaded before, it is checking if it is still placed in the application cache. If not, it loads the file into the XmlDocument then adds it to the application cache to gain some performance points by caching the file content.

An XPath expression is built based on the add record whose key attribute value is the same as the one specified in the declarative expression. Finally, the value attribute value is returned as if we had a lookup based on the key attribute. If there was no such key, we could have simply thrown an exception, but in this case we simply returned a warning message that the expression could not be evaluated properly.

The GetCodeExpression returns a CodeDOM expression that invokes the method GetXmlKeyValue. When the page executes, it finds a call to the GetXmlKeyValue, it invokes this method and the returned value replaces the declarative expression on the page.

Adding key to web.config

The first thing to do is to place the CustomXmlExpressionBuilder class in the App_Code folder. Next, add the following section to the web configuration file under the compilation section.

<compilation debug="true" strict="false" explicit="true">
      <expressionBuilders>
        <add expressionPrefix="XmlFile"
        type="CustomExpressionBuilder.CustomXmlExpressionBuilder"/>
      </expressionBuilders>
    </compilation >

We have registered the new ExpressionBuilder in the web configuration file and now the web application is ready to use it. On a new WebForm you simply add the following server control.

<asp:label ID="CustomExpBuilder" runat="server" Text='<%$ XmlFile: LinkValue %>' />

The .NET runtime will take the XmlFile keyword, create a new instance of the CustomXmlExpressionBuilder and evaluate the expression; in this case it is the value of the key attribute of each record in the Web.config file. Below output will show you the result


Custom Expression Builder

I hope this introduction gave you a closer look to Expression Builders and Custom Expression Builders, the new feature added to ASP.NET 2.0.


Tutorial toolbar:  Tell A Friend  |  Add to favorites  |  Feedback  |