comments suggest edit

ASP.NET 2.0 MVP Hacks and
Tips Scott Hanselman mentions a new book in which he is one of the coauthors featured on the cover. Yes, they do look like they are throwing the twelve sided dice on a table with meticulously painted miniatures. If you have no idea what I am talking about, you have never embraced the inner geek.

The reason I mention this is that In 2005 I wrote a post in which I presented an Abstract Boilerplate HttpHandler. This particular post was inspired and built upon Scott’s original (non-abstract) boilerplate HttpHandler. And now it comes full circle as Scott has borrowed from my borrowing, cleaned it up a bit, put a tie and suit on it, and then put it in a book.

Nice work! Now in order to one-up him, I will have to borrow from the book (which would be borrowing from a borrowed borrow) and get a Hollywood movie made. Keanu Reeves stars in Abstract Boilerplate HttpHandler I - The Pipeline of Opportunity.

So among this book of MVP hacks, they have inadvertently included a Haack.

comments suggest edit

Zinedine Zidane I hear from a fairly reliable source that after the World Cup, Zinedine Zidane plans to move to Los Angeles to get into some kind of entertainment. That in and of itself is not exceedingly interesting. However, this source also tells me that Zidane has been offered a spot on the Hollywood United roster thanks to the other ex-French national team player, Frank LeBeouf.

That means that sometime in the near future, there is a small chance (you know how plans can change) that I may play in a soccer game against Zinedine Zidane, one of the world’s best players! Even though on the field, he will be just another opponent, I will probably bring my camera and try and get a pic with him before the game.

Although we would be in the same league, we are definitely not in the same league. Honestly, this all sounds a bit outlandish. I mean, he currently plays on Real Madrid for Pete’s sake! He is by no means over the hill yet. He could, if he wanted, join the MLS and completely dominate. Going from Real Madrid to our league would be a major drop in action.

On the other hand, if he really is retiring, a low key game once a week might be just the thing to keep in shape and not place such demands on his time.

In any case, does anybody out there know of any ex-professionals who are looking for a league in Los Angeles? Brazillian national team players are especially welcome. Whatever happened to Bebeto and Romario?

comments suggest edit

Axe Well this post marks my 1000th post on this blog. Since I am totally on board with the base 10 system, that makes this noteworthy to me. If we all used the hexadecimal system (base 16), then this post would be my 3E8th post which really wouldn’t warrant me even mentioning it in the first place. Be glad we are on base 10.

So how shall I observe the 1000th time that you’ve been Haacked? Obviously by writing about ways to avoid getting hacked.

I have a nice brand spanking new workstation so I figured now is as good a time as any to make the jump to running as a non-admin. This is what the security folks refer to as the principle of running with the least privileges. This is also referred to as LUA which stands for Least-Privileged User Account or Limited User Account depending on who you ask.

Hopefully I am behind the times and most of you are already running as LUA. But just in case, I will continue to plod on. This will be my third attempt to run as a non-admin, but the tools have gotten better since I last made the dive.

Temporarily Elevated Privileges

One of my favorite approaches to dealing with privileges is the idea of temporarily elevating privileges. This is in contrast to the approach in which you use RunAs to run a program using another user’s credentials. There are two ways to do this.

MakeMeAdmin

First of of all, there is the excellent batch file MakeMeAdmin written by Aaron Margosis and announced in this blog post.

This batch file temporarily elevates your normal account to an admin. This is useful in those scenarios when you need to install software and you want the per-user settings to apply to your profile, not the administrator’s profile.

WinSUDO

WinSUDO was inspired by the MakeMeAdmin script, but consists of a client and server piece. Instead of relying on a command window, WinSUDO installs as a shell extension. Right click on a program in Explorer and select the Sudo menu option. I haven’t tried it just yet as the author is in the middle of a rewrite, but it’s worth keeping an eye on it.

Setting Shortcuts To Prompt For User

