简体   繁体   中英

Switch statement inside Razor CSHTML

I'm developing a project in ASP.NET MVC4, Twitter.Bootstap 3.0.0 and Razor. In a View, I need to display buttons depending of a property value. Using the switch statement, the example below doesn't work (nothing is displayed):

@switch (Model.CurrentStage) { 
    case Enums.Stage.ReadyToStart:
        Html.ActionLink(Language.Start, "Start", new { id=Model.ProcessId }, new { @class = "btn btn-success" });
        break;
    case Enums.Stage.Flour:
        Html.ActionLink(Language.GoToFlour, "Details", "Flours", new { id=Model.Flour.FlourId }, new { @class = "btn btn-success" });
        break;
    ...
}

Changing a bit, using a <span> tag, the code works:

@switch (Model.CurrentStage) { 
    case Enums.Stage.ReadyToStart:
        <span>@Html.ActionLink(Language.Start, "Start", new { id=Model.ProcessId }, new { @class = "btn btn-success" })</span>
        break;
    case Enums.Stage.Flour:
        <span>@Html.ActionLink(Language.GoToFlour, "Details", "Flours", new { id=Model.Flour.FlourId }, new { @class = "btn btn-success" })</span>
        break;
    ...
}

Can someone explain why?

Thanks.

It's the funkiness of Razor. When you're in normal HTML and use C# code, putting something with an @ symbol on it will write the result to the page:

<p>@Html.ActionLink("whatever", "whatever"...)</p>

This is similar to the old-school <%= %> .

<p><%= SomeMethodThatReturnsSomethingThatWillBeWritten() %></p>

However, the Html.ActionLink method simply returns an MvcHtmlString object in the .NET world. In your first example, you've got a regular C# code block. So calling Html.ActionLink() from there simply executes it and returns the MvcHtmlString to nobody. In your second example, you've jumped back into the HTML context, so it writes the HTML again.

You can use the special <text> block to get back to HTML instead of using <span> or other real HTML, and it will write directly without writing the extra HTML:

case Enums.Stage.ReadyToStart:
    <text>@Html.ActionLink(Language.Start, "Start", new { id=Model.ProcessId }, new { @class = "btn btn-success" })</text>
    break;

You can also use the similar @: syntax:

case Enums.Stage.ReadyToStart:
    @:@Html.ActionLink(Language.Start, "Start", new { id=Model.ProcessId }, new { @class = "btn btn-success" })
    break;

You can read more about both here

EDIT

Actually, in this case, you don't need either one. You just need the @ symbol, which will be enough to get you back into the HTML:

case Enums.Stage.ReadyToStart:
    @Html.ActionLink(Language.Start, "Start", new { id=Model.ProcessId }, new { @class = "btn btn-success" })
    break;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM