Recently, I was playing with archive.org and came across some old blog postings of mine. These postings are about ASP classic (you know, that old stuff that no one really pays attention to anymore).... Long after learning .NET, I was charged with rewriting a site (from scratch) in ASP. I typed "IsPostBack" and of course was told that was undefined. Doh! So I did a few things to make ASP a bit more .NET-like. Anyone still writing in ASP but used to .NET may want to take a look at this!
Making Classic ASP Feel Better (Wednesday, March 02, 2005)
So overall, classic ASP sucks. I hate it, I don't like touching it, its ruining my C# coding habits, and I'm about to kill someone because I have to code in it. That being said, I found a way to make classic ASP feel a little bit better: .NET it.
Currently, I am working on a project which is implemented in ASP. Because the code base is ASP, I need to build this new module in ASP. Building new things in classic ASP makes me cringe, the thought of mixing code with HTML and having to possibly migrate to .NET in the future is disasterous. That said, I have found a way to make it bearable: Make your own .NET framework (so to speak).
After becoming completely fed-up with the ASP coding style, I decided to implement a bit of a framework of my own. Events that are triggered on the client and processed by functions, and a clean “code-behind” style of coding.
Two includes (framework.inc.asp and framework_top.inc.asp) make up the majority of the framework and are quite simple. I'll show an example below:
MyPage.asp
<html>
<body>
<form id=“Form1” method=”post”>
<!--#INCLUDE file= “MyPage.inc.asp”-->
Click this button for a suprise:<br>
<input type=“button“ onclick=“onEvent(this.name,'onClick')“ name=“mybutton“ value=“Click me“><br>
<%= StrVisibleVar %>
</form>
</body>
</html>
--------------------------------------------------------------------------------
MyPage.inc.asp
<!--#INCLUDE page=“framework_top.inc.asp”-->
<%
' The variable that will hold the string that will be outputted if the button is clicked
Dim StrVisibleVar
' Occurs on page load
Function Page_Load()
'Do Stuff
End Function
' Occurs when the button is clicked
Function myButton_onClick()
StrVisibleVar = “The server says you have clicked the button“
End Function
%>
<!--#INCLUDE page=“Framework.inc.asp”-->
--------------------------------------------------------------------------------
Framework_top.inc.asp
<&
' This function is only here if it is never replaced by one in MyPage.asp
Function Page_Load()
' This will never trigger
End Function
%>
--------------------------------------------------------------------------------
Framework.inc.asp
<%
' Holds the value stating if this is a postback
Dim IsPostBack
' Not sure on this code
IsPostBack = (request.HttpParams(“HTTP_METHOD“) = “POST“)
' First call page load
call Page_Load()
'Now check if an event fired.
If (IsPostBack = true) And ( request(“eventOccured“) <> ““ ) Then
'Trigger the event.
execute( “call “ & request(“eventOccured“) & “()” )
End If
%>
<!-- This will be appended in the form to handle postbacks. -->
<script language=”Javascript”>
'Submit the event to the server (do a postback)
onEvent( triggerName, triggerEvent )
{
document.forms[0][“eventOccured“].value = triggerName + “_“ + triggerEvent;
document.forms[0].submit();
}
</script>
<input type=”hidden” name=”eventOccured”>
--------------------------------------------------------------------------------
Most of this is pseudo-code, as I recreated it from the top of my head, but you get the idea. Its pretty cool to implement, and gives you a bit of .NET style coding and view-abstraction from your code.
Saving ASP VBScript "Objects" to Session (Tuesday, March 08, 2005)
Continuing my trouble and hatred of anything todo with Visual Basic, especially VBScript. In this episode of The VB Sucks Edition, I'll reivew the problem with VBScript "Objects”. As any programmer knows, VBScript was never meant to be object-oriented, but by VBS 5, someone at Microsoft thought they could try to make it a bit OO compatible. The introduction of VBS classes was a major step in that direction. This seems like a good idea, but instead of making real objects, Microsoft hacked together classes that really mean nothing. Let me explain.
VBS objects are not really stored in memory as objects. For this reason, it is not possible to store a VBS object in the Session or Application variables in ASP. This creates huge headaches, and is completely rediculous. There are however, some solutions.
The first solution is "Serializing" your class. You will not truely be serializing anything, but rather creating a "seralize" and "deserialize" method for each class that you declare. These methods will take a Session variable name as a parameter and "store" or "retrieve" a class from session. See the example below.
Class MyClass
Dim Var1
Dim Var2
End Class
Function Serialize_MyClass( instance, sessionVar )
Session( sessionVar & ".Var1" ) = instance.Var1
Session( sessionVar & ".Var2" ) = instance.Var2
End Function
Function Deserialize_MyClass(sessionVar)
Dim instance : Set instance = new MyClass
instance.Var1 = Session( sessionVar & ".var1" )
instance.Var2 = Session( sessionVar & ".var2" )
Set Deserialize_MyClass = instance
End Function
This solution will work if you must keep all your code in VBScript, however is quite a pain to implement. If you can mix JScript into your code, I suggest using the following solution.
The other way of saving objects to session in ASP is not to use VBScript objects, but use JScript objects instead. Because of the way JScript creates objects, you can save JS objects to Session. By declaring your class in JS, you can keep your code (somewhat) clean, and still have the ability to save your objects. See below for an example.
<script runat="server" language="jscript">
function MyClass()
{
this.Var1 = Var1;
this.Var2 = Var2;
}
var Var1, Var2;
function MyClassFactory()
{
return new MyClass();
}
</script>
Using script like the one above allows you to keep your class declarations clean, and removes the need for "serialization” functions. The only problem that still remains is VBScript can't declare instances of JScript classes (even though it can use them). For this reason, I suggest using a factory function in JScript for your classes (such as MyClassFactory in the example above). Because VBScript can call JScript functions, you will be able to get a new instance of the JScript class into your VB code, as shown below.
Dim instance : instance = MyClassFactory()
instance.Var1 = "12345"
So there you have it, the half-ass hack to solve the problem of saving classes to Session or Application variables to the piece of junk that is VBScript.
Through my time in software development, I've often been a project lead or a technical lead in the group that I've been in. The management of several developers and of the source that is generated has always been an issue, and with every project I've come closer to perfecting my solutions to these problems. On the way, I've picked up advice from articles, coworkers, superiors and trial and error. I certainly don't have the be-all-end-all answer to these problems, and am not sure if anyone does have them, however I like to believe that I'm edging closer to the holy grail.
Good and professional software developers are very hard to come by. I've been told before that you need one good developer and a bunch of code monkeys to put together a project. No matter how hard I'd like to believe that, its not true. Modern software development requires deep understanding of core concepts that many people lack. If you have a group of a few highly talented developers your ROI will be much higher than if you have 100 times the number of code monkeys, even if there is a talented developer overseeing them.
The most dominent difference between a code monkey and talented developer is an understanding of architecture. A talented developer understands the architecture of the environment around him, and is able to architect his solution on the fly, building classes and methods necissary to make an intuitive, reusable and refactorable code base. Unfortunately, this is one of the most difficult talents to come by.
The three most difficult (and most in demand) talents are also the most important for effective software development.
- Architecture
- Software management
- Environment setup and maintainance
These three items, although a very small portion of development, are closely connected and probably the most important things to a groups effectiveness.
Environment Setup and Maintainance
The configuration and maintainance of the development environment is one of the most critical aspects of running development in a team. The initial setup takes some time, usually a day to a week, depending on your experience with setting up environments and the training required in your team, but can save endless hours and headache once properly configured. Very few teams properly configure their environment for effective development. A well configured team will need the following (and must use them appropriately).
- Source Control - Most teams configure a source control system, however very few teams that I have worked in or seen working use source control properly. Branches and merging are two of the most important aspects of source control, however very few teams seem to understand how and when to properly use branches. Nearly every feature in your project should be developed on a branch, and code merges should happen regularly. See more below in the "Source Control" subsection.
- Team task and issue management - Task and issue management is probably the second most common thing teams configure. Unfortunately, most teams work with paper-based systems and do not seem to make a good distinction between "completed" and "released". It is a big benefit if this aspect of your rig integrates with source control's changesets and the integration's builds, but software packages that do this (like Team Foundation Server) are not always available.
- Continuous integration (daily builds) - One oft-overlooked component of a good development environment is a daily build of the trunk (and/or important branches) of the source control. Daily builds allow for regular status checks and a working build of the application that can be used and tested, with everyones changes combined.
Source Control
Source control is a difficult thing to tackle without seeing a system congfured properly in the first place. It took me a while to fully understand how source control should work. Ultimately, there are two ways to think of source control, and it depends on how large and how long running your project is.
Source Control Method 1: Long running, Large Project and/or Many Developers
The first method uses branching to split off versions of the project. This means that you know ahead of time what features will enter which version of the project. If a version is a long-running development effort "sub version" branches may be created to mark milestones.

