OdeToCode IC Logo

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?