Hanalei, Hawaii 9/2/2010
438 Posts and Counting

Crazy Talk: Inline Scripting Revisited (Or, 2003 Bites Back)

Tuesday, February 05, 2008 -

A few months back, right before I was hired by Microsoft, I knew people wouldn't look kindly on the forthcoming ASP.NET MVC Framework and it's support of Inline Scripting. As part of my community effort I decided to take this issue on a bit and try to remind people that inline scripting on it's own isn't spaghetti code - it's the code itself.

As I always say - spaghetti is as spaghetti does.

Last night I had a fun (not really) experience, and for me it's thrown a whole new twist on what Inline Scripting and Maintainability mean. Code Generation and an old toolset don't add up to a fun maintenance issue...

 

Knock Knock Rob, it's 2003 Calling
I worked on a pretty nice site back in 2003 when I was in love with CodeSmith and Extreme Code Generation. I had this Killer Set of Templates that I could rock out a full-blown scaffold with (before it became a household control in .NET), and I used them to create the admin section of said site.

I won't dive into the details, suffice to say it works and I'm not very happy with why. It was an admin site and I reasoned that I didn't need to worry about perf (which is true). The code was readable, easy to follow, and while I could have/should have refactored it to be less verbose, I liked that I could rev the DB and then generate the code - this process was simple and Grampstimely.

Ahem. Yes I know.

The site has worked great for the last 4 years, until today. Strange how these bugs can lie dormant for so long! I'd never had this happen before and the bug was pretty stupid.

In short, the site is for a Venture Capital company and the DB holds all kinds of "people info" - teams, groups, etc. The groups haven't changed at all over the last 4 years - until 3 days ago.

The admin for the site decided to add a group for a company they acquired, and when she went to the admin tool it exploded - complaining that the Data Table I was using wasn't mapped properly. The templates I created used the built-in DataTable.Update() support so I could work with any DB Provider - unfortunately if they don't map to your scheme precisely, you'll have a bug on your hands.

Oops. I changed the schema back in 2004 and forgot to regenerate my Code Page it seems. Bad Dev.

 

And The Feeling Of Dread Creeps Over...
The admin person was very nice - sending me an email that I take a look at the problem. That night, when I got home I fired up VS, grabbed the source from my Subversion server, and set about fixing the issue.

It's .NET 1.1. Uh Oh. Forgot about that...

I don't have VS 1999 (or whatever version that was) anymore and I don't know where that CD could be. Crap - I knew I should have held onto that! Frantically I think of all the PCs in the house (laptop, old box in the garage) and where/how I can install 1.1 so I can work on this site.

As I start to weigh the time up (finding and installing 1.1, getting the site setup, and redeploying) I start to think sideways (it's how my brain works) and I realize:

I only need Visual Studio so I can compile the dang solution - I know how to run "csc"... I can do this without it!

But I don't have .NET 1.1! It's easy to get - but now I have to install it and reboot and if I get errors this is going to take me a very, very long time tonight and I want to watch Lost! This is getting out of control...

I think about converting the whole thing to .NET 2.0, but this is a no-go as the hosting account is set to 1.1 and I don't want to deal with that. So I restate the problem to myself - this helps me from doing stupid stuff to solve a minor issue:

You simply need to add one line of code to account for the DB schema change.

There's no way I'm sitting here partying with VS 1999 and .NET 1.1 so I can accomplish a single line of code change. That, my friends, is a maintenance issue (and yes, it's my fault).

 

Sir, The Wall's Too Tall! No Problem, We'll Go Through It!
As I restate the problem to myself, it becomes clear that the only thing in my way here is the mechanism itself: fix the code and recompile. The only reason I'm installing these tools is to recompile - so let's remove that step from the equation so I can now fix the problem.

I moved all the code from the codebehind page, pasted it between <script runat="server"> tags, and then reset the @Page directive to not inheret anything. Took me 5 minutes: I made the fix, and FTP'd it up. Done.

It reminded me of my last post on the inline/codebehind debate, and one of the comments I received:

"I think inline script blows...No thanks. I think it's a very bad idea. Cleaner and more manageable? You must have been drunk when you posted this."

It may indeed blow, but it just saved my bacon :).

 

Summary and The Obligatory Hedge
I know this isn't an issue with ASP.NET 2.0, and yes I know that I should have been a LOT more careful with my Code Generation. But as I've been writing this I've been chuckling at the things I did back then (don't we all?). I loved Code Generation - to me it saved so much time, and I could be pretty certain that bugs were mitigated since I didn't handcode the stuff. I just had to remember to do it!

I'm not telling you to use Inline Scripting - I just found this to be very, very ironic since many people believe your application is "less maintainable" if you use it. Not in this case my friends :).

I spose the moral of the story is to always view the concept of maintenance with an eye towards shifting toolsets and platforms. In 4 years you will need to support the ASP.NET 2.0 site you're on now, using Visual Studio 2012 and it's Silverlight-generated Scaffolds :).

