Legacy Code – Dealing with Classic ASP


I’ve written quite a few blog posts about legacy code.  In this blog post I’m going to discuss how you can deal with classic ASP, why you should deal with it sooner than later and some details of what to do.

Classic ASP

If you’re running a .Net shop, Classic ASP is about the most difficult monster to deal with.  Off the top of my head, I can list a few disadvantages to having one or more asp pages mixed in with your .Net code:

  • ASP executes under the IIS app pool pipeline type of “Classic” and will not work well with the “Integrated” managed pipeline mode.
  • ASP has it’s own session management.  If you mix ASP with .Net, you’ll end up with two different session storage mechanisms.
  • ASP does not have a compiler.  Bugs are only discovered during run-time.
  • ASP does not have a robust unit testing capability.
  • ASP is rarely written in a modular fashion.  Object oriented design can be used but rarely is.
  • ASP is not supported by Microsoft increasing the likelihood that a future version of IIS might not support it.
  • ASP contains config settings in the global.asa and does not recognize the web.config file.

The behavior of an ASP page is similar to JavaScript.  You can change it on the fly and not have to worry about re-compiling it.  This is only a minor advantage considering the fact that you must test all features in run-time.

Eliminating Classic ASP pages

Your first goal should be to eliminate these pages.  Here is a list of advantages to eliminating all ASP pages in your product:

  • Finding qualified software developers will be easier.  ASP knowledge is rare and becoming rarer.
  • Non structured ASP code is very difficult to work with.  Development time can be reduced by converting to .Net.
  • .Net code can have unit tests added.
  • Compile time bugs can be identified before code is released.
  • Memory and performance profiling tools work with .Net.
  • Refactoring tools work with .Net, reducing errors when variables are renamed.
  • You can combine your config settings to the web.config file.
  • Visual Studio will auto-indent VB.Net code reducing coding errors.

Some disadvantages of eliminating ASP pages in your product could be:

  • It costs money/man-hours to convert the code.  The amount can vary depending on the level of conversion.
  • Converting the code will cause bugs, translating to a degradation of customer satisfaction.

Levels of Conversion

There are different levels of converting code.  The level depends on how far you wish to go with the conversion.  The easiest level to eliminate ASP is to convert it directly to Visual Basic .Net.  No special translation, no real cleanup of code, just convert as directly as possible.  You’ll end up with the same spaghetti as before, except you can now compile it together with your existing code.  No new features are created when performing this type of conversion.

The next level is to convert and cleanup.  This level involves converting to VB.Net and then maybe consolidating your common functions (from ASP) with your existing common objects and methods.  This usually occurs if you have a database driven web application.  If you have a mixture of .Net and ASP code, you’ll end up with two sets of common database wrappers.  Merging these together will reduce your code and if your .Net objects are unit tested, you now have a more robust set of database functions.  This level of conversion is difficult and can take a lot of time because your common objects/functions are probably going to be alien to each other.  There will be a lot of refactoring of pages to use the common .Net objects.  No new features are created in this type of conversion.

The next level is to convert into another language such as C#.  I’m assuming your system has a mixture of ASP and C# and possibly VB.Net.  If you plan to convert to C#, this will be a difficult task.  C# syntax alone is not close to ASP syntax like VB.Net is.  The hazard of doing your conversion this way is that you’ll cause a lot of bugs that your customers will notice without gaining any new features.

The next level of conversion is the replacement.  This is where you redesign and replace your ASP code with completely new code.  This is very long term and hazardous.  You’ll probably need to live with your ASP for years before you can replace the code with new systems.  The advantage of this method is that the conversion is buried into the work of creating new features.  Customers will attribute bugs with the new code (since there will be bugs in the new code), but there will also be challenges with integrating with existing ASP legacy code.

Converting from ASP directly to VB.Net

Let’s pretend that you’ve settled on converting your ASP into .Net as quickly and as cheaply as possible.  Now you need to take inventory of your ASP pages and you’ll need to plan which pages you’re going to convert first.  I would recommend converting a few smaller pages just to get the feel of it.  You might want to determine what the maximum number of converted pages per release will be.  This will probably depend on developer effort and QA effort.  You could break it into systems and deploy one system of converted pages at a time.  If you have on-going enhancements, then ignore any pages that are about to be replaced by any new subsystem.  Convert those last if necessary.

Once you’ve identified your pages, you’ll notice that there are some common functions that are probably contained in included ASP pages.  Those will need to be converted to .Net first.  You should define a unique namespace for all of this legacy code so that your functions, which will be converted to objects and methods don’t collide with any existing .Net code.

Converting an ASP Page

Let’s get down to some details.  An ASP page typically consists of a collection of programming languages crammed into one source file with switches that indicate where one language starts and another stops.  Here’s an example:

<% Option Explicit %>
<!--#include virtual="/common/myutil.asp"-->
Dim sSQL, rsTemp, dbConnect
Dim action, note, id

If Not checkPageRights("MyPage") Then Response.Redirect("/denied_access.asp")

id = Trim(Request("id"))

If Request("add")<> "" and trim(Request("id")) <> "" then

  '-- Adding a new user
  '-- some asp code here
End If

' Read list
sSQL = "query_for_list " & dbid(id)
executeSQLStatement sSQL, id, rsTemp, dbConnect

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

  <style type="text/css">
  body {
    margin: 5px 5px;
    background: #FFFFFF;
  <!--#include virtual="/js/jquery_stuff.js" -->

  <% While NOT rsTemp.EOF %>
    <tr><td><%=rsTemp("name") %></td><td><%=rsTemp("age") %></td></tr>
  <% Wend %>

<script language='javascript' type='text/javascript'>
function ConfirmDel() {
  if (confirm("Are you sure you want to delete this record.  Press OK to delete."))
    return (true);
    return (false);


You’ll need to cut any Javascript and HTML and put it into the front-side page of a VB.Net web form.  Some code that works in ASP will not work with the VB.Net front-side page.  For that code, you’ll need to put the code in a method and call the method from the front-side code.  You might even need to go as far as writing the code from the code-behind page.

All functions will need to have parenthesis added to them.  The “executeSQLStatement” will need to be converted to: “executeSQLStatement(sSQL, id, rsTemp, dbConnect)” in order to compile.

As I mentioned earlier, you’ll need to convert any included files first.  That means that the “myutil.asp” page at the top will need to be converted to VB.Net first.  You can convert the entire file, or just convert common functions that are used in this page.  The advantage of doing it peacemeal is that you’ll end up removing any dead-code while you’re converting.  You can also include your job of testing common code with the pages that you are converting.  As you continue to convert more difficult pages, you should have most of your common functions converted into objects/methods.

Here are a few conversions you’ll need to be aware of:

  • Convert any line wrapping “&_” into a “& _”.  VB.Net expects a space between the ampersand and the underscore.
  • Add parenthesis to your function calls if needed.
  • “Wend” converts to “end while” in VB.Net.
  • isNul() converts to “Is Nothing”.
  • “Date” converts to “DateTime.Now()”
  • Remove any “set” statements.
  • Add “.Value” to recordset variables.  rs(“lastname”) becomes rs(“lastname”).Value

Microsoft has a good site for conversion tricks: Converting ASP to ASP.NET.  I would recommend reviewing this information before starting.

Next, ASP code will go into the code-behind page.  That would be this section of code:

Dim sSQL, rsTemp, dbConnect
Dim action, note, id

If Not checkPageRights("MyPage") Then Response.Redirect("/denied_access.asp")

id = Trim(Request("id"))

If Request("add")<> "" and trim(Request("id")) <> "" then

  '-- Adding a new user
  '-- some asp code here
End If

' Read list
sSQL = "query_for_list " & id
executeSQLStatement sSQL, id, rsTemp, dbConnect

You’ll need to make sure that any variables that are used in the front-side code are declared globally in the code-behind.  You’ll also need to determine the data types and add those.

After You Convert a Page

When you have completed your raw conversion, you’ll probably execute the page and see how it compiles and runs.  Fix any obvious bugs.  Does it run slower?  If so, then something is wrong.

I would recommend running a memory profiler at least once to see if there are any memory leaks.  Classic ASP can handle some memory management better than VB.Net and some things are worse.  Database connections are handled a bit better in ASP.  You’ll need to make sure your database connections are closing when your web page is finished.  If not, then you’ll need to track down where to put in a close statement.  I usually open up a studio window into MS SQL and execute the following query to determine how many connections are currently open:

  DB_NAME(dbid) as DBName,
  COUNT(dbid) as NumberOfConnections,
  loginame as LoginName
  dbid > 0
  dbid, loginame

Then run your web page a few times and see if the numbers increase.  You’ll need to have a local database that only you are using in order for this step to be effective.

I would also recommend purchasing a tool such as ReSharper.  You’ll discover variables that are not used.  When your page works, remove all the unused variables.  Reduce the clutter.

Upon completion of your page conversions you can change your IIS server to use the Integrated managed pipeline.  Make sure you perform a regression test after this has been switched.


If your system has hundreds of Classic ASP pages you can script some of the conversion.  I would make a list of common functions and then create a script or program that can search a designated source file and check for missing parenthesis.  Encode as many of the conversion rules as possible in your script to handle the bulk of the conversion before you move the code to your .Net source file.

Name your .Net source the same as your asp file (you’ll end up with extensions like .aspx, .aspx.designer.vb and .asp.vb which do not collide with .asp extensions).  Once you have replaced an ASP page, be sure to map out any links to that page in your application to the new page.  I would also recommend changing the ASP extension to something like .asp.done so you can catch any missed mappings in your application while you are testing.


Legacy Code Writers


The purpose of this blog post is to describe how legacy code gets perpetuated years beyond its useful life and how to put a stop to it.  I will also make my case for why this process needs to be stopped.  I will attempt to target this article to managers as well as the developers who are continuing the creation of legacy code.  I would like to make a disclaimer up front that my intent is not to insult anybody.  My intent is to educate people.  To get them out of their shell and think about newer technologies and why the new technologies were invented. 

My History

First, I’m going to give a bit of my own history as a developer so there is some context to this blog post.  

I have been a developer since 1977 or 78 (too long to remember the exact year I wrote my first basic program).  I learned Basic.  Line numbered Basic.  I join the Navy in 1982 and I was formally educated on how to repair minicomputers, specifically the UYK-20 and the SNAP-II.  In those days you troubleshoot down to the circuit level (and sometimes replace a chip).  While I was in the Navy, the Apple Macintosh was introduced and I bought one because it fit in the electronics storage cabinet in the transmitter room on the ship (which I had a key to).  I programmed with Microsoft Basic and I wanted to write a game or two.  My first game was a battleship game that had graphical capabilities (and use of the mouse, etc. etc.).  It didn’t take long before the line numbers became a serious problem and I finally gave in and decided to look at other languages.  I was very familiar with Basic syntax, so switching was like speaking a foreign language.  It was going to slow me down.

I stopped at the computer store (that really was “the day”), and I saw Mac Pascal in a box on the shelf and the back of the box had some sample code.  It looked similar to Basic and I bought it.  I got really good at Pascal.  Line numbers were a thing of the past.  In fact I used Pascal until I was almost out of college.  At that time the University of Michigan was teaching students to program using Pascal (specifically Borland Pascal).  Object oriented programming was just starting to enter the scene and several instructors actually taught OOP concepts such as encapsulation and polymorphism.  This was between 1988 and 1994.

The reason I used Pascal for so long was due to the fact that the Macintosh built-in functions used Pascal headers.  The reason I abandoned Pascal was due to the fact the the World Wide Web was invented around that time and everything unixish was in C.  I liked C and my first C programs were written in Borland C.  

Fast Forward…

OK, I’m now going to fast-forward to the late 90’s and early 2000’s when OOP programming really became main stream and frameworks, unit testing, etc. all became available.  When the web became something that businesses used there were only a hand-full of tools available.  There was C, html (with javascript), Java, PHP and Microsoft’s product called ASP (and a hand-full of oddballs that no longer exist).  If you wanted to develop a dynamic interactive website application, and you were running Microsoft Windows Server products, you had to perform the deed in ASP.  I avoided this path by using PHP on a Linux machine, but I got lucky.  I was in charge of the department and I made the final decision on what technology will be used and how the product would be developed.  Don’t get me wrong, there is a lot of ASP code that is in use and it is stable and operational.  Unfortunately, ASP is one of the most difficult legacy code to convert into something modern.

What’s my Beef with Legacy Programmers?

If your development knowledge ended with ASP and/or VB without learning and using a unit testing framework, the MVC framework (or equivalent), ORMs, Test Driven Development, SOLID principles, then you probably are oblivious to how much easier it is to program within a modern environment.  This situation happens because programmers focus on solving a problem with the tools they have in their tool box.  If a programer doesn’t spend the time to learn new tools, then they will always apply the same set of tools to the problem.  These are the programmers that I am calling Legacy Programmers. 

Legacy Programmers, who am I talking about?

First, let’s describe the difference between self-taught and college educated developers.  I get a lot of angry responses about developers who have a degree and can’t program.  There are a lot of them.  This does not mean that the degree is the problem and it also should not lead one to believe that a developer without a degree will be guaranteed to be better than a degree carrying developer.  Here’s a Vin diagram to demonstrate the pool of developers available:

The developers that we seek to create successful software is the intersection of the degree/non-degree programmers.  This diagram is not intended to indicate that there are more or less of either developer in the intersection called solid developers.  In my experience, there are more college degree carrying developers in this range due to the fact that most solid developers will be wise enough to realize that they need to get the piece of paper that states that they have a minimum level of competence.  It’s unfortunate that colleges are churning out so many really bad developers, but to not obtain the degree usually indicates that the individual is not motivated to expand their knowledge (there are exceptions).

OK, now for a better Vin diagram of the world of developers (non-unix developers):

In the world of Microsoft language developers there are primarily VB and C# developers.  Some of these developers only know VB (and VB Script) as indicated by the large blue area.  I believe these individuals outnumber the total C# programmers judging by the amount of legacy code I’ve encountered over the years, but I could be wrong on this assumption.  The number of C# programmers are in red and the number of individuals who know C# and not VB are small.  That’s due to the fact that C# programmers don’t typically come from an environment where C# is their first language.  In the VB circle, people who learned VB and not C# are normally self-taught (colleges don’t typically teach VB).  Most of the developers that know VB and C# come from the C# side and learn VB, or if they are like me, they were self-taught before they obtained a degree and ended up with knowledge of both languages.

The legacy programmers I’m talking about in this blog post fall into the blue area and do not know C#.

Where am I Going With This?

OK, let’s cut to the chase.  In my review of legacy code involving VB.Net and VB Script (AKA Classic ASP) I have discovered that developers who built the code do not understand OOP patterns, SOLID principles, Test Driven Development, MVC, etc.  Most of the code in the legacy category fit the type of code I used to write in the early 90’s before I discovered how to modularize software using OOP patterns.  I forced myself to learn the proper way to break a program into objects.  I forced myself to develop software using TDD methods.  I forced myself to learn MVC (and I regret not learning it when it first came out).  I did this because these techniques solved a lot of development issues.  These techniques help to contain bugs, enhance debugging capabilities, reduce transient errors and make it easier to enhance without breaking existing features (using unit tests to perform regression testing).  If you have no idea what I’m talking about, or maybe you’ve heard the term and you have never actually used these techniques in your daily programming tasks, you’re in trouble.  Your career is coming to an end unless you learn now.

Let’s talk about some of these techniques and why they are so important.  First, you need to understand Object Oriented Programming.  The basics of this pattern is that an object is built around the data that you are working on (I’m not talking about database data, I’m talking about a small atomic data item, like an address or personnel information or maybe a checking account).  The data is contained inside the object and then methods are built to act on this data.  The object itself knows all about the data that is acted on and external objects that use this object do not need to understand nuances of the data (like how to dispose of allocated resources or how to keep a list properly ordered).  This allows the developer that creates the object to hide details, debug the methods that act on the data and not have to worry about another object corrupting the data or not using it correctly.  It also makes the software modular.

On a grander scale is a framework called MVC (Model View Controller).  This is not the only framework available, but it is the most common web development framework in Microsoft Visual Studio.  What this framework does is give a clean separation between the C# (or VB) code and the web view code (which is typically written in HTML, JQuery and possibly Razor).  ASP mixes all the business logic in with the view code and there are no controllers.  In MVC, the controllers will wire-up the business logic with the view code.  Typically the controller will communicate with an AJAX call that gives the web-based interface a smooth look.  The primary reason for breaking code in this fashion is to be able to put the business logic in a test harness and wrap unit tests around each feature that your program performs.

Unit testing is very important.  It takes a lot of practice to perform Test Driven Development (TDD) and it’s easier to develop your code first and then create unit tests, until you learn the nuances of unit testing, object mocking and dependency injection.  Once you have learned about mocking and dependency injection, you’ll realize that it is more efficient to create the unit tests first, then write your code to pass the test.  After your code is complete, each feature should be matched up with a set of unit tests so that any future changes can be made with the confidence that you (or any other developer) will not break previously defined features.  Major refactoring can be done in code designed this way because any major change that breaks the code will show up in the failure of one or more unit tests.

ORMs (Object Relational Mapping) are becoming the technique to use for querying data from a database.  An ORM with LINQ is a cleaner way to access a database than ADO or a DataSet.  One aspect of an ORM that makes it powerful is the fact that a query written in LINQ can use the context sensitive editor functions of Visual Studio to avoid syntax errors.  The result set is contained in a object with properties that produces code that is easier to read.

APIs (Application Programming Interface) and SOA (Service Oriented Architecture) are the new techniques.  These are not just buzzwords that sound cool.  These were invented to solve an issue that legacy code has: You are stuck with the language you developed your entire application around.  By using Web APIs to separate your view with your business logic, you can reuse your business logic for multiple interfaces.  Like mobile applications, custom mini-applications, mash-ups with 3rd party software, etc.  The MVC framework is already setup to organize your software in this fashion.  To make the complete separation, you can create two MVC projects, one containing the view components and one containing the model and controller logic.  Then your HTML and JQuery code can access your controllers in the same way they would if they were in the same project (using Web API).  However, different developers can work on different parts of the project.  A company can assign developers to define and develop the APIs to provide specific data.  Then developers/graphic artists can develop the view logic independently.  Once the software is written, other views can be designed to connect to the APIs that have been developed, such as reports or mobile.  Other APIs can be designed using other languages including unix languages running on a unix (or Linux) machine.  Like Python or Ruby.  The view can still communicate to the API because the common language will be either JSON or XML.

Another aspect of legacy code that is making enhancements difficult is the use of tightly coupled code.  There is a principle called SOLID.  This is not the only principle around, but it is a very good one.  By learning and applying SOLID to any software development project, you can avoid the problems of tightly coupled code, procedures or methods that perform more than one task, untestable code, etc.

The last issue is the use of VB itself.  I have seen debates of VB vs. C#, and VB has all the features of C#, etc. etc.  Unfortunately, VB is not Microsoft’s flagship language, it’s C#.  This is made obvious by the fact that many of C# Visual Studio functions are finally going to come to the VB world in Visual Studio 2015.  The other issue with VB is that it is really a legacy language with baggage left over from the 1980’s.  VB was adapted to be object oriented not designed to be an object oriented language.  C# on the other hand is only an OOP language.  If you’re searching for code on the internet there is a lot more MVC and Web API code in C# than in VB.  This trend is going to continue and VB will become the “Fortran” of the developer world.  Don’t say I didn’t warn ya!


If you are developing software and are not familiar with the techniques I’ve described so far, you need to get educated fast.  I have kept up with the technology because I’m a full-blooded nerd and I love to solve development issues.  I evolved my knowledge because I was frustrated with producing code that contained a lot of bugs and was difficult to enhance later on.  I learned each of these techniques over time and have applied them with a lot of success.  If I learn a new technique and it doesn’t solve my issue, I will abandon it quickly.  However, I have had a lot of success with the techniques that I’ve described in this blog post.  You don’t need to take on all of these concepts at once, but start with C# and OOP.  Then work your way up to unit testing, TDD and then SOLID.


Web Sessions


I’m going to create a series about how Microsoft handles sessions for VB.Net and C# web applications.  The purpose of these posts will be to provide a clearing-house of all the information needed to get a common session system going between multiple languages.

The Problem

Web sites typically use session data to keep track of who is logged in and what state they are in.  I’m not going to go into details on why sessions are used or how to use them to build a website.  Instead, I’m going to assume you are already familiar with this technique and you’re saddled with a large amount of legacy code that cannot be converted in one shot.  Let’s say you have a website in PHP and you’re attempting to migrate into a C# environment.  How do you go from one web page in PHP running on a Unix server into a C# program running on an IIS server?

There are many solutions, such as cookies, tokens passed in the URL, a GUID stored in a hidden field, etc.  The smoothest solution would be to somehow share the session data between different languages so that one page at a time can be converted and the URL from the old page can be redirected to the new page with a smooth and secure transition.  The first thing to recognize is that we’re going to have to store the session data in a database that is shared by all web sites that will be connected into one web application.  Microsoft provides this capability through their own session management.  

Using MS SQL Server to Store Session Data

For Dot Net applications, you can setup a SQL server to store the session data.  The following link is probably your best article for getting SQL setup with the ASPState database and redirecting your application to point to the new database:

Configuring ASP session state on SQL server 

Once you have set this up, you’ll need to make sure your user rights are setup in the ASPState and the tempdb database.  The session data is actually stored in the tempdb database in two tables: ASPStateTempApplications and ASPStateTempSessions.  The ASPStateTempApplications table contains the name of the application and the unique app id used by the session cookie (I’m going to assume you’re using the cookie mode in iis, since it is the default).  The ASPStateTempSessions table contains one record per session created.  All of the session data is encoded and stored in a binary field in this table called SessionItemShort (or if it’s larger than 7k, then it’ll be in SessionItemLong which is an image data type).

The Session Cookie

When your application creates a session, a cookie is created with the application id and a unique session id.  The default cookie name is “ASP.NET_SessionId”.  If you look at the session id the tempdb.ASPStateTempSessions table, you’ll discover that it is a large alphanumeric string.  That string represents two parts: The session GUID and the application ID.  The application ID is in hex in the ASPStateTempSessions table and it is in decimal in the ASPStateTempApplication.appid field.  If you are going to read the session data from the tempdb database ASPStateTempSessions table, then you’ll need to add the application ID to the end the cookie value.  Take your application name and read the application id from the ASPStateTempApplications table.  Convert this to hex, then append to the cookie value.  This will be the primary key of the ASPStateTempSessions table for your session data.

If your googling skills are savvy enough, you will have discovered most of this information from this article: Session State Providers.  

The next thing to note about this session setup is that the cookie is a non-persistent cookie.  There is no expire date and this type of cookie will remain until you close your browser.

If you dig into your SQL server and you look at your SQL Server Agent jobs, you’ll see a new one called ASPState_Job_DeleteExpiredSessions.  This job will execute the stored procedure: DeleteExpiredSessions once per minute.  The sole purpose of this stored procedure is to delete all cookies where the expires field is beyond the current date/time.  This will cause the session to expire.  If you look at this date/time in the
ASPStateTempSessions table, then refresh your browser, you’ll notice that the time updates.  The time will always be 20 minutes into the future (if your session is set to expire in 20 minutes, which is the default).  If your web page goes idle for more than 20 minutes, then you’re toast.

Sharing Session Data Between VB.Net and C#

The easy method of sharing between two languages is to set the application name to the same name in the global.asax file for both programs:

Session State shares session across subdomain, VB.NET website C# MVC 4 Application

Session Data

The session data that is stored in the tempdb.ASPStateTempSessions table is an encoded version of all the session variables and data used by your program.  There is this code in C#, which can decode this data into a list of variables:


This code does not handle objects, but it does demonstrate the complexity of how this is encoded.  Creating an encoder and decoder for this data for a multitude of languages would be very handy.  Especially if you wanted to use many languages in one large monolithic application.  I believe the reason that Microsoft encoded this data into one large field instead of using a sub-table of fields and data, is that they can store the session data for each session in one record.  This prevents a lot of table locking issues with deleting records and it also reduces the amount of time it takes to read and write to the database (assuming they had a database in mind when they designed this system.  If you look closely at the DeleteExpiredSessions stored procedure inside the ASPState database, you’ll see that a query of all the expired sessions is put into a temp table.  Then the temp table is looped through and each session record is re-checked as it is deleted, just in case it was updated or deleted while this operation was in progress.

Wrap up

For this blog post, that’s all I’m going to go into.  Armed with this information anybody can make a decision on how they want to pursue sessions with legacy code and new code.  For instance, you could design your own session system to mimic what Microsoft does and use child records to store your variables.  I am unsure how this will perform or what issues you’ll run into with this method.  You could write encoders and decoders for the session data and use the data that Microsoft stores (avoiding the need for converters and decoders from VB.Net and C# (i.e. you could write a codec for PHP, Classic ASP, Java).  By storing your session in the database, you can use different IIS applications for each language (or divide your systems into multiple applications).  You can also prevent your session from clearing when an IIS server is re-cycled, or if you have a server farm, you don’t need to worry about which server the web request returns to.