Expressions vs. Statements, part 2: ASP.NET Code Block Types

A couple of days ago I wrote about the difference between expressions and statements. I wanted to briefly touch on that subject again, this time in the context of ASP.NET. By now you have probably heard about the new ASP.NET MVC framework. The first official release was during the 2009 MIX event after several previews and betas in 2008. This subject is more relevant for ASP.NET MVC views than for regular WebForms.

ASP.NET pages have always supported embedded code. I am not talking about <script runat="server"> blocks, in which all code is contained in methods that are compiled as part of the page class. Rather I am talking about code surrounded by the <% and %> delimiters. Interaction with the page from these blocks is limited, since the code is executed during the render phase of the page life cycle. So these code blocks are generally used for small code snippets.

<% Trace.Warn("Embedded Code Block", "Hello World"); %>

The syntax makes it hard to search but MSDN has some limited information on embedded code blocks as they are called. Besides the limited interaction with the page and its lifecycle, embedded code blocks also can’t be used in the attributes of server controls. The literal text of the code block will just be used as the value of the property when the control is instantiated. These limitations are not really a problem in ASP.NET MVC, since we hardly ever use server controls (although this may change in the future) and all of the hard work is already done by the controller, so there is no need to interact with the page life cycle. In fact, ASP.NET MVC views should be treated as simple templates that only know how to render the page and its data (no view state either :-)

Let’s have a look at the different types of syntax we can use for code blocks in ASP.NET pages. There are really four types of code blocks, and the first one is different from the others:

<%$ ... %>
<%# ... %>
<%  ... %>
<%= ... %>

There is quite a difference between these code constructs and the names can be confusing sometimes. Let’s examine!

ASP.NET Expression Syntax

First of all we have ASP.NET expressions which look like <%$ AppSettings:Key %>. These are not the kind of expressions we were concerned with in the previous post (Expressions vs. Statements in C#). This is in fact not even a code block like the others we will discuss shortly, because there is no valid C# or VB.NET code inside an ASP.NET expression. It’s just a magic syntax that is translated to code by an expression builder (distinguished by the prefix in the above syntax) when the page is parsed. The following code example illustrates what happens, the expression

<asp:Label runat="server" Text="<%$ AppSettings:Key %>" />

is translated to:

label.Text = Convert.ToString(
    AppSettingsExpressionBuilder.GetAppSetting("Key", typeof(Label), "Text"),
    CultureInfo.CurrentCulture);

The built-in expression builders can be used to bind to application settings, connection strings and resources. ASP.NET 4.0 will introduce a new expression builder to dynamically generate URLs based on routing configuration. You can also create your own expression builder, but that’s hardly ever needed. Interesting, but not the type of expressions I was talking about.

ASP.NET Data-Binding syntax

The next code construct is the data-binding syntax: <%# Eval("Value") %> which is used to bind to properties to data on demand. This means that these blocks are only evaluated when you call the DataBind() method. Behind the scenes, when the page is parsed code is generated to handle the DataBinding event of the control. What’s interesting, is that expressions (in the sense of a construct that evaluates to a value) are supported in data-binding syntax. So the following is allowed:

<%# DateTime.Now.Hour < 12 ? "Good morning" : "Hello" %>

Statement and Expression/Evaluated Code Blocks

In many cases, especially in ASP.NET MVC, the data-binding syntax is not needed. It is closely related to the page life cycle, view state and data controls, all of which are just not relevant in MVC views. You just want to display some values. For this you can simply call Response.Write in your code block:

<%
    string message = "Hello World!";
    Response.Write(message);
%>

The code in slightly modified form becomes part of a method (RenderMethodDelegate) that is responsible for rendering the page. Therefore, the code inside the code block should consist of statements (if you forget the semicolon on the end of your statement you will receive the CS1002 compiler error).

Because this scenario is so common, there is also a syntax that you can use to render directly without calling Response.Write. This syntax has no official name that I could find (ExpressionSnippet?), so I will call them evaluated code blocks. These are delimited by <%= and %> and the content of this code block becomes the parameter to the HtmlTextWrite.Write() method. Therefore, the code inside this type of code block should be an expression, and not a statement. Remember now from the previous post on this topic, one of the differences between expressions and statements: expressions can be used as parameters to methods while statements cannot.

<%= String.Format("The title of this page is: {0}", this.Title ?? "n/a") %>

becomes

private void __Render__control1(HtmlTextWriter __w, Control parameterContainer)
{
    // ...
    __w.Write(string.Format("The title of this page is: {0}", base.Title ?? "n/a"));
    // ...
}

Conclusion

I’m sure that it has happened to you many times, when you run your page you get compiler error CS1026:

) expected

Well, you can add a right parenthesis but it will not help. We now know that we were using a statement where an expression was expected. This will happen even more often when you develop ASP.NET MVC views, since the use of embedded code blocks is so common. And it’s in our nature as C# developers to add that semicolon after an expression in that context.