If you right click on a shortcut and click the Properties menu item. Then click the Advanced button. You can check an option to Run with different credentials. When you double click on the shortcut, it prompts you with an option to run as yourself, or run as a different user.

Create Your Own Control Panel Shortcut

Control panel applets are a bit of a challenge since the RunAs option is not there when you right click an applet or Control Panel itself. So I went ahead and created my own control panel shortcut.

  • Right Click on the desktop and select New | Shortcut from the context menu.
  • For the location, just enter control.exe. For the name, I entered Control Panel.
  • Right click on the shortcut and click Change Icon… (looks matter!).
  • Select the icon that looks like the control panel (see the image below).
  • Now click on the Advanced… button and check the Run with different credentials option.

Control Panel
Selection

Visual Studio Development {.clear}

The article Developing Software in Visual Studio .NET with Non-Administrative Privileges is quite helpful in outlining the issues you may run into as a developer.

One particularly challenging issue is debugging ASP.NET applications on your local machine as a non-admin. Since a normal user doesn’t have the rights to debug applications running in the context of other users’s accounts. The article suggests editing machine.config and configuring ASP.NET to run under your own account.

I really don’t like this solution. If you open up the Group Policy Editor (Start | Run | Type in “gpedit.msc” without the quotes) you can find a “Debug programs” policy option. I may try adding that to my account instead, but I need to find out if it would open up a security risk that totally invalidates the security benefits of running as a LUA in the first place.

Community

If you are interested in learning more, check out this site devoted to a community of PC users who want to run without admin privileges. They have some great pointers to articles and tools to help mitigate the royal pain it is to run as non-admin on Windows XP.

Conclusion

Hopefully this time running as a non-admin will stick. I will keep you posted during the next 1000 posts.

comments suggest edit

Scott makes a great distinction between Open Source code and Source Out in the open.

Public Does Not Equal Open Source

I wanted to add to the discussion by pointing out two things. Often people make the mistake of assuming that any code posted on someone’s blog or in Google Groups is either open source or public domain. This is not necessarily true.

While it might be the intent of the author to make code published in a blog or Google Groups open to the public domain or freely distributed as open source, as the consumer of the code we cannot assume this to be the case. If the author does not state the license under which the code is available (either by just saying so or by referencing a license), then the author owns the exclusive copyright (assuming he or she wrote the code etc…).

I try to make a habit of asking permission from authors of useful code when I cannot find any license information on their blog. My blog is licensed under the Creative Commons Attribution license, so you can assume that any code snippets I post are licensed in the same way unless I specifically state otherwise.

I wrote on this topic in my Developer’s Guide to Open Source Software Licensing, which I know you read because developers just love reading up on legal topics.

The second thing I wanted to add to the discussion, and maybe I am way late on this, but I just recently learned about koders.com, an open source search engine.

It is a search engine that indexes various open source repositories and allows you to conduct searches through the source code. For each piece of code it returns, it presents the language, the location, the source, and the license.

This is an interesting way to take a look at open source code, though not without its quirks. Finding a method that you need can be difficult since the semantics of what code does and naming conventions are so different from project to project. But over time, this may become a useful tool.

comments suggest edit

This weekend I went to see the Los Angeles Galaxy play with my wife and some friends. What a disappointing game that was! Despite having discount tickets (only $10) we felt totally ripped off. During the whole game, my teammate and I were joking that “Ronaldinho would’ve made that play.”

My wife and I now have a new song entitled What would Ronaldinho do? sung to the tune of South Park’s What would Brian Boitana do? I think I will have to start passing out WWRD bracelets.

The Galaxy are playing boring lackluster soccer so far this season. The game was a scoreless tie till the Columbus Crew scored in injury time with an ugly goal. Fugly. It takes FC Barcelona visiting to play a Mexican team for us to get us some decent soccer around here. I am hoping to get some tickets to that.