You may not want to go running through the house looking for VS 2005 and hopefully you won't have to since 2008 supports 2005 projects - but will VS 2012? Notice that 2005/2008 doesn't support 1.1...

And finally, while you may be thinking I'm a complete hack :), think back to what you did in 2003...

Related


Gravatar
Craig - Tuesday, February 05, 2008 - oh I've lost the actual code for a compiled 1.1 site - which still runs today, takes a lot of dns hacks to keep the email for it working but that was pretty stupid :) (stolen laptop bad backups! :))
Gravatar
Chris Brandsma - Tuesday, February 05, 2008 - I'm one of those who is generally against in-line code, mostly because it is harder to automate tests for. Plus, I also graduated from the ASP days of hell (and I'm not going back!). But with the MVC Framework I have to redefine my thoughts. Currently my philosophy is like this: no in-line business logic! But I think that is mostly a given with the framework forcing some separations of concerns. I still have two lingering concerns though: 1. How do you debug in-line code. (please don't say alerts) 2. How bad will with affect code readability. That was 90% of the issue with old school ASP, with HTML, JavaScript, and VBScript all running around in the same code file things got real messy in a hurry. That said: I do miss being able to perform a quick fix without much hassle and be done with it. Finally: you should be using Virtual Machines (have a 2003 dev image), and a lot of my concerns would be fixed by a good UI tester (Watir, Watin, Selinium) -- but those are a lot of work as well.
Gravatar
Rob Conery - Tuesday, February 05, 2008 - @Chris - you can debug by simple setting a break point in the page. I know I know - I have a whole mess of them sitting around. In this case I didn't have one with 1.1 and one of these days I'll make one called "2003" :). Time capsules!
Gravatar
Shawn Oster - Tuesday, February 05, 2008 - It's funny, just today I was able to quickly fix an old classic ASP site in about 5 minutes and my buddy turns to me and says, "Man that must have been nice, if it would have been our other site (.NET 2.0) that would have meant a full re-gen and deploy." I've also experienced that feeling when while at the in-laws I got a frantic call about a site that was misbehaving and after a simple ftp and notepad from their aged and definitely not developer friendly PC I was able to get it running again. I still have to maintain a lot of PHP and ASP sites and while I do miss the nice structure of the Visual Studio world it is amazingly refreshing and "simple" to work on those old sites. They are fairly well chopped up into include files and I even have some nice fake BLL/DAL layers so it's not too much spaghetti code. Every once in awhile I wonder just what I'm actually gaining by using ASP.NET. Of course I do gain a lot, such as membership providers, better caching, IntelliSense and speed but I've found myself using more and more inline code these days, if I can't fix it with just FTP and notepad then I start to get a little nervous.
Gravatar
Justin - Tuesday, February 05, 2008 - I've run into this issue before when wanting to update a clients site (that I had never worked on). SharpDevelop is probably what you were looking for. Just open up the project and make sure it's set to compile in .net 1.1 http://www.icsharpcode.net/OpenSource/SD/
Gravatar
Steve - Tuesday, February 05, 2008 - Good post Rob, actually, very thoughtful of you to take that code inline :) On a side note, I've switched most all of my big ugly GridViews to using repeaters in conjection with jQuery table's. I've used a minimal amount of inline code, mostly for binding purposes (static page functions and one page method that I use for a ajax call from jQuery until I get it moved over to using jayrock). What I like best is that it has made me think more about using my middle tier to construct the data to be applied to the UI, minimizing the amount of code in the UI (most all of it now is javascript only) By the way, the move to jQuery and Repeaters was a first step toward migrating my code to MS MVC - I use no postbacks in this particular code base. Why do all this? I've been using webforms since day one, and at first it was a godsend, but as time has gone on in my web development days, webforms are a pain in the butt to use when a page requires any amount of complexity. It was a great joy to return to a no-postback web application :) It's easier today as well with the good javascript api's available (I'm hooked on jQuery right now). Off topic now, but good post :)
Gravatar
Ray - Tuesday, February 05, 2008 - After ensuring you had the 1.1 framework installed, you could have just loaded the solution into VS2005 (not sure about 2008), upgraded it, and used MSBee to target 1.1. I support a mixed bag of 1.1 and 2.0 stuff in my job and it's extremely nice to have everything in a single development environment while still accomodating the older framework version. Check it out: http://www.codeplex.com/Wiki/View.aspx?ProjectName=MSBee
Gravatar
southwo8 - Tuesday, February 05, 2008 - The quick "edit-and-ftp" scenario is something I actually often miss from my PHP days. I like ASP.NET a lot (especially with the new MVC stuff coming) but PHP has always felt simpler in that regard...
Gravatar
Rob Conery - Tuesday, February 05, 2008 - @Ray: Indeed there are a number of solutions - my issue was the voice in my head saying "one line of code..." over and over and over. All that work for 1 line of code is silly :).
Gravatar
Josh Stodola - Wednesday, February 06, 2008 - I've been waiting for this for post for... 3 months now (nice blockquote you got there, LMAO). WTF took you so long? I guess inline script does have a purpose (saving your bacon).

