Monday, October 15, 2007 -
As if I haven't been flamed enough in the last few days (and I still have a few minutes left on my Fire Ward), I'm going to challenge the notion that Inline Scripting is a relic of Web 1.0, and that it has no place in today's ASP apps. I take a slightly different view, and that is that many times inline scripting is preferable because it forces you to write less UI code, decreases ViewState abuse, and can result in cleaner, more manageable HTML.
Inline scripting gets a bad wrap in the ASP world. Many people avoid it like the plague and you're branded as a "Spaghetti Hack" who "codes like it's 1999". I've stared, open-mouthed, at these words in the SubSonic forums as people have questioned my preference for inline scripting. I've been meaning to write this post for a while, and this weekend I've finally had the chance since the inlaws are in town :).
I like what Atwood has to say about it:
After religiously adhering to the new, improved code-behind model of ASP.NET for so long, I have to admit it's sort of refreshing to rediscover inline code ASPX pages again. Deploying single web pages to a server without recompiling the entire solution? Making localized edits to single pages that take effect in real time? A single file that contains both code and markup in one convenient self-contained package? Revolutionary!
but then he finishes with this:
Unfortunately, Inline ASPX pages also remind me of some things I didn't miss from the bad old days of ASP programming: spaghetti code, extremely limited intellisense, and crappy debugging
That post was written in 2005. Today, however, with Visual Studio and ASP 2.0, we now have great debugger support in the designer and intellisense so that mitigates a lot of concerns that people have. In terms of Spaghetti Code...
Spaghetti Code
It's not easy to write spaghetti code using .NET, but there are many who manage to do it. From Wikipedia:
Spaghetti code is a pejorative term for source code which has a complex and tangled control structure, especially one using many GOTOs, exceptions, threads, or other "unstructured" branching constructs. It is named such because program flow tends to look like a bowl of spaghetti, i.e. twisted and tangled
So Spaghetti code makes it hard to understand what an app is doing during execution. I think this is more a function of what ASP's CodeBehind model allows you to do, versus the concept of "scripting the UI". Spaghetti is as Spaghetti does...
In purest terms, scripting the UI should literally be a visual expression of logic, NOT the logic itself. To that end, simple, VERY SIMPLE routines in the UI are acceptable (and needed) when scripting. This is an important aspect of this discussion: Logic does not belong anywhere near the UI!
Rails has some neat guidelines to follow when working up their views:
To dive into this further, let's use the ubiquitous GridView example. For fun, let's see what it takes to do something simple, like link to an editor page from a grid. I'm using Northwind, SubSonic, and ASP 2.0 Web Site for this example.
GridView with ObjectDataSource, bound to Products.Fetchall() - a BLL method
The designer makes this trivial- I just hook up the ODS to ProductController.FetchAll() (using SubSonic) and I'm well on my way! Not one to be fooled by a designer's simplicity, let's take a look at the markup:
Let's hook up the select events. Here's the code:
Now let's do the same thing using inline-scripting (the Controller in this example is my BLL):
So consider:
I need to keep my HTML and Code Separate
Why is that anyway? Designers use Photoshop, and think in terms of PSDs. Designers don't use Visual Studio (I think it's a rule in SOMA that you have to turn in your Mac if you ever look at the Visual Studio's Medusa Glare [the white screen of pain when it stalls]).
You might be one of the lucky people on the planet who's workplace hires an HTML gunslinger (I've worked on 3 projects like this). These guys are usually the mock turtleneck-wearing guys who hang out by your desk trying to learn to code :). These guys know Visual Studio, but also know "runat=server" and "<%" means "don't touch".
Inline Scripting Is Slower
Not at all. From Jeffrey Palermo:
My colleague insisted that script block incur and extra performance hit because the ASP.NET engine must check for changes in every page hit. After lunch, I whipped up a test and created to ASP.NET pages: one with code-behind, and the other with the code in a script block. I ran each for 1 minute in WAST. Then I ran each 8 more times. My results: It doesn't make a hill of beans difference. Each test was less than 1% difference
Inline Scripting Is Ugly
If you ask me, XML is ugly. Code is wonderful. I can read code easily and I (usually) can grok what was intended, Declarative markup (which is XML-based) just sits there, telling me nothing. This is subjective anyway and you can always toggle script blocks shut.
Only Hacks Use Inline Scripting.
Could be true, but if you take a second to look over the walls of the MS Schoolyard you'll see the kids playing with all kinds of code-based markup. Rails, PHP, Django - all use this style of programming. It's effective, and actually breeds LESS code (see below). The most popular platforms in the world... I'm hoping you're at least considering this by now...
Here's a virtual beer :). We'll make it through the rest of the post together...
Inline Scripting Breeds Crufty Pages That Are Hard To Read
It absolutely can, but often the issue is not with scripting as a practice, it's with the developer's coding style. Spaghetti is as Spaghetti does. If you drive yourself to rip out any logic from your UI, scripting becomes enlightening and fun.
If you're a Server Control Junky (use Image Controls, Hyperlink Controls, etc) I would ask you to consider whether the use of these controls (when not using skinning or required eventing) is warranted. Consider the Page Life Cycle:
Generally, this stuff is pretty quick and you don't need to worry about it's execution. But if you don't need it to run at all, why do it? I'm not saying server controls are evil - I'm saying you should carefully consider whether they're needed.
With code behind, you get a big rug that you can sweep your code under. It can lead to bad habits (like too much code) and also cause slow downs that just aren't needed.
CodeBehind 2.0
I think it's time to lean harder on the notion of UI scripting as just that: visually representing logic. CodeBehind is (most of the time) overkill for this . When .NET was introduced this seemed like the way to go (cause they told us it was). Now that it's 5 years later, it's time to revisit this notion - especially in light of the new MVC framework that's right around the corner.
Do you really need two pages, when one will do just fine?
By the way, in your code example you compare apples with oranges: instead of using the "SelectedRow" event you should use an "ItemDataBound" event to create the hyperlink. This would be more or less the equivalent to your Inline Scripting example.
One final think: I love subsonic, keep up your great work!
Joris
Thanks,Megha
Sure, inline scripting just made it easy to mix the two, but ASP.NET did a decent job of making the separation more clear.
But again, there's nothing wrong with putting presentation logic as inline script.
After all,
">
isn't really (except for the data binding) different from
They're just alternative template syntax for the same thing.
<asp:Literal id="x" runat="server" Text="<%#Foo %>">
isn't really any different from
<%= Foo %>
except for more typing. They can both be considered alternative syntax for the same result.
was trying to
[quote]
These guys are usually the mock turtleneck-wearing guys who hang out by your desk trying to learn to code :). These guys know Visual Studio, but also know 'runat=server' and '
just wanted to say that about 3 months ago I found my self on the code-behind side of this argument (against a PHPer)... started digging into monorail recently and find that every view I script is pulling me the other way.
Good post :)
No thanks. I think it's a very bad idea. Cleaner and more manageable? You must have been drunk when you posted this.
In your example, what would you do about an edit or delete button?
Best regards...
# 2 - I don't agree. YOU might know what your GridView control is doing, but it's presence doesn't convey anything. Walking the "eventing path" leads devs to lean on grid events and the "OnItemDatabound" morass (see comment above) that really makes spaghetti yummy.
# 3 - so what's the point then? Why use the control?
# 4- I "Lose refactoring"? Nah - if I've done my layout right then I have a lot more flexibility with than the WebForm way.
I've not given up any maintenance - I've gained it. Please see my point where mention that scripting is layout only - any UI logic belongs in a centralized "helper".
"Also, I would argue that in this case the handcoding method is more likely to lead to html errors and other logic issues"
Can I get you some more KoolAid :):):)? If anything, HTML spun out by Render() methods (which is completely out of my control) is *questionable* - but that's a debatable point entirely. My overall point is that server controls abstract the HTML put out - I don't like that.
Finally - Server controls are code, and just another place that an error can crop up. The Load() event in a GridView, for example, is a complete nightmare to debug. Ever seen the empty GridView and wonder "where's my data???"
Server markup is NOT HTML. It's declarative coding.
"Plus, markup can be huge and the indentation gets ridiculous" - if you do it poorly, sure. Do you validate the HTML that a GridView puts out? Care to comment on that?
"No thanks. I think it's a very bad idea. Cleaner and more manageable? You must have been drunk when you posted this."
Yah, I was having a beer while you were in the back room with your bong :). Needless whitespace? And the ViewState is what? And you're worried about your source view?
In terms of Buttons - i'm not sure what you're asking but I don't put them in grids; I use links. If I need to use a button I usually do HTML button. You remember how to do that right?
I should note that as I reread this comment - I'm having some fun with it :):):). See the smilies :). I do appreciate your thoughts...
So, I hope that statically typed data binding is what we need. Even with MVC patern I like my input boxes to be able to do asyncpostbacks to support rich UI. I know that it is possible to develop completely client side AJAX controls talking to server (not to page itself), but is is as boring boring as data binding in ASP.NET.
I am trying to make ASP.NET handle generic classes like TypedDropDown. I got some results and it looks possible to get typed DataList control as well. (http://weblogs.asp.net/ysolodkyy/archive/2007/10/02/control-builders-amp-asp-net-generic-control-classes.aspx)
LOL
My reasoning is simple unrelated things shouldn't be put together in the source code.
A 'for each' loop in the middle of code whose job it is to present information to the user just doesn't make good sense and will be more difficult to maintain in the future.
Why is this business logic and not layout logic? Everything about layout logic is meant to convey meaning about the placement and location of information and the 'foreach' (ok extra space last post :P ) doesn't convey info consistent with this.
I can see that you won't be convinced of any other reasoning so I'll just offer that these kind of coding pratices will come back to bite you later. :)
Realize, friend, you are in a VAST minority with your opinion (including other platforms here). And your "back to bite you comment" applies to them, as well as me. And I find it hard to believe that you have all the answers. Or maybe you do and I've been arguing with God... who knows these days :).
Take a look outside the MS walls friends - it's a big world out there that is indeed round. They speak weird languages, use profanity, and do strange things like use "foreach" in a code page. And yet they look just like you and me!
You could have made a hyperlink column do what you did with unnecessary code.
I respect your Subsonic work, but this blog post is just embarrassingly bad.
above. And what if you build grid dynamically? It's a nightmare on
inline script. Once you ends using real gui component (like
GridView) you will end with endless routines and you will have to
write them over and over again on every page in your application.
Indeed in very rare simple cases your approach is worthy. Thanks
has not yet used in-line scripting in VS2008. A few things in my
recent experience has led me back to in-line scripting. First, I
had to make changes to an ASP.NET 1.1 web site that used
codebehinds and for which the source code had ben irrevocably lost.
Second, I have been developing web parts for MOSS and recently
switched to using Smart-Part and ascx files (coded in-line) in lieu
of deploying dlls. (If you don't know how painful it is to develop
and deploy web parts in compiled form to MOSS, count your
blessings.) Third, I have been asked to make changes to a very well
coded .asp/VBScript site who's judicious use of inline coding,
includes and VBScript classes make it the easiest application to
maintain that I've ever been handed, in any language/platform.
I can see both sides of the fense when it comes to the code behind/inline coding debate. The problem I have noticed is the lack of some server controls (ex. DataGrid....if I recall correctly) spitting out crappy HTML and that's simply unacceptable. Failing the W3C Validation is like getting punched in the face. So this is when inline coding becomes attractive... again. *looks back at ASP classic and grins* More control over the HTML is a good thing.
About two jobs ago, I was slapped on my wrists with a ruler each time I would write "spaghetti code" of any type, even if the performance was better or equal to it's server control counterpart. To this day, I still cringe when I write some type of inline code that could be seperated to the codebehind. Why do I feel I MUST use the code behind? Well, it's been a while since I've asked myself that question and I find that from an architectural point-of-view, it's a seperation of logic and UI for clean implementation. The UI homies work on the ASPX and the Logic homies work on the code behind. Makes for good organization, I suppose. It is all clean in my head at least.
The other side of my head screams, "Will using the code behind be most efficient in helping me get this project completed on time?". For most developers, there is a constant stress to deliver a pimpin' product before the ever present deadline. Will inline coding be faster and more efficient than coding with the code behind? Will this save my department money/time in maintenance for the poor soul that have to take over this project after I leave?
I'm not sure there is a right answer. I see both sides of the code behind/inline argument and I agree with both. It all boils down to what is most effective for you. As for me, I just use the code behind because that's how I'm most effective.
Though, I could just be completely retarded. Which is most likely the case. :)
My understanding, from the first I encountered discussions about MVC, is that the code-behind portion of ASP.NET is your controller. The .aspx page is your view. So that's where you get the confusion about separation.
That being said, if this is true, then I think this actually reinforces your point somewhat. Code which controls the view, makes perfect sense to be inline. So your example of the foreach loop building the table is a good one in that sense. Although I believe you can easily do the same thing with the DataRepeater, but then you still have inline code with the data eval constructs. So I think your way is clean in many ways.
However, I think code which controls the view, should be somewhere behind the scenes. So the call to data layer from your view grabbing the collection of objects is what is bothering people.
I've been using the MVP pattern described by Bill McCafferty over at http://www.codeproject.com/aspnet/ModelViewPresenter.asp in some of my recent work. This appears to me to be a good compromise between dealing with the oddities of the asp.net webform framework, and a desire to abstract out the view from the business logic. In the case of the MVP, you'd set a property on the aspx page with the presenter, and then your data interating code would take over.
Or I suppose you could load up a value in your Page_Load, and then reference that in your inline script. Either way.
Now, to the other point of view. By keeping the UI free of inline, and using user controls for these blocks of what you'd script out, you do make it easier for a web designer to mock up the page display without breaking things. Although in my projects, I never see this mythical web designer appear anywhere, so is that a useful argument?
I think this is good discussion. I'm eager to see where this new way of thinking takes us.
Aloha! This is your cousin Tom in San Diego!!!! I attempted to send an email and am not sure if you received. Hope all is well in Hawaii. Have been spending quite a bit of time in Maui (Kihei). Hope fully this reaches you.
Regards,
Tom Conery