Creating a Custom ExpressionBuilder


Creating a Custom ExpressionBuilder

An ExpressionBuilder class generates one expression from another expression. Typically, you use an ExpressionBuilder to look up a particular value given a particular key.

The ASP.NET Framework includes the following ExpressionBuilder classes:

  • AppSettingsExpressionBuilderRetrieves values from the appSettings section of the web configuration file.

  • ConnectionStringsExpressionBuilderRetrieves values from the connectionStrings section of the web configuration file.

  • ResourceExpressionBuilderRetrieves values from resource files.

The ConnectionStringsExpressionBuilder has been used throughout this book whenever a connection string has needed to be retrieved.

You use the following syntax when working with an ExpressionBuilder:

<%$ ConnectionStrings:MyDatabase %> 


The <%$ and %> tags are used to mark an expression that should be parsed by an ExpressionBuilder. The prefix ConnectionStrings is mapped to the particular ExpressionBuilder class that is responsible for parsing the expression.

ExpressionBuilders must always be used with control properties. For example, you cannot display a connection string in a page like this:

<%$ ConnectionStrings:MyDatabase %> 


Instead, you must display the connection string like this:

<asp:Literal       Text='<%$ ConnectionStrings:MyDatabase %>'   Runat="server" />


You can create a custom ExpressionBuilder when none of the existing ExpressionBuilder classes do what you need. For example, you might want to store your application settings in a custom section of the web configuration file. In that case, you might want to create a custom ExpressionBuilder that grabs values from the custom configuration section.

Creating a Lookup ExpressionBuilder

In this section, you learn how to extend the ASP.NET Framework by building a custom ExpressionBuilder class. We'll create a Lookup ExpressionBuilder that looks up string values from an XML file.

The LookupExpressionBuilder class is contained in Listing 25.10.

Listing 25.10. App_Code\LookupExpressionBuilder.vb

[View full width]

Imports System Imports System.CodeDom Imports System.Web.UI Imports System.ComponentModel Imports System.Web.Compilation Imports System.Xml Imports System.Web.Hosting Imports System.Web.Caching Namespace AspNetUnleashed     Public Class LookupExpressionBuilder         Inherits ExpressionBuilder         Public Overrides Function GetCodeExpression(ByVal entry As BoundPropertyEntry,  ByVal parsedData As Object, ByVal context As ExpressionBuilderContext) As CodeExpression             Dim refMe As New CodeTypeReferenceExpression(MyBase.GetType())             Dim expression As New CodePrimitiveExpression(enTry.Expression)             Return New CodeMethodInvokeExpression(refMe, "GetEvalData", New CodeExpression () {expression})         End Function         Public Overrides Function EvaluateExpression(ByVal target As Object, ByVal enTry  As BoundPropertyEnTry, ByVal parsedData As Object, ByVal context As  ExpressionBuilderContext) As Object             Return GetEvalData(enTry.Expression)         End Function         Public Overrides ReadOnly Property SupportsEvaluate() As Boolean             Get                 Return True             End Get         End Property         Public Shared Function GetEvalData(ByVal expression As String) As String             Dim lookupDoc As XmlDocument = CType(HostingEnvironment.Cache("Lookup"),  XmlDocument)             If IsNothing(lookupDoc) Then                 lookupDoc = New XmlDocument()                 Dim lookupFileName As String = HostingEnvironment.MapPath("~/Lookup.config")                 lookupDoc.Load(lookupFileName)                 Dim fileDepend As New CacheDependency(lookupFileName)                 HostingEnvironment.Cache.Insert("Lookup", lookupDoc, fileDepend)             End If             Dim search As String = String.Format("//add[@key='{0}']", expression)             Dim match As XmlNode = lookupDoc.SelectSingleNode(search)             If Not IsNothing(match) Then                 Return match.Attributes("value").Value             End If             Return "[no match]"         End Function     End Class End Namespace 

