Nested If and For loops in views woes

I want to start this off by saying that I generally don't like using C# code in my views, I feel it is bad practice.  I would much rather the models be simple enough to be displayed without the use of code on the front end.  I also feel that display views for complex nested types should be used as partial views, this is the correct way to do it in my opinion.  However, situations arise where you can't refactor all your models to work, or it isn't worth it.  For these cases, it is often better to simply break down and put the if and for blocks in the view.  This does have some syntax challenges I will talk through.  
The first is the @ symbol.  You are probably familiar with using it before all calls to the Html Helper and such.  Now if we have an if block, that if block must be started with an @ and then it will have { curleys } around stuff that occurs on that condition.  This works well enough if you just have html in there.  But lets say you have 2 nested if blocks, well you have to be careful now.  
Basically, after you have an @, it is code until it sees what it thinks is static text, usually an html tag.  Sometimes it isn't so easy for the parser to figure this out.  So say you have 2 if blocks in a row, well it is going to be upset.  This is where the @: syntax and the <text></text> syntax come into play.  Basically, in complex scenarios like this (nested) we need to specify everything that is text so it can know the rest is code and parse correctly.  Here is what my double if looks like in a for loop for reference using the above syntax.
<div class="fieldgrid" style="float:left;">
            <table class=" table-bordered" style="max-width:200px;word-wrap: break-word;">
                @{int i = 20; }
                @foreach (var prop in Model.GetType().GetProperties().Where(c => !c.PropertyType.ToString().Contains("Collections.Generic")).OrderBy(c => c.Name))
                {
                    if (i == 0)
                    {
                        i = 20;
                        @:</table></div>
                    @:<div class="fieldgrid" style="float:left;"><table class=" table-bordered" style="max-width:200px;word-wrap: break-word;">
                }
                    <text>
                        <tr>
                            <td class="display-label">
                                @prop.Name
                            </td>
                            <td>
                                @prop.GetValue(Model, null)
                            </td>
                        </tr>
                    </text>
                    i--;
                }
            </table>
        </div>
So this code I will talk about in another post, but for the scope of this post, it creates many tables from a set of data.  It does a simple for loop of the data to do so, but breaks the table into 20 record chunks.  So a counter is created and an if block put in place to see if the counter hits 0, it resets the counter and ends and starts a new table.  The static text is all identified either with a @: before it, or surrounded in <text></text> tags.  I would have only used <text> tags, however, wrapping just closing tags with it doesn't go well as precompiler xml is hard to differentiate from post xml I guess.  But this works and is how to do such things.  
Remember, just because you can, doesn't mean you should.

Add comment