The Dual Life of Code Behind

When you create an ASP.NET page using Visual Studio .NET, the default processing model is to use code-behind (the basics of which I described here). One of the more interesting aspects of code-behind is that you can specify the code for the code-behind assembly using two different techniques.  The first, and most commonly used is to build an assembly and deploy it to the bin directory on the web server.  The second mechanism is to specify the file containing the source code in the Page directive for the ASPX file.

Compiled Assembly

<%@ Page Language=”C#” Inherits=”ObjectSharp.WebPageClass” %>

Source Code

<%@ Page Language=”C#” Src=”WebPageClass.cs” %>

There are pros and cons to both of these approaches.  Functionally, they are equivalent.  When the first request is made to the page, the source code file is compiled and the resulting assembly loaded into memory. For every subsequent request, no compilation is required. Not only does this mean functional equivalence, but it also means that there is no performance penalty for deploying source code instead of a compiled assembly.

The biggest downside of the source code technique is exactly that, however.  That the code file needs to be deployed onto the web server.  This, naturally, has the potential to be a security problem.  A deployed assembly doesn’t have quite the same exposure, if only because it can be deployed into the Global Assembly Cache instead of directly into the application’s virtual server.

While it might seem that the security risk might tilt the tables entirely towards compiled assemblies, that isn’t true.  The problem with compiled assemblies has to do with updates to the web site.  When a new version of a compiled assembly is deployed to the web server, IIS is smart enough to detect the change.  The current web application is stopped and restarted so that the modified assembly can be loaded.  Unfortunately, the stopping and starting of the web application means that every Application and, more importantly, Session variable is discarded.  Depending on how the web application has been designed, this can be a significant problem.

Source code deployment doesn’t suffer from the same problem.  As with compiled assemblies, IIS monitors the source code files, so that when an update occurs, a recompilation takes place.  So the updates do get activated immediately.  The difference is that the web application does not have to be stopped and started in order to get the changes in place.

Choices, choices.  The trick to ASP.NET, as it is with almost any discipline, is to understand not only the choices but when each can and should be used.  This not only helps you design better web applications, but also solve those nagging times when the web application seems to restart for no apparent reason.

The Code Behind Model of ASP.NET

Almost from it’s beginning, HTML has been a mixture of data, display and logic.  While the original static pages might have only combined data and display, once scripting was introduced the three disciplines have lived together uncomfortably.  ASP only made this situation worse by introducing a different location (the server) where the scripting code could be executed. 

Ugly doesn’t adequately describe this problem.  There is little possibility for functional reuse in this scenario.  It is difficult even to modify existing business logic, much less make sure that it’s capable of being using by other components. This is not how enterprise-class applications are suppose to be created.

While ASP.NET supports this older processing model (known as in-line), it also introduced a newer model known a code-behind.  While this particular model doesn’t eliminate the data/display co-mingling, it does take the business logic away from the web page.  Instead, the events are handled by methods in a separate class.  The code behind class. Let’s take a brief look at how these pieces (the ASPX page and the code behind class) get wired together.

<%@ Page Language="C#" Inherits="ObjectSharp.WebPageClass" %>

   
       
       
       
       
       
   

Above is a standard, if simplistic, ASPX page.  Were it not for that first line, it would look like pretty much a run-of-the-mill HTML page.  And it’s that first line that brings the code-behind class into play.

That first line is known as the page directive.  When the ASPX file is processed, the directive is interpreted to mean that a) the language in any of the script blocks in the file will be in C# and b) that the processor should use methods in ObjectSharp.WebPageClass to handle the events raised by the web form.  As an example, this means that the MyButton_Click method (seen above as the Onclick event handler for MyButton) would be implemented in the assembly that contains the ObjectSharp.WebPageClass class.

using System;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace ObjectSharp
{
    public class WebPageClass : Page
    {
        protected System.Web.UI.WebControls.Label MyLabel;
        protected System.Web.UI.WebControls.Button MyButton;
        protected System.Web.UI.WebControls.TextBox MyTextBox;

        public void MyButton_Click(Object sender, EventArgs e)
        {
            MyLabel.Text = MyTextBox.Text.ToString();
        }
    }
}

Above is an example of a code-behind file for that example ASPX page.  Again, there are a couple of points worth noting. First off, the class itself inherits from System.Web.UI.Page.  This is the base page for all ASP.NET code behind files.  The fully qualified name for this particular class is ObjectSharp.WebPageClass, which matches the Inherits attribute in the Page directive.  There is a public method called MyButton_Click that will be invoked whenever the MyButton control on the web page is clicked. 

The final item of note for this class definition are the three protected variables MyLabel, MyButton and MyTextBox.  You might have noticed that they correspond, by name and type, to the three elements of the example ASPX page that have asp: as the element’s namespace qualifier.  That is not a coincidence. By utilizing that asp: qualifier, a corresponding object is created in the code-behind.  Then when the methods of the object are manipulated within the code-behind class, the values on the web page are modified as well. 

In the example, the MyButton_Click method sets the Text property on MyLabel.  As a result, the MyLabel control on the page that is sent back to the browser will have it’s text updated.  This mapping is managed automatically by ASP.NET and has the effect of moving the web page development model much closer to the Windows Forms model.  While you can accurately claim that as an abstraction the ASP.NET code-behind model is leaky, as a starting point for ASP.NET developers, it is nice to have a familiar base from which to build.

 

Last Developer Standing

In case you were unaware, Microsoft Canada is in the middle of running a Last Developer Standing competition. Modelled on the wildly popular (or at least, moderately watched) Last Comic Standing show on television, the idea is to give developers a series of tests.  For each test, only the developers who answer the most questions correctly get to move on to the next round.  What’s even better is that the final developer gets more than just good wishes…to the tune of $25,000.  More information can be found at http://www.lastdeveloper.com.

So why am I mentioning this now?  As part of this contest, I have been asked to blog about some of the topics that contestants will face.  These posts are available on a specific feed (http://objectsharp.com/Blogs/bruce/category/104.aspx), as well as my main feed.  So stay tuned for information that might very well be what you need to be the Last Developer Standing.