Very large developer groups may want to have a version branch, and branches off the version branch for features or feature sets. This allows smaller groups of developers to share code amongst themselves, but not affect the other developers on the version.
In any case, all code that is checked into or merged into the version and trunk should be buildable code. These are the branches that you will do your continuous integration on, and any new feature may be derrived from. A broken trunk will significantly slow down development time.
Typically when releasing when using this model, you will release from your "version" branch, not from the trunk, as other versions may have edited the trunk. Hotpatches and critical bug fixes that affect all versions, or need to be released as a patch to the current production version should be a new branch off the trunk that is merged back into the trunk when its completed. Any version that is about to be released should have the trunk reverse-merged into it so it picks up these changes.
Source Control Method 2: Small Development Teams and/or Short Running Projects
The second source control method uses less branches to achieve similar goals. In a rapid paced environment where less emphsis is placed on versioning, the trunk can be considered the "latest version" that is released. In this scenario, all work is done on a seperate branch (or multiple branches if different features are being built). Small fixes or patches are applied as short-lived branches off the trunk that are immediately merged back in.

In this model, when releasing, you will merge any features destined for the release into the trunk and build that as your release. The risk to this model is that the trunk is overall less stable because it is being continuously changed for releases. If less QA is going into your product between releases, this model should suffice.
Notes on Source Control
The hardest part about source control is getting everyone else to play along. Users should only checkin code that works. Many developers checkin whatever they have daily, for fear of losing it. This is fine, but then give that developer their own branch and let them merge when they are done. Developers who checkin code that doesn't work should feel your wrath :-).
Continuous Integration
Continuous integration benefits you because you can always checkup on the health of your branches, always have the option of testing and releasing a build on a given day, and have the ability to rollback to a previous release should something go wrong. In addition, by doing the integration processing on a seperate machine, you ensure your project thats in source control is always buildable by a machine not configured as a development machine. This meants that your project will most likely "copy and run" when setting up new developers.
I much prefer Team Foundation Server for the continuous integration tasks. The reporting you can get from TFS is great. In circumstances where TFS does not exist, your options are usually NAnt, or MSBuild.
I am not a big fan of NAnt, as creating project specs is not simple. I have been using MSBuild in this situation along with PowerShell. I create a PowerShell script that pulls from source control, sets up my environment and runs MSBuild with the SLN file, then copies output to an "install" directory. This is typicially a pretty solid solution. Throw the PowerShell script in the "Scheduled Tasks" and instant continuous integration. Woot!
Developers, Developers, Developers.... Management
Management of development teams is not a trivial task, especially when the team is not of your picking (as is usually the case). Many teams you will enter have a mix of good and "less good" developers. The good (level 1) developers will be happy with a good architecture and will architect their own code while they write it, keeping in mind where the project is going. The not-so good (level 2) developers will write long procedual code, copy/paste and generally ignore their sorroundings and habitat. Unfortunately, we are typlically required to manage both types.
Management of a development team is a test of not only your social and managerial skills, but also your architecture skills. The goal as a technical lead of a project should be two fold:
- Manage the tasks at hand to complete the project
- Manage the architecture of the system
Managing the tasks is mostly handling the assignment of the jobs. Choosing the right person for the task, and making sure it gets done. This is basic project management, and in large projects, may be delegated to a project manager. I am not going to write a project management book here as there are plenty of them already, so lets skip this.
Managing architecture is a skill that few people talk about and more people should be doing. This is a skill that I am still working on perfecting, and something I only recently discovered. Good architecture is many things. Many people say good architecture means code is legible, flexible, consistent, reusable/refactorable and stable. These are definately major qualities of good architecture, but I'd like to add one more. Good architecture should be usable by the not-so-good developers in your team.
The developers that can't see architecture generally know somewhat how to use it (they use the .NET of Java SDK's, for example). Your architecture should be transparent enough to them that they can query simple interfaces you give them for data. Outside of that, it should blackbox any code that someone rights. Like modular, unit-test driven development, the not-so-good developers should be coding an object or screen or whatever in a box -- somewhere that you say "here are your inputs, here are your outputs, and here are the services you can use -- make me this". No one should ever care whats going on inside as long as the code works. Service oriented architectures generally aid this situation greatly.
A few things to consider when building an architecture that can handle bad code:
- Modularize as much as possible
- Use things like dependency injection to allow novice developers to get to interfaces without having to touch any of your external APIs. If you can say "use interface IDataAdapter" and they can just "import" that, all the better. If you are writing a Winforms app, consider using CAB (Microsoft Composite UI Application Block) to aid in this.
- Consider using an SOA design.
- If this is a GUI application, have your better developers work out the backend, and expose an interface early on. The SOA can be a Windows Service in the backend and the UI in the front end querying it over remoting. Let the more novice developers deal with UI layout code (especially in the context of ASP.NET). Give them the interface and let them go.
- If this is a server-side application, modularize components into seperate services talking through interfaces or remoting, and have developers concentrate on their part
In any case, this turned into a much more lengthy rant than I expected. I really just wanted to write down some thoughts. I hope this is somewhat helpful to someone. None of this is revolutionary, but I've never read anything that summarizes development in a team, so I figured I'd write something up.
Tell me if you have any ideas to contribute!