Couldn't you potentially do the same thing without inline script by not pre-compiling your site? Obvious perf hit, but isn't it possible?

"VS1999"- that was effin' hilarious!
Gravatar
Joe Chung - Wednesday, February 06, 2008 - http://www.codeplex.com/Wiki/View.aspx?ProjectName=MSBee

Then you could have made your one-line code change, used MSBuild with .NET 1.1 targets to rebuild the solution, and deployed the updated DLL's and markup files. No "Visual Studio 1999" (Visual Studio .NET 2003) required. Actually, no Visual Studio at all required if you're comfortable executing MSBee from the command line.
Gravatar
Damien Guard - Wednesday, February 06, 2008 - Personally I've found that two different approaches are required: Single-customer sites (Web sites) These are entirely proprietary, contain business-specific content in the pages and need to be maintained/hotfixed without causing the site to restart. Use the "web site" solution in VS, let the server compile the .cs/.vs files and FTP/WebDav updates across. Basically an evolution of the web site to add dynamic and editable elements/database support and the concept of version numbers is vague. Multi-customer sites (Web applications) Non-specific generic sites that are tailored through parameters. The "web application" solution in VS, deployed to customers through a proper test/release cycle and sent out either as an MSI, ZIP or other complete unit every time a change is made. .vs/.cs files are compiled into the binary and not shipped to the client. An evolution of software applications utilising a web interface. Shame VS 2003 did not support both models and it took until 2008 to get it in the box. Let's hope Microsoft makes it clearer what the two types are for. [)amien
Gravatar
Jarle Nygård - Wednesday, February 06, 2008 - We'll be using Virtual Machines to do debugging/hotfixing/servicing of old code. So we'll have one machine for our 1.1 releases, one for our 2.0 release and whenever we move beyond we'll create more new machines. They boot up in a few minutes, the code is already there and the environment is good to go. Pretty handy!

I know, this was not the point of the post at all, but I just _had_ to mention it. :) Anyways, pretty good solution you came up with in the end and; yes, inline scripting can save your bacon. But then I don't much like Norwegian bacon, I prefer Danish... ;)
Gravatar
Jorge Diaz Tambley - Wednesday, February 06, 2008 - I once read that you should put everithing you need to compile your project under version control.... now I see what they meant... I also use the VM way of doing things..... it all began when I had to many versions installed at the same time for different projects/customers Regards
Gravatar
Kirk Jackson - Thursday, February 07, 2008 - I know that feeling! In the past, I've resorted to ildasm / ilasm to add a single line of code to a dll with no source :) Kirk
Gravatar
Dimitri Stoikof - Thursday, February 07, 2008 - oh virtual machines is a good trick! how many days i've wasted getting old code to run again with databases, project files and specific folders needing to be set up! Thanks for the tip Jarle!
Gravatar
Serg - Thursday, February 07, 2008 - Actually I compile my 1.1 projects with NAnt. It supports VS2003 solutions and it is much faster than run VS2003.






Output file doesn't exist in ${expected.output}


That's it!
Gravatar
Serg - Thursday, February 07, 2008 - Ooops. it stripped tags

<target name="build.winforms">
<solution configuration="${configuration}" solutionfile="HelloWorld.sln">
</solution>

<property name="expected.output" value="HelloWorld/bin/HelloWorld.exe"/>
<fail unless="${file::exists(expected.output)}">Output file doesn't exist in ${expected.output}</fail>
</target>
Gravatar
Adnan - Monday, February 11, 2008 - I had the same exact experience with 2003/2005. I was suprised to read theat 2003 is not supported on Vista (whatever that means). My development environment have completely changed from 2003 days (2003 XP) to 2005 (Vista). I cannot debug the application now and have read pretty much the entire web to see if I can debug the app. I did setup the 2003 after 2005 and had to install ii6 compaliblity, IIS7 and much much more. I really think all studio environments should be backwards compatible. May be 2003 to 2005 was bug change but ging forward I would like to see this because I really don't want 2003, 2005, 2008, 2010, 2011, and 2011.5 installed on my machine.
Gravatar
brad dunbar - Tuesday, March 04, 2008 - First off, I LOVE inline code. I think that there is no easier way to manipulate html than to have it directly alongside my C#, and if you're being clever about stylesheet usage, the bloat is minmum. In fact, I often think of writing a visual studio addin to take this farther, adding html to C# code, which I think would be a beautiful endeavor. That being said, I almost never use inline scripting. Why? Because there is no refactoring or compile time error checking support, and when my project gets large enough that I can no longer remember all the places I've written inline code (and it will, because it always does) I'll inevitably change a variable/property name using Right Click -> Rename, and my inline script is broken. To me, this makes inline code utterly useless. I cannot ensure that errors will be caught, so I move everything to the code-behind. Is compile time support just too big to be implemented, or is it just not done that way? I know that this is a little off topic, but its something I've often lamented about Visual Studio. What do you think? -brad