Speaking of the big R, have you seen the amazing Nike commercial featuring Ronaldinho as a kid playing in the Brazillian futsal leagues (like soccer but indoor with smaller teams and ball). It splices scenes of him playing as a kid with him now. He was amazing back then. Here it is on YouTube.

This was a soccer weekend for me. I had a fantastic game on Saturday in which we won five to one, only to be followed by a terrible three zero loss on Sunday. I need to quit playing on Sundays, because it always erases the good feelings created on Saturday.

comments suggest edit

In two earlier posts I presented a couple of SQL stored procedures that I promised to tie together. The first procedure generates a random time of day and the second can be used to FTP a file from within SQL Server.

Well in this post I put these two together to create a stored procedure for creating a database job that will take a nightly backup of a database and FTP it to another location. I hope this isn’t terribly anti-climactic for you.

This script is perfect for a quick and dirty backup plan for a database. If you are dealing with enterprise level (and sized) databases, your DBA will probably scoff at this script, and rightly so. Such a situation really needs a more robust database backup plan probably with differential backups etc…

But for smaller operations, this will save your butt. I use this to backup my blog database and some of our development databases every night.

The parameters are pretty much a combination of the two previous parameters.

Parameter Datatype Description
@databaseName nvarchar(128) Name of the database to backup
@jobName nvarchar(255) The name of this Job as it would be listed in Enterprise Manager under Management | Sql Server Agent | Jobs
@scheduleName nvarchar(255) A descriptive name for the schedule.
@timeOfDay int Time of day as an int (HHMMSS). Default is -1 which indicates a random time of day between midnight and @maxHour
@maxHour int If generating a random time of day, the upper bound for the hour in which the backup job can run. By default 4 am.
@owner nvarchar(128) The database user account that this job runs under. By default the sa account.
@backupDirectory nvarchar(256) The directory on the database server to backup the file.
@ftpServer nvarchar(128) FTP host name.
@ftpUser nvarchar(128) FTP user.
@ftpPassword nvarchar(128) FTP user password.
@ftpPath nvarchar(128) FTP path.

Why the randomness?

Notice that if you set @timeOfDay to -1, this script will create a schedule for the job at a random hour of the day which is constrained by @maxHour. This is really there to help stagger the times at which the database backups run. All too often administrators make the mistake of scheduling the backups of all the backups at the same time. Of course, you can override this randomness by simply specifying a @timeOfDay.

Typical usage of the query looks like

exec CreateBackupJob @databaseName='MCTDb'
    , @ftpServer='example.com'
    , @ftpUser='UserName'
    , @ftpPassword='Supersecret'

When you obtain this script, I recommend modifying the script when you create it on a server to have give the ftp parameters default values, if that makes sense in your environment. That can save you time when creating new backups.

You can download the full script here. This script will drop (if they exist) and recreate all three stored procedures I mentioned. Let me know if you found this useful.

Download it from http://tools.veloc-it.com/

sql comments suggest edit

This is another useful Sql Server Stored Procedure I found on the net written by Nigel Rivett.

The procedure uses the xp_cmdshell extended stored procedure to shell out an FTP command. You can use this procedure to ftp a file from one place to another. Of course, you will need to make sure that your command runs in the proper security context.

I made some very slight modifications in my own version of this procedure. I changed some of the parameters to be of type nvarchar instead of varchar for my international friends. I also changed the name to suit my own naming conventions.

It takes in the following parameters.

Parameter Data Type Description Example
@FTPServer varchar(128) The host name. ftp.example.com
@FTPUser nvarchar(128) The username for the FTP site. Haacked
@FTPPWD nvarchar(128) The password for the FTP site. Ha!_AsIfIWouldTellYou!
@FTPPath nvarchar(128) The subfolder within the FTP site to place the file. Make sure to use forward slashes and leave a trailing slash. /
@FTPFileName nvarchar(128) The filename to write within FTP. Typically the same as the source file name. ImportantFile.zip
@SourcePath nvarchar(128) The path to the directory that contains the source file. Make sure to have a trailing slash. c:\projects\
@SourceFile nvarchar(128) The source file to ftp. ImportantFile.zip
@workdir nvarchar(128) The working directory. This is where the stored proc will temporarily write a command file containing the FTP commands it will execute. c:\temp\

