October 03, 2005 12:10 AM

Express Yourself

Discern the Various Forms of Dynamic Expressions Available in ASP.NET
DevConnections
Rating: (0)

CoreCoder

LANGUAGES: C#

ASP.NETVERSIONS: 2.0

 

Express Yourself

Discern the Various Forms of Dynamic Expressions Availablein ASP.NET

 

 

There are various flavors of dynamic expressions inASP.NET, each serving a particular scenario and providing a specific missingcapability. What are dynamic expressions? I?m referring to any expression youcan write in the .aspx file wrapped by <% ... %> tags. As you?ll see in amoment, there are two types of expressions in ASP.NET 1.x. A third type of dynamicexpression has been added in ASP.NET 2.0. All of them, though, find inspirationin the first form of dynamic expression that appeared with classic ASP quite afew years ago: code blocks. In this article, I?ll go through the three types ofexpressions available in ASP.NET 2.0 and discuss their implications, as well assome implementation details.

 

ASP-style Code Blocks

In classic ASP, code blocks are fragments of executablecode delimitated by <% ... %> tags. Within those tags, you can putvirtually everything that the ASP runtime engine can understand and parse,ranging from variable assignments to for statements, from function declarationsto function calls. This apparently excessive liberty of coding is made possibleby the structure of the ASP page. The runtime engine builds an ASP pageincrementally as it parses the text. The final output is obtained by composingany literal expression with the output of code blocks. A scripting environmentis up and running all the time to process the contents of <% ... %>blocks statefully with respect to the current request. This explains why, say,a function declared in one block can safely be invoked later in another block ?the function body has been published and remains visible in the scriptingcontext.

 

There are two types of code blocks in classic ASP: inlinecode and inline expressions. Inline expressions are merely shortcuts forResponse.Write and take the well-known form illustrated below:

 

<% x = 1 %>

<% = x %>

 

The former expression is an example of inline code; thelatter is an inline expression that outputs the contents of the x variable set one step earlier.

 

To the extent that it was made possible by a brand new run-timeenvironment, code blocks survived during the transition from classic ASP toASP.NET. They lost some features along the way, but still remain a supportedfeature of the ASP.NET platform even today with version 2.0 just around thecorner.

 

In ASP.NET, code blocks can no longer be used to declarefunctions, and variables are no longer considered globals. Inline statementsand expressions are accepted. Another difference that is worth noting is thatin ASP.NET, code blocks are processed at rendering time ? not when the pageloads up. This doesn?t probably make a huge difference for old code, but it?salways the sign of an underlying brand new run-time model.

 

The contents of all code blocks are incorporated in theform-rendering procedure and interspersed with calls to the RenderControlmethod of declared server controls and literals. For this reason, an inlineexpression can?t be used to assign a property value in ASP.NET. In ASP, thebuilding model of the page made it possible because all text was accumulatedinto a memory buffer and two successive writings could in the end compose anattribute assignment. The object model of ASP.NET simply prohibits thisapproach.

 

Data Binding Expressions in ASP.NET

To let developers assign dynamic values to controlattributes in a declarative manner, ASP.NET introduced in version 1.x a newtype of dynamic expression named data-bound expressions. At first sight,data-bound expressions look similar to old-style code blocks. They look sosimilar at the syntax level that one, with good reason, can wonder why twotypes of expressions are necessary. Consider the following fragment:

 

<asp:Label id="Label1" runat="server"

 Text='<%DropDownList1.SelectedItem.Text %>' />

 

The Text property of the Label control is set to the textof the currently selected item in a drop-down list control. More exactly, whatI described is only the desired behavior; unfortunately, it has nothing to dowith what happens in reality. Run the code and you?ll see that the Textproperty is assigned the literal expression, including the opening and closingcode block tags. You may think this is because of the quotes. Try removing thequotes and run it again. This time you get a compile error informing you that <%... %> expressions cannot be used that way in an ASP.NET page. This is wheredata-bound expressions fit in. In terms of syntax, a data-bound expression isnearly identical to a code block, except that it is prefixed by a # symbol. Towork, the preceding code label tag must be rewritten as shown here:

 

<asp:Label id="Label1" runat="server"

 Text='<%#DropDownList1.SelectedItem.Text %>' />

 

The simple insertion of a # symbol changes completely theperspective of the markup. The ASP.NET page parser now creates an event handlerfor the DataBinding event of that instance of the Label control, as thepseudocode shown here documents:

 

