From the Suggestion Box: Why can't you use code expressions for properties?

From the suggestion box InfinitiesLoop asks:

"How about, why can't you use code expressions inline with server controls? You can obviously with the DataBinding expression <%# code %>, but you can't simply say <%= code %>. Using a custom expression builder it's only a few lines of code to enable this:

http://weblogs.asp.net/infinitiesloop/archive/2006/08/09/The-CodeExpressionBuilder.aspx

So I'm curious whether something like this was considered for the framework at one point, and if so, why it wasn't included. One disadvantage that expression builder has is that it doesn't work with NoCompile pages, but its so extremely useful for compiled pages."

Well, believe it or not, the spec for the Expressions feature for ASP.NET 2.0 gave CodeExpressionBuilder as an example of an expression builder we could implement. This would have been especially nice since as you discovered it takes exactly one line of code to implement it!

So why didn't we do it? I honestly don't know since I didn't own the feature until much later, but here are some reasons to consider:

  • Very poor designer support for it. For most features in ASP.NET 2.0 we made sure they worked really well in the designer. It's awkward to type code in a teeny little textbox with no Intellisense, syntax highlighting, or those cool squigglies that tell you where you messed up.
  • Doesn't work in non-compiled pages. Since it's code inside your expression and non-compiled pages don't go through the compiler, they simply wouldn't work - you'd get a parser error instead. This is similar to the first reason in that we also made sure that most features in ASP.NET 2.0 worked really well in non-compiled pages.
  • Hard for most users to understand page life cycle. What if I wanted to put some code in the expression that used a "calculated" value from another control? Well, it would surely compile, but the value would be wrong 99% - 100% of the time. Since the expressions execute really really really early in the page lifecycle they are mostly only useful for static values, such as connection strings, app settings, and localized resources. Sounds familiar? :)
  • And finally, my philosophical reason: I believe that code shouldn't be scattered in a page. If you want the value of DateTime.Now, I believe you should have a "TimeExpression" that offers several values, similar to my post on custom data source parameters. If you want one for user names, you should have a "UserNameExpression." It might sound like a lot of work, but I think your pages end up being super clean and easy to read. If it really is too much work, then using the custom CodeExpression is fine. Just be aware of when it won't work.

- Eilon

3 Comments

  • Thanks for the explaination :) I totally agree with all your reasons. At the same time though, it would be nice if there was a way to programmatically or declaratively (there's currently neither) initialize a control prior to its viewstate being tracked.

    For example if you override OnInit in a page and set a Label's Text field to something (like DateTime.Now), which is a fairly common and intuitive thing to do, you end up bloating the page's viewstate size, because that label is already tracking its viewstate changes. Because basically, in a control's OnInit method, it is not yet tracking its own viewstate, but its child controls are.

    All the solutions to this have issues. You can disable viewstate on the label, but you lose its viewstate-ness entirely, so other updates to it will be lost on postbacks. You can create a custom label control and initialize the value from there, but creating a custom control just to get an initial value is way overkill. You can hook into its OnInit method declaratively, but this requires either lots of OnInit handlers on the page or a single OnInit handler with a giant switch statement (if sender is this, do this, etc).

    Since most people don't really understand viewstate tracking they will simply do the page OnInit thing, and as a consequence, most asp.net pages out there have more serialized viewstate than they need to. In a lot of cases, WAY more than they need to. And the offenders have no idea what they've done.

  • Darren -- this assumes you are writing the control to begin with. Lets say you want the Text of a CheckBox to be the current Date. How do you do that declaratively? You can't without the Code Expression Builder, writing presentation logic in the code behind, or creating a custom CurrentDateCheckBox control. Writing the control is the most correct way to do it, but it would be better if the framework had a way to handle thie scenario so you didn't have to.

  • Hi Rick,
    Code expressions using ExpressionBuilders are executed before the page life cycle even begins. It executes at construction time of the page when the raw controls are new'ed up.

    Another kind of code expression, the ones that look like mostly just turn into calls to Response.Write(), which of course happens at render time. These are not related to ExpressionBuilders, however.

    Yes, we like to reuse the same names to mean different things all the time. All the good names were taken! :)

    - Eilon

Comments have been disabled for this content.