Here is an example of the usage.

exec FtpPutFile     
    @FTPServer = 'ftp.example.com' ,
    @FTPUser = n'username' ,
    @FTPPWD = n'password' ,
    @FTPPath = n'/dir1/' ,
    @FTPFileName = n'test2.txt' ,
    @SourcePath = n'c:\vss\mywebsite\' ,
    @SourceFile = n'MyFileName.html' ,
    @workdir = n'c:\temp\'

I will soon combine this and my random time of day generator sql into a very useful stored procedure for you.

sql comments suggest edit

Here is a function that will generate a random time of day. Later I will show why I am posting this particular query and how I am using it. It comes in useful when trying create random scheduled jobs in SQL Server. I made use of a technique for generating random dates via Jon Galloway.

Parameter | DataType | Extra | Description ————|———-|————-|———— @timeOfDay |int |OUTPUT | Represents a time of day using the format HHMMSS. For example, midnight is represented as 0 and 1:52:01 PM is represented as 135201. @maxHour |int |Default = 24 | Upper bound for the hour of the day. So to generate a random time of day between midnight and 3 AM, specify 3.

Here is an example of its usage.

-- Generate time of day between midnight and 3
DECLARE @timeOfDay int
exec GetRandomTimeOfDay @timeOfDay OUTPUT, 24
PRINT @timeOfDay

And here is the stored procedure declaration itself. Notice I am creating this procedure within the master database.

USE [master]
GO

CREATE PROCEDURE [dbo].GetRandomTimeOfDay
( 
    @timeOfDay int = 0 OUTPUT
    , @maxHour int = 24 -- Upper bound for the hour.
)
AS
BEGIN
    IF @maxHour > 24 OR @maxHour < 1
        RAISERROR ('Choose value between 1 and 24', 16, 1)   
    
    DECLARE @randomHours int
    SELECT @randomHours = 
        (@maxHour - 1) * 
RAND(CAST(CAST(newid() as binary(8)) as INT))
    
    DECLARE @randomMinutes int
    SELECT @randomMinutes = 
        60 * RAND(CAST(CAST(newid() as binary(8)) as INT))
    
    DECLARE @timeOfDayDate DateTime
    SET @timeOfDayDate = '00:00:00'
    
    SET @timeOfDayDate = 
DATEADD(hh, @randomHours, @timeOfDayDate)
    SET @timeOfDayDate = 
DATEADD(mi, @randomMinutes, @timeOfDayDate)
    
    DECLARE @timeAsString varchar(8)
    DECLARE @timeWithoutColons varchar(6)
    
    SET @timeAsString = CONVERT(varchar(8), @timeOfDayDate, 8)
    SET @timeWithoutColons = REPLACE(@timeAsString, ':', '')
    
    SET @timeOfDay = ( CAST(@timeWithoutColons as int) )
END
GO

In a later installment, I will show you why this is useful.

You can download the SQL in a zip file

comments suggest edit

Section of Adam's
Design

Adam Kinney recently unveiled a redesign his blog. I posted a snippet there to the left.

Adam is one of those rare developers who has both solid design skills to complement his solid coding chops. In other words, he makes me sick, rubbing our absolute lack of design skills in our faces.

It is overall a pretty sweet design. The layout is clean with a crisp headline. My only niggle is the styling (or lack of) of the Recent Entries list. Just a little more CSS will go a long way there.

Keep up the good work, man.

subtext comments suggest edit

I noticed the following checkin message in the subtext commits mailing list today (this is the mailing list in which we can receive Subversion checkin notifications).

Revision: 999
Author:   simo
Date:     2006-04-21 13:56:27 -0700 (Fri, 21 Apr 2006)
ViewCVS:  http://svn.sourceforge.net/subtext/?rev=999&view=rev

