ChiliYago
ChiliYago

Reputation: 12319

proper razor syntax for switch statement inside foreach

I am having a heck of a time trying to find the proper syntax for creating a switch statement inside a foreach loop on my mvc view page.

Here is the latest attempt (after many others) I have so far but the the Razor engine won't accept it. Here the error is right at the @foreach and indicates it is missing a closing }

@foreach (var item in Model) {

    String s = item.RegistrationStatus.ToString();

    // Make sure this mirrors values in RegistrationStatus enum!
    switch (s)
    {
        case "New": 
            <tr class='info'>
                break;

        case "Arrived": 
            <tr class='success'>
            break;

        default:
            <tr>

    }


......

}

Upvotes: 14

Views: 22941

Answers (4)

Variant for ASP NET CORE 2.2 MVC

@foreach (var item in Model) {

    String s = item.RegistrationStatus.ToString();

    // Make sure this mirrors values in RegistrationStatus enum!
    switch (s)
    {
        case "New":
            @Html.Raw("<tr class='info'>")
            break;

        case "Arrived":
            @Html.Raw("<tr class='success'>")
            break;

        default:
            @Html.Raw("<tr>")
            break;
    }

    ......
    @Html.Raw("/<tr>")
} 

Upvotes: 0

epox
epox

Reputation: 10940

Sometimes it's better to use { in a separate line. With that approach you get more lines of code. On the other hand, you get clear lines of html tags without "@:" garbage. That allows you quickly copy-paste entire html lines "as is" from/to a real html during "in-browser" debugging.

@foreach (var item in Model) {
    String s = item.RegistrationStatus.ToString();

    // Make sure this mirrors values in RegistrationStatus enum!
    switch (s)
    {
        case "New":
        {
            <tr class='info'>
        }
            break;
        case "Arrived":
        {
            <tr class='success'>
        }
            break;
        default:
        {
            <tr>
        }
            break;
    }

......
}

Upvotes: 0

Mario S
Mario S

Reputation: 11955

You can do as Justin suggests, something in the way of this:

@foreach (var item in Model) {

    String s = item.RegistrationStatus.ToString();

    // Make sure this mirrors values in RegistrationStatus enum!
    switch (s)
    {
        case "New":
            @:<tr class='info'>
            break;

        case "Arrived":
            @:<tr class='success'>
            break;

        default:
            @:<tr>
            break;
    }

    ......
}

But, if you're running MVC4 with Razor V2, you could as easily use a helper method (or regular method) instead:

public static class MyHelperExtensions
{
    public static string GetCssClass(this HtmlHelper helper, RegistrationStatus status)
    {
        // Make sure this mirrors values in RegistrationStatus enum!
        switch (status)
        {
            case RegistrationStatus.New:
                return "info";

            case RegistrationStatus.Arrived:
                return "success";

            default:
                return null; // Return null so that the attribute won't render.
        }
    }
}

And then use it like so:

@foreach (var item in Model)
{    
    <tr class='@Html.GetCssClass(item.RegistrationStatus)'>

    .....
}

This is a bit more readable and easier to maintain. If the GetCssClass() method returns null then Razor V2 won't even render the attribute (in this case class=).

Upvotes: 22

Justin Bicknell
Justin Bicknell

Reputation: 4808

You could use the Html.Raw method:

    case "New": 
        Html.Raw("<tr class='info'>")
        break;

Also see MVC3 Razor: Displaying html within code blocks for other options such as:

    case "New": 
       @:<tr class='info'>
       break;

Upvotes: 2

Related Questions