Label1.DataBinding += new EventHandler(TextPropertyBinder);

 

Needless to say, the body of the TextPropertyBinder methodincorporates the evaluation of the expression and assigns it to the Textproperty:

 

void TextPropertyBinder(object sender, EventArgs e)

{

  Label1.Text =DropDownList1.SelectedItem.Text;

}

 

The expression is copied verbatim; any error or wrongsyntax elements will be caught at compile time. It is important to note thatthese expressions are evaluated only after a call to DataBind is made. The DataBindmethod can be called on the page or the specific control. If no call is made,no data-bound expressions are ever evaluated. You can use any code snippet in adata-bound expression that returns a valid value for the property being bound.You can even call methods on the Page class or external components.

 

What?s wrong with data-bound expressions? Nothing, ifyou?re working with ASP.NET 1.x. But in ASP.NET 2.0, a new breed of controlsmake their debut: data source controls. Data source controls manifest yetanother requirement where expressions are concerned. Heralding declarativeprogramming, data source controls should be bindable to the results ofexpressions regardless of the binding mechanism. Data source controls operateon a data source almost automatically, and fully support a scenario in whichall their settings are set at design time ? including how to cooperate withother page controls to get required data. Data source controls are notdata-bound controls, even though they closely work with, and support,data-bound controls (especially the new generation of data-bound controls suchas GridView and DetailsView). Not being data-bound controls, how can yourequire that DataBind is called on source controls?

 

Note that DataBind is a method declared by the Controlclass ? the root of all ASP.NET server controls ? and inherited by all controls,including data source controls. In theory, you could use data-bound expressionsto configure data source controls. As long as you invoke DataBind on the datasource controls, it should work. Really? Well, not always. Let?s see why. Trythe following code:

 

<asp:SqlDataSource id="MySource"runat="server"

 :

 ConnectionString=<%

  #ConfigurationManager.ConnectionStrings["LocalNWind"]%>

<asp:GridView id="grid" runat="server"

 datasourceid="MySource"/>

 

You have a GridView control (the successor to the DataGrid)bound to a SqlDataSource control. If you?ve only absorbed 10% of the variousdemonstrations, slides, sample code, and preview books on the topic of datasource controls, you should know by now what the code above does. For all theothers, I?ll say that SqlDataSource takes a connection string and a bunch ofcommand strings (SELECT, plus optionally DELETE, INSERT, and UPDATE) andprovides fresh data to the bound control ? in this case, the grid.

 

How do you set the connection string? You can do thatprogrammatically in the Page_Load event. If this is fine for you, then there?snothing more that I can add. For all the others, I?ll say that you can alsothink of setting the connection string declaratively by instructing the controlto retrieve the string programmatically. The code snippet above might work(even with the extra burden of calling DataBind to trigger the process).

 

Now try swapping the position of the two controls in themarkup in such a way that the GridView control is processed before the SqlDataSourcecontrol. When DataBind is called, all controls are bound to their data in theorder they appear in the page. Called to bind its data, the GridView control realizesit depends on the SqlDataSource control. The DataSourceId property provides thelink. So the GridView control asks the SqlDataSource control to supply data.Given the architecture of new data-bound controls bound to data sourcecontrols, the GridView control tries to get its data by connecting to aninternal object inside the SqlDataSource and running the select command. Guesswhat happens? The connection string property is not set at this time becausethe data binding process for the SqlDataSource hasn?t started yet.

 

Therefore, to fully support data source controls, a newtype of expression is required. ASP.NET 2.0 calls them $-expressions.

 

ASP.NET Dynamic Expressions

Use the following code to declaratively set the connectionstring on a data source control:

 

<asp:SqlDataSource id="MySource"runat="server"

 :

 ConnectionString=<%$ConnectionStrings:LocalNWind %>

<asp:GridView id="grid" runat="server"

 datasourceid="MySource"/>

 

The $ symbol replaced the # symbol, thus giving life to abrand new type of expression that requires a brand new type of support from theASP.NET runtime. But wait, there?s more. As you can see, comparing theexpression above with the previous one, the contents of the <% ... %>block is different. The call to a static method on the ConfigurationManagerclass that you saw earlier is plain executable code. The expression you seehere, instead, takes a different form and is not directly executable:

 

<%$ [expressionPrefix]:[expressionValue] %>

 