Log Message:
-----------
The link to Phil Haack blog was wrong 
(https://haacked.com/blog) Fixed it.

-- SNIP--

This had me cracking up because I am the one who added the link to my own blog originally. It took someone else to notice the mistake and fix it. An inability to link to oneself correctly. Is that a recognized form of dementia?

Tags: Subtext

comments suggest edit

I recently moved my blog off of WebHost4Life where I have had it hosted for a couple years now. Apparently the traffic on my blog was causing a load on their servers. I never fully believed it was my blog’s fault since they didn’t give me any convincing evidence.

In any case, it is a fitting time to move it to my company’s dedicated server (at 1and1) and my blog is now blazingly fast compared to before. I figure rather than paying WH4L for hosting, I might as well pay my own company for the privilege.

I switched DNS over and so far no problems. In case you are wondering, I use ZoneEdit.com for my DNS servers. They are a free DNS provider and I have not had any problems with them at all. Very simple to set up and use.

The key benefit of having all my DNS over there is that everytime I change hosting provider, I don’t have to change the root DNS servers at my Domain Registrar.

Since I have already paid for a year at WH4L, I will probably set up a Subtext blog for my younger brother and some of his friends there.

comments suggest edit

Chinese Character for
Money Jeff has a great post in which he compares UML to circuit diagrams and then asks, why doesn’t UML enjoy the same currency for software development?

In the comments Scott Hanselman makes a great point…

It’s because, IMHO, UML isn’t freaking obvious. It’s obtuse. What’s the open arrow, open circle mean again?

I think he is spot on. But you could also say that about any programming language, right? What is that colon between the two words mean?

public class Something : IObscurity<-- What the heck is that?
{
}

If you are a VB programmer, it might be unfamiliar. But if you are a C# programmer my question is like asking what is that funny curly line and dot at the end of this sentence? Oh that’s an interface implementation silly. Of course!

Don’t get me started on C++ with its double colon craziness and its @variable and variable* which leave the befuddled developer asking what exactly do they mean?

Isn’t UML a Decent Abstraction Layer?

The evolution of software has been a steady stream towards higher level abstractions. We no longer punch holes in cards to represent computer calculations in binary (at least I hope not). As a managed code developer, I don’t even have to worry about allocating memory (malloc anybody?) before I use code…Glory be! So doesn’t it seem natural that UML would be the next evolutionary step in that chain?

Umm…Well no.

The most successful widespread abstractions are those that abstract the underlying computing architecture, which itself is abstract. Memory, for example, is pretty the same thing to everybody, no matter what kind of software you are working on. If the machine can handle allocating and deallocating it for you so you don’t have to think about it all the time, then all the better for everybody.

But that same principle doesn’t work as well when we start raising the abstraction level to cover our real world concepts. The next obvious level of abstraction are domain classes. How many times have you written an Order class? I’ve written one. Great! Since I did the work, I can simply post that baby on SourceForge and save the rest of you suckers a bunch of time. Now anybody can simply just drag the UML representation into their UML diagrams and bam!, their Web 2.0 revolutionary microformatted shopping cart application is complete. Sit back and watch the flood of money flow in.

If only it were that easy.

Make a Wish

Evil Genie It would be nice to be able to work with such high level abstractions and wire them up. Oh, here, I’ll just draw a line from this order to the shopping cart and boom! when the user clicks this button, the item goes into the cart. But what about the various business rules triggered around adding this order to the cart? What about the fact that the cart lives in another process on a separate server and the order needs to serialized? What about the persistence mechanism? How do you express that in UML?

You can’t. Writing code is like asking an evil genie for a wish. No matter how carefully you craft the wish, there is always some pernicious detail left out just waiting to jab you in the eye. I wish I were rich and now I am some poor slob named Rich living in abject poverty. There are just too many moving parts and pitfalls in a piece of software to deal with and worry about.

UML has a bit of trouble capturing the semantics of code. Like snowflakes, no two Order classes are alike. Every client has their peculiar and idiosyncratic ideas on what an order is and how it should work in their environment. So what do we do? We start encumbering UML with all sorts of new symbols and glyphs so that we can work toward a semantically expressive UML (executable UML anyone?)

But this just turns UML into another programming language. The fact that it is in a diagram form doesn’t make it any more expressive than code. In a way, adopting UML is like changing from English to Chinese. Sure a single Chinese character can represent a whole word or even multiple words, but that doesn’t make it any easier to grasp. Now, you have to learn thousands of characters.

Not to mention the fact that you are writing the same code twice. Once by dragging a bunch of diagrams around with a mouse (how slow is that?) and again by writing out the actual compilable code. Granted, that particular issue my be solved by executable UML in which the model is the code. But that suffers from its own range of problems, not the least of which is the huge number of symbols required to make it work.

What is UML Good For?

Now to be fair, my criticism is about formal UML and UML modelling tools such as Rational Rose. If you are prepared to run wild and loose with your UML, it can be useful at a very high level as a planning tool. I sometimes sketch out interaction diagrams to help me think through the interactions of my class objects. That is useful. But I rarely keep these diagrams around because hell will freeze over before I waste a bunch of my time trying to keep all of them up to date with the actual code. The code really is the design. The only diagram potentially worth keeping around is the very high level system architecture diagram outlining the various subsystems.

comments suggest edit

So after a few humiliating losses (in both soccer leagues I play in), we finally have a convincing win last night (5 to 2) in the Olympic league (the more competitive one). I even had a goal off of a dangerous cross that the defender tried to stop, but ended up deflecting it into the goal.

Hey, I’ll take what I can get.

comments suggest edit

DibsI love working with other developers who are really excited about technology and the work we are doing. As is characteristic of such an organization, there is a constant flurry of IM messages and emails with links to interesting new technologies and topics.

This is nothing new of course, except for a recent phenomena of calling dibs to blog these topics. Is this something that happens to you? Let me give you an example.

A little while back, Jon Galloway IMs me a link to this very cool tool to remove source control bindings from a VS.NET 2003 project.

Immediately I start firing up w.Bloggar when his next IM message comes through, Oh, by the way I am going to blog that. He called dibs on blogging it.

This doesn’t mean that he owns this information somehow. Certainly there are others who have blogged about it. But I do feel it is good form to defer, since we probably have a similar readership. To that end, I present the rules for calling blogging dibs, which have their roots in concurrent software development.

  • Dib Contention: In conversation, if the person (the originator) who mentions the interesting link or story (the content) does not call dibs, and another person does, dib rights are lost to the originator.
  • Dib Wait Condition The listener must give the originator a reasonable moment (a pause really) to call dibs. Afterwards all bets are off.
  • Dib Hijacking In IM conversation, the originator has exactly one message (or 30 seconds) after the content to call dibs. If the next IM message is off topic, the other party may call dibs at any time..
  • Dib Deadlock Resolution Tie goes to the originator.
  • Implicit Dib Call In the absense of a dib call, it is assumed the originator has dibs until some point it is taken away by an explicit dib call.
  • Dib Race Condition If the listener can write and post the entire blog post before the originator calls dibs, the originator loses dibs privileges for obvious reasons.
  • Dib Access Violation Violating another person’s dibs right loses the offending party’s dibs rights for a period no less than two weeks.
  • Dib Timeout Condition A dib has a shelf life of one week. If no blog post is forthcoming, dib rights are fair game.
  • Dib Finalization Once the originator has written a post. The listener may follow up. It is good form to link to the originator’s post.
  • Keep dibs in the freezer, or they melt.

So go out there and steal someone else’s thunder. But do it according to the rules.

I violated one of my own rules. Can you figure out which one?

comments suggest edit

CoComment Logo My blog now supports CoComment tracking. Let me know if you run into any problems with posting comments.

As I mentioned earlier, I added CoComment to Subtext as an administrative option. I am running the latest build from our Subversion repository. What better way to hash out bugs than to dogfood your own code. And man, was I eating some chow last night and this morning. I think I teased out most of the pressing bugs and my blog is pretty stable right now. Whew!

I performed a live test of automatically upgrading the schema and stored procs via the new web-based upgrade wizard in Subtext. That was really cool. When I was done, it looked like all my blog posts were gone. I nearly splattered my eyes on the monitors. But that was simply a UI glitch caused by hitting the site while files were still being copied over.

subtext comments suggest edit

Subtext Logo Steve Harman reports that Subtext reached 1000 downloads just recently on SourceForge.

That is pretty sweet news. I sort of wish we added some code that asked permission to ping us when someone installs Subtext, but as you can imagine that would be very low on the totem pole of requirements.

We are getting close to a bug fix release that contains some extra goodies. I will set a release date soon. I have just been overwhelmed with work and other events.

Tags: Subtext

comments suggest edit

Joel Spolsky totally nails it this time with his article on the Developer Abstraction Layer. This is one of his better articles. It is a tad on the long side, but well worth the read. Try to get it in your manager’s hands.

With a software company, the first priority of management needs to be creating that abstraction for the programmers.

If a programmer somewhere is worrying about a broken chair, or waiting on hold with Dell to order a new computer, the abstraction has sprung a leak.

In summary, a development company is a lot more than the developers. In fact, it is a huge support organization designed to remove abstractions for the developers so they can let the magic happen. Beautiful.

comments suggest edit

If you are seeing duplicate posts from my blog in your feed aggregator, my apologies. I am dogfooding the latest development version of Subtext straight from the Subversion repository. Unfortunately, my unit tests did not catch the fact that I changed the link and guid elements from fully qualified to virtual URLs.

Doh!

I should have a fix soon.

UPDATE: All fixed. Sorry for the brief disruption.

comments suggest edit

Rainbow Eric Ramseur who works on the Rainbow 2.0 Portal project looks like he has made progress inimplementing Subtext as the blogging module for Rainbow. That is pretty sweet.

I have to admit I do not know much about the Rainbow system other than it is a Content Management System written in C# with versions for ASP.NET 1.1 and ASP.NET 2.0. It definitely bears investigation to see how it compares and contrasts with DotNetNuke.

I am definitely interested in seeing how easy (or not) it is to integrate Subtext into another system. One thing I have been working on when I have time is to refactor Subtext to clean up some code and make it easier to understand the source. As a team, we also hope to make the codebase even more modularized. This stuff is fun.

comments suggest edit

Red Paperclip This is one of the most ingenious methods of self promotion I have ever seen. Not to mention an interesting way to obtain a house.

Mr. Galloway sent me this link to a guy who is trying to trade a red paperclip for a house. Well not directly. He is attempting to negotiate a series of trades. In each trade, he attempts to get something of more value than the previous item. In the end, he hopes to trade for a house.

It sort of reminds me of the way you teach people about exponential growth. Start with a penny on day 1. Double it every day. And at the end of the month you are a multi-millionaire (unless it is February).

But of course, this is not exponential growth in the true sense of the word. Really, it is a demonstration in some small part of how wealth is subjective. The value of an item is really dependent on the value the people involved in a transaction see it. In a good trade, both parties are become wealthier because they both received something of more value to them than the item they gave away. Otherwise they wouldn’t have made the trade in the first place.

The other lesson may be a demonstration of how much people will give to be a part of something public. Just like reality television. In some small way, as his site makes the rounds, these people get their 15 minutes of fame.

In the end, when this guy receives his house, it will be remarkable to compare that house to the value of the paperclip. But the value of the publicity and of taking part in this interesting experiment may make the red paperclip quite valuable to the two women who received it. Of course this guy will be the biggest winner of all for his ingenuity.