ASP.NET and Separating Concerns

Wednesday, July 25, 2007

Ayende had a recent post with the following quote from Nicholas Piasecki:

To me, this discussion all boils down to one thing: the foreach loop. Let's say you want to display a table of sales reports, but after every tenth row, you want to print out an extra row that displays a running total of sales to that point. And you want negative numbers to appear in red, positive numbers to appear in green, and zeros to appear in black. In MonoRail, this is easy; with WebForm's declarative syntax, just shoot yourself in the face right now. Most solutions I've seen end up doing lots of manipulation in the code-behind and then slamming it into a Literal or something, which to me defeats the purpose of the code separation.

Ayende says this is the essence of why he dislikes WebForms. In the comments, someone proposed a rails solution ...

#set ($i = 0)
#set ($running_total = 0)
#foreach ($report in $reports)
#each
    <tr>
        <td>$report.name</td>
        #if ($report.ammount > 0)
            
<div class="green">
        #elseif ($report.ammount < 0)
            
<div class="red">
        #else
            
<div class="black">
        #end
        $report.ammount
</td>
    </tr>

    #set ($running_total = $running_total + $report.ammount)
    #set ($i = $i + 1)
    #between
    #if (($i % 10 ) == 1)
    
<tr class="Running Total">
        <td>$running_total</td>
    </tr>
    #end
#end

... which received praise for elegance. I'm thinking if you really want to intermingle code and markup, than open up an .aspx page and have at it:

<%@ Page Language="C#" %>
<%  
    SalesReport report = new SomeApplicationService().GetSalesReport();
    int rowCount = 0;
    
int runningTotal = 0;
%>
<table>
  <% foreach (Salesperson p in report.SalesPeople) {
     rowCount++;
     runningTotal += p.TotalSales;
  %>
  
<tr>
    <td><%= p.Name %></td>
    
<td>
      <div class="<%= p.TotalSales < 0 ? "red" : p.TotalSales > 0 ? "green" : "black" %>">
        <%= p.TotalSales.ToString("c")  %>
      
</div>
    </td>        
  
</tr>
        
  <%
if(rowCount % 10 == 0) { %>
  
<tr>
    <td>SubTotal:</td>
    <td><%= runningTotal.ToString("c") %></td>
  </tr>
  <% } // end if %>  
<% }
// end foreach %>
</table>

Why throw out the baby with the bathwater?


Comments
Joe Ocampo Wednesday, July 25, 2007
I think we forget that ASP.Net still has it's roots in ASP.
Tomas Restrepo Wednesday, July 25, 2007
Scott, you have to admit, though, that the Webforms syntax is far worse :) That said, there's obviously much more to monorail (though I prefer the brail syntax myself), than simply being able to do loops and ifs in the markup. I find far more interesting the following aspects:
- No page life cycle mess (it's dirt simple)
- Controllers can be written in a more simple fashion, and easy to test
- It's still ASP.NET. That is, you can still write HttpModules, use IHttpHandlers, and all of that, which is the really nice part of the ASP.NET architecture.
Eber Irigoyen Wednesday, July 25, 2007
hehe... so now the "good old way" of coding web stuff (mixing code with html) is the elegant way of doing things... sigh...

good answer Scott
Vikram Wednesday, July 25, 2007
I am the kind of person who would still like to keep things clean and do it in code behind. I am sure the designer will be more happy to see the no code in the design
Trumpi Wednesday, July 25, 2007
Just looking at both methods, the first one seems a lot easier to read, and I think that this is the elegance that is spoken of. One reason why I think that the first method is easier to read is because the dynamic markup is completely different to the html markup. In the second method, the dynamic (ASP.NET) markup is too similar to the html markup. You really have to squint your eyes sometimes to find what it is that you are looking for.
LaptopHeaven Wednesday, July 25, 2007
You could always write a UserControl or WebControl which which accepts a SalesReport (even better ISalesReport) and has the display logic inside of it. Of course the aspx page then just has a reference to the user control. You could even bind the call to the service and call it in the control.
Rick Strahl Wednesday, July 25, 2007
Sigh - I can't tell you how often some jughead has left a comment in my blog because I DARED to use an <%= %> expression in an ASP.NET page.

I suppose this is what you get from arrogant 'architecture über alles' nazis who can't see the forest for the trees sometimes. Common sense appears to be to common for them at times <s>...

While it's certainly preferrable to keep code out of ASPX pages, it certainly can be more useful in some situations to do it inline especially if its a scenario where it effects the customization of the UI.

These days it seems people are overtaken by their preferences more than anything. The Ruby code and the ASP.NET code are functionally the same and require roughly the same amount of code and somebody will complain because one uses <% %> vs. a #. What's next?

The language debates these days over what's cool and isn't is really, really getting tiresome given that it's all the same crap rehashed in different regurgarations of the same basic coding syntax.


Scott McMaster Thursday, July 26, 2007
I'm certainly not going to be one to say that you should -never- use inline script in your ASPX pages. But before we dismiss out-of-hand those who would, let's consider for a minute where they might be coming from.

First, as Vikram mentioned, a markup-only solution does tend to be friendlier to design tools, particularly those that have some built-in smarts about the server tags in question.

But more than that, does anyone else remember bad ASP code? I'm not talking about bad ASP code that causes you to merely roll your eyes. I'm talking about truly evil, abominable, grungy, make-you-cry-for-your-mommy-and-question-your-career-decisions BAAAAAD. Close your eyes and think about that for a second.

Now, I'm sure that no one who is reading this post and has made it this far down in the comments would ever personally write code like that. But we probably all know developers who would still misuse markup-embedded script without giving it a second thought. (And yes, it's possible to write unmaintainable code in any language or environment, but I submit that this particular style of programming has proven more susceptible than most others.)

In a team environment, rather than constantly policing the quantity and complexity of embedded script in your markup, there might be occasions where it would be easier to simply declare a coding standard that prohibits it altogether.
scott Thursday, July 26, 2007
Tomas:

Excellent points. I'll give you the first hunk of code is slightly easier to read, but to me they both look terrible :)

I have no qualms about using code snippets in .aspx when they serve a good purpose (and I've been though the bad, grungy ASP code that Scott mentions - never want to do that again).

I also have no qualms about moving as much of that logic into some C# code that gets invoked from some sort of column template or templated control (perhaps with a little <% %> magic). If it's written properly I can test it and make sure it performs the formatting I need.
Comments are now closed.
by K. Scott Allen K.Scott Allen
My Pluralsight Courses
The Podcast!