Each $-expression must have a public prefix known by theASP.NET runtime, as well as a value. Each prefix is statically associated withan expression builder class. The link takes place in the web.config file. Thevalue of the expression becomes input for some methods of the expressionbuilder class. The builder class ultimately determines the syntax of the valueexpression. Before reviewing the default expression builders that ship withASP.NET 2.0, let me clarify that $-expressions are a parse-time feature. Thepage parser is the only system tool that takes care of the expressions.Whenever the page parser meets a $-expression, it extracts the prefix and,through it, gets to the underlying expression builder class.

 

The expression builder class derives from a known baseclass with a predefined interface; the page parser calls some methods and getsthe code to insert in the dynamically generated source for the requested ASPXpage. In the end, the expression above turns to the following:

 

MySource.ConnectionString = Convert.ToString(

 ConnectionStringsExpressionBuilder.GetConnectionString(

 "LocalNWind" ),CultureInfo.CurrentCulture);

 

$-expressions are simply parse-time property setters.Data-bound expressions are event-based and strictly tied to the classic databinding process as defined in ASP.NET 1.x. They?re similar, but not related.

 

Predefined $-expressions

As shown in Figure 1, there are three predefined$-expressions in ASP.NET 2.0: AppSettings, ConnectionStrings, and Resources.The AppSettings expression takes the name of an entry under the <appSettings>section of the configuration file. ConnectionStrings is similar, except that itreads the <connectionStrings> section. The value of the ConnectionStringsexpression can be in the form value.type. Here?s an example:

 

<% $connectionstrings:northwind.connectionstring %>

<% $connectionstrings:northwind.providername %>

 

Prefix

Expression

Description

AppSettings

Entry

Retrieves the specified entry in the <appSettings> section of the configuration file.

ConnectionStrings

Entry[.Type]

Retrieves the specified entry in the <connectionStrings> section of the configuration file.

Resources

Class, ResourceName

Retrieves the specified resource in the given global RESX file.

Figure 1: $-expressionsin ASP.NET 2.0.

 

Past the dot (.) symbol you can have any of the following:connectionstring or providername. Basically, the string indicates the attributeto retrieve in the specified entry. The .connectionstring is the default andcan be omitted. Here?s how to use the ConnectionString expression to takeadvantage of this feature:

 

<asp:sqldatasource runat="server"id="SqlDataSource1"

 ConnectionString='<% $ConnectionStrings:NWind %>'

 ProviderName='<% $ConnectionStrings:NWind.providername %>'

 :

/>

 

The Resources expression is used to access a globalresource declaratively. You need to specify two parameters, RESX file andresource name. Here?s an example:

 

<asp:label runat="server" id="Label1"

 Text='<% $Resources:Globals,HeaderString %>'

 

You cannot use the Resources expression to access resourceslocal to a page. Global resources are resources defined in an RESX file locatedin the application?s App_GlobalResources folder. $-expressions can also bedefined through the Visual Studio.NET 2005 designer. You select the control ofchoice and click on the Expressions entry in the property grid. Once there, youselect the property you want to set and the expression you need, as shown inFigure 2.

 


Figure 2: Setting expressions inVisual Studio.NET 2005.

 

Conclusion

Even though ASP.NET 2.0 counts three different types ofexpressions, it?s difficult to say that any is redundant. Dynamic$-expressions, added in ASP.NET 2.0, serve in particular to make more flexiblethe declarative model of data source controls working in a way that#-expressions cannot always do. Three predefined $-expressions make theprogramming offer richer and provide a declarative way to bind resources andconfiguration settings directly to control properties.

 

Dino Esposito is atrainer and consultant who specializes in ASP.NET and ADO.NET. Author of Programming Microsoft ASP.NET and Introducing ASP.NET 2.0, both from MicrosoftPress, Dino also helped several companies architect and build effectiveproducts for ASP.NET developers. Dino is the cofounder of http://www.DotNet2TheMax.com, apopular portal for .NET programmers. Write to him at mailto:dinoesp@hotmail.com or join theblog at http://weblogs.asp.net/despos.

 

 

 

Add a Comment

There are no comments to display. Be the first one!
You must log on before posting a comment.

Are you a new visitor? Register Here

advertisement




Comments from the DevConnections Community

Join our community of development pros.

Windows problem

I all, I have a problem on my Windows Vista that began afetr the purchase of an external Hard Disk Freecom. A few days afetr the purchase I discon...

Most Recent Posts

GOOGLE LINKS
SPONSORED LINKS
FEATURED LINKS