Well, I was looking over some old stuff on Rob Conery’s blog and came across a little rant about code behind vs. inline scripting. Now, I’m not gonna flame Rob – not at all – I just have a different viewpoint on the issue. I’m not going to say that Rob’s wrong or way off or anything like that – I have a ton of respect for him and his viewpoint – but I must also respectfully offer a different side of the story.
With that said, before I get into it, I do have to say that I agree with much of Rob’s defense of inline code. It is a perfectly valid way of doing ASP.NET pages, even today - it’s a “lifestyle choice”, like the choice between VB.net and C# (oh, I’m gonna get flames for that one, I’m sure). His responses to the arguments against inline code are dead-on.
One comment, though, that I’d like to add to the discussion of inline code vs. code-behind is that it promotes better separation. Done right, you have pure UI and design in the aspx markup. In the code-behind, you have the “glue” that ties the UI to the Business Layer. From a designer-to-developer workflow perspective, this is definitely a big bonus. You really don’t want pure designers writing or mucking about in code.
I also have to admit that I do have an aversion, personally, to inline code. It could be that it reminds me of ASP “Classic” code that I wrote so, so long ago. It was, to me, much harder to maintain and there was data access and logic and all kinds of ugly stuff all mixed up and jumbled up with the UI code. Of course, if you were smart about your ASP code – and I like to think that I was – you put a lot of this into include files. This, however, had it’s own issue that I like to term the “Magical Mystery Include”. Was it spaghetti code? No, not at all. But I didn’t find it tidy. Then again, on the flip side, there was no question about what was actually getting sent to the client – you had complete control over that, which is something that’s lacking in some of the higher-level ASP.NET controls (like GridView). And, Rob did have a point … too many developers have gotten so reliant on the abstractions brought about by ASP.NET’s server controls that they’ve forgotten their HTML and JScript – not a good thing.
With that said, I do take issue with his “example” using code-behinds. It was, I think, not truly representational of how one would accomplish the task with controls and code-behind. Back in college philosophy, we called this a straw-man argument. So I’m gonna set the record straight. I’m going to be implementing the same functionality – showing a list of objects returned from the BLL with one of the columns having a hyperlink to a page called “MyEditPage.aspx” passing the id to the page in the query string.
First, duplicating Rob’s example with an ObjectDataSource and GridView control:
<form id="form1" runat="server" >
<div>
<asp:ObjectDataSource runat="server" ID="categoryDataSource"
SelectMethod="GetCategories" TypeName="Commerce.CSK.Web.Services" >
</asp:ObjectDataSource>
</div>
<asp:GridView ID="catalogListing" runat="server" AutoGenerateColumns="False"
DataSourceID="categoryDataSource" enableviewstate="false">
<Columns>
<asp:HyperLinkField DataNavigateUrlFields="ID"
DataNavigateUrlFormatString="MyEditPage.aspx?id={0}" Text="Select" />
<asp:BoundField DataField="ID" HeaderText="ID" SortExpression="ID" />
<asp:BoundField DataField="Name" HeaderText="Name"
SortExpression="Name" />
</Columns>
</asp:GridView>
</form>
Look Ma! No Code!! That’s right folks, no code at all is required for this. Also, note that since we don’t need the ViewState, I’ve turned it off for the GridView control. But .. ViewState isn’t quite as bad as some folks think – it is compressed and, even better, it can be validated to help mitigate Cross-Site Request Forgery (something that’s getting to be more and more in vogue these days).
Still … I don’t have complete control over the HTML that is generated and sent to the browser. And this, my friends, is one of the reasons that I tend to avoid the DataGrid and prefer the Repeater. I like the Repeater – it is, in fact, my absolute favorite databound control. One of the responses that I get to that comment is that the Repeater doesn’t have a designer. Well, yes, that’s true but that doesn’t really bother me. I’m in the habit of doing about 95% of my ASP.NET in the markup view, not the designer. Call me old-fashioned, but I learned HTML back around 1994 or so, when all we had was Visual Notepad, and I still like to work directly with the tags. Which is why I love the split view in VS 2008; I get the best of both worlds.
Here’s the same thing, now using the Repeater control:
<form id="form1" runat="server">
<div>
<asp:ObjectDataSource runat="server" ID="categoryDataSource" SelectMethod="GetCategories"
TypeName="Commerce.CSK.Web.Services"></asp:ObjectDataSource>
</div>
<asp:Repeater ID="catalogListing" runat="server"
DataSourceID="categoryDataSource"
EnableViewState="false">
<HeaderTemplate>
<div>
<table>
<tr>
<td>Option</td>
<td>ID</td>
<td>Name</td>
</tr>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td><asp:HyperLink runat="server" NavigateUrl= '<%# "~/MyEditPage.aspx?id=" + Eval("ID") %>' Text='Select' /></td>
<td><%# Eval("ID") %></td>
<td><%# Eval("Name") %></td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table> </div>
</FooterTemplate>
</asp:Repeater>
</form>
Now … complete control over the HTML and still no code. I also want to point out that using the Hyperlink control provides a benefit that we don’t get with inline code – with the “~” format, the ASP.NET runtime will handle making sure that the link is correct from the current location, some that is very handy, even necessary, for user controls that could be running from a page anywhere in the application. The output will be identical (or darn close) to Rob’s example with inline code and even looks a little similar. But … I have to be honest … I’m not always too keen on using DataSource controls, especially if I don’t need the editing functionality that they provide. So … I could just take the ObjectDataSource out and write maybe 3 or 4 lines in the code behind to bind it all up. Easy enough. In that case, can you see all that is going on with the page in one shot? No, you can’t. You look at the markup and you see what the resulting page will look like … you see the design and that alone. To see the logic, you look in the code-behind. A nice separation of design/UI and code/logic and I like that. And, just in case you haven’t guessed, you’ll see quite a bit of that in CSK 3.0.