[c#] Simple If/Else Razor Syntax

I'm trying to do a simple If/Else within a foreach with this code:

@{
var count = 0;
foreach (var item in Model)
{
    if (count++ % 2 == 0)
    {
        @:<tr class="alt-row">
    } else { 
        @:<tr>
    }
        <td>
            @Html.DisplayFor(modelItem => item.Title)
        </td>
        <td>
            @Html.Truncate(item.Details, 75)
        </td>
        <td>
            <img src="@Url.Content("~/Content/Images/Projects/")@item.Images.Where(i => i.IsMain == true).Select(i => i.Name).Single()" 
                alt="@item.Images.Where(i => i.IsMain == true).Select(i => i.AltText).Single()" class="thumb" />
        </td>
        <td>
            @Html.ActionLink("Edit", "Edit", new { id=item.ProjectId }) |
            @Html.ActionLink("Details", "Details", new { id = item.ProjectId }) |
            @Html.ActionLink("Delete", "Delete", new { id=item.ProjectId })
        </td>
    </tr>
}
}

I get a parse error "Encountered end tag "tr" with no matching start tag. Are your start/end tags properly balanced?". Seems like the if statement doesn't wanna' work.

This question is related to c# asp.net-mvc razor html-table

The answer is


I would just go with

<tr @(if (count++ % 2 == 0){<text>class="alt-row"</text>})>

Or even better

<tr class="alt-row@(count++ % 2)">

this will give you lines like

<tr class="alt-row0">
<tr class="alt-row1">
<tr class="alt-row0">
<tr class="alt-row1">

To get rid of the if/else awkwardness you could use a using block:

@{
    var count = 0;
    foreach (var item in Model)
    {
        using(Html.TableRow(new { @class = (count++ % 2 == 0) ? "alt-row" : "" }))
        {
            <td>
                @Html.DisplayFor(modelItem => item.Title)
            </td>
            <td>
                @Html.Truncate(item.Details, 75)
            </td>
            <td>
                <img src="@Url.Content("~/Content/Images/Projects/")@item.Images.Where(i => i.IsMain == true).Select(i => i.Name).Single()" 
                    alt="@item.Images.Where(i => i.IsMain == true).Select(i => i.AltText).Single()" class="thumb" />
            </td>
            <td>
                @Html.ActionLink("Edit", "Edit", new { id=item.ProjectId }) |
                @Html.ActionLink("Details", "Details", new { id = item.ProjectId }) |
                @Html.ActionLink("Delete", "Delete", new { id=item.ProjectId })
            </td>
        }
    }
}

Reusable element that make it easier to add attributes:

//Block is take from http://www.codeducky.org/razor-trick-using-block/
public class TableRow : Block
{
    private object _htmlAttributes;
    private TagBuilder _tr;

    public TableRow(HtmlHelper htmlHelper, object htmlAttributes) : base(htmlHelper)
    {
        _htmlAttributes = htmlAttributes;
    }

    public override void BeginBlock()
    {
        _tr = new TagBuilder("tr");
        _tr.MergeAttributes(HtmlHelper.AnonymousObjectToHtmlAttributes(_htmlAttributes));
        this.HtmlHelper.ViewContext.Writer.Write(_tr.ToString(TagRenderMode.StartTag));
    }

    protected override void EndBlock()
    {
        this.HtmlHelper.ViewContext.Writer.Write(_tr.ToString(TagRenderMode.EndTag));
    }
}

Helper method to make razor syntax clearer:

public static TableRow TableRow(this HtmlHelper self, object htmlAttributes)
{
    var tableRow = new TableRow(self, htmlAttributes);
    tableRow.BeginBlock();
    return tableRow;
}

A little bit off topic maybe, but for modern browsers (IE9 and newer) you can use the css odd/even selectors to achieve want you want.

tr:nth-child(even) { /* your alt-row stuff */}
tr:nth-child(odd) { /* the other rows */ }

or

tr { /* all table rows */ }
tr:nth-child(even) { /* your alt-row stuff */}

Examples related to c#

How can I convert this one line of ActionScript to C#? Microsoft Advertising SDK doesn't deliverer ads How to use a global array in C#? How to correctly write async method? C# - insert values from file into two arrays Uploading into folder in FTP? Are these methods thread safe? dotnet ef not found in .NET Core 3 HTTP Error 500.30 - ANCM In-Process Start Failure Best way to "push" into C# array

Examples related to asp.net-mvc

Using Lato fonts in my css (@font-face) Better solution without exluding fields from Binding Vue.js get selected option on @change You must add a reference to assembly 'netstandard, Version=2.0.0.0 How to send json data in POST request using C# VS 2017 Metadata file '.dll could not be found The default XML namespace of the project must be the MSBuild XML namespace How to create roles in ASP.NET Core and assign them to users? The model item passed into the dictionary is of type .. but this dictionary requires a model item of type How to use npm with ASP.NET Core

Examples related to razor

Uncaught SyntaxError: Invalid or unexpected token How to pass a value to razor variable from javascript variable? error CS0103: The name ' ' does not exist in the current context how to set radio button checked in edit mode in MVC razor view @Html.DropDownListFor how to set default value Razor MVC Populating Javascript array with Model Array How to add "required" attribute to mvc razor viewmodel text input editor How to correctly use Html.ActionLink with ASP.NET MVC 4 Areas Multiple radio button groups in MVC 4 Razor How to hide a div element depending on Model value? MVC

Examples related to html-table

Table column sizing DataTables: Cannot read property 'length' of undefined TypeError: a bytes-like object is required, not 'str' in python and CSV How to get the <td> in HTML tables to fit content, and let a specific <td> fill in the rest How to stick table header(thead) on top while scrolling down the table rows with fixed header(navbar) in bootstrap 3? Sorting table rows according to table header column using javascript or jquery How to make background of table cell transparent How to auto adjust table td width from the content bootstrap responsive table content wrapping How to print table using Javascript?