Before you can use the LookupExpressionBuilder class, you need to register it in the web configuration file. The web configuration file in Listing 25.11 includes an <expressionBuilders> section that registers the LookupExpressionBuilder class for the prefix lookup.

Listing 25.11. Web.Config

<?xml version="1.0"?> <configuration>   <system.web>     <compilation>       <expressionBuilders>         <add expressionPrefix="lookup"             type="AspNetUnleashed.LookupExpressionBuilder" />       </expressionBuilders>     </compilation>   </system.web> </configuration> 

The LookupExpressionBuilder uses an XML file named Lookup.config to contain a database of lookup values. This file contains key and value pairs. A sample Lookup.config file is contained in Listing 25.12.

Listing 25.12. Lookup.config

<?xml version="1.0"?> <lookup>   <add key="WelcomeMessage" value="Welcome to our Web site!" />   <add key="Copyright" value="All content copyrighted by the company." /> </lookup>

Finally, the page in Listing 25.13 uses the LookupExpressionBuilder. It contains a Literal control that displays the value of a lookup expression named WelcomeMessage (see Figure 25.3).

Listing 25.13. ShowLookupExpressionBuilder.aspx

<%@ Page Language="VB" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" > <head  runat="server">     <title>Show LookupExpressionBuilder</title> </head> <body>     <form  runat="server">     <div>          <asp:Literal           Text="<%$ lookup:WelcomeMessage %>"          runat="Server" />          </div>     </form> </body> </html> 

Figure 25.3. Displaying text generated by an ExpressionBuilder.


You create a custom ExpressionBuilder by inheriting a new class from the base ExpressionBuilder class. The ExpressionBuilder class has the following methods:

  • GetCodeExpressionReturns the code that is used to evaluate an expression.

  • EvaluateExpressionEvaluates the expression in the case of no-compile ASP.NET pages.

  • ParseExpressionReturns a parsed version of the expression.

The ExpressionBuilder class also supports the following property:

  • SupportsEvaluateWhen true, the ExpressionBuilder can be used in no-compile ASP.NET pages.

When you use an ExpressionBuilder in a normal ASP.NET page, the ExpressionBuilder returns code that is integrated into the compiled ASP.NET page. The GetCodeExpression() method returns a block of code that is injected into the compiled ASP.NET page class that gets created in the Temporary ASP.NET Files folder.

Because an ExpressionBuilder might be used with either a Visual Basic .NET or C# ASP.NET page, the code returned by the GetCodeExpression() method must be language neutral. This means that you must represent the code that gets executed with the CodeDom.

In Listing 25.11, the GetCodeExpression() method returns an instance of the CodeMethodInvokeExpression class. This class represents an expression that invokes a class method. In this case, the CodeMethodInvokeExpression class is used to represent the expression LookupExpressionBuilder.GetEvalData(). In other words, the ExpressionBuilder adds code to the compiled ASP.NET page class that invokes the GetEvalData() method contained in Listing 25.10.

As an alternative to creating a normal ASP.NET page, you can create something called a no-compile ASP.NET page. A no-compile ASP.NET page is not compiled dynamically. You create a no-compile ASP.NET page by adding the following attribute to a <%@ Page %> directive:

<%@ Page CompilationMode="Never" %> 


Note

No-compile ASP.NET pages are discussed in Chapter 1, "Overview of the ASP.NET Framework."


If you want an ExpressionBuilder to work with no-compile ASP.NET pages, then you must return the value true from the ExpressionBuilder.SupportsEvaluate property and implement the EvaluateExpression() method. The EvaluateExpression is executed at runtime when the no-compile ASP.NET page is requested. In Listing 25.11, the EvaluateExpression() method simply calls the GetEvalData() method.




ASP. NET 2.0 Unleashed
ASP.NET 2.0 Unleashed
ISBN: 0672328232
EAN: 2147483647
Year: 2006
Pages: 276

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net