如何使用?:Razor和内联代码块的if语句

177

我正在使用新的Razore视图引擎更新我的旧.aspx视图。 我有很多地方需要像这样编写代码:

<span class="vote-up<%= puzzle.UserVote == VoteType.Up ? "-selected" : "" %>">Vote Up</span>

理想情况下,我想要做到这一点:

<span class="vote-up@{puzzle.UserVote == VoteType.Up ? "-selected" : ""}">Vote Up</span>

然而这里有两个问题:

  1. vote-up@{puzzle.UserVote .... 没有将@符号视为代码块的开始
  2. @puzzle.UserVote == VoteType.Up 将第一部分@puzzle.UserVote 视为应该渲染变量值。

有人知道如何解决这些问题吗?


6
我没有使用过 Razor,但根据我所看到的,建议尝试 @(puzzle.UserVote == VoteType.Up ? "-selected" : "") - Lasse Espeholt
1
由于这是Razor中行内三元运算符的顶部结果,我要补充一下:如果您的输出包含HTML或可编码字符(例如撇号),例如注入JavaScript或类似内容,它将将它们编码为实体,如&# 39;并破坏页面。因此,您必须使用Html.Raw("..")。否则,使用上面的代码,您最终会得到类似于<p class=&#39;test&#39;>的无效结果。 - NibblyPig
4个回答

334

这应该可以工作:

<span class="vote-up@(puzzle.UserVote == VoteType.Up ? "-selected" : "")">Vote Up</span>

3
使用圆括号而不是花括号非常奇怪。 - pat capozzi

55
@( condition ? "true" : "false" )

2
我选择了这个,感觉很整洁,以后阅读起来也很容易。 - Dan Harris
1
如果您需要显示属性的值(包括字符串),而不是调用ToString() - 在我的情况下无法正常工作。您可以这样做 @(condition ? $"{foo.bar}" : "Default") - Dan Harris

32

关键是在@分隔符之后用括号将表达式封装起来。您可以以此方式使任何复合表达式工作。


10
在大多数情况下,CD..解决方案都可以完美地运作。然而,我遇到了一个更加复杂的情况:
 @(String.IsNullOrEmpty(Model.MaidenName) ? "&nbsp;" : Model.MaidenName)

这将在我的页面中打印"&nbsp;",生成的源代码为&amp;nbsp;。现在有一个函数Html.Raw("&nbsp;"),它应该让您编写源代码,但在这种情况下,它会抛出编译器错误:

编译器错误消息:CS0173:条件表达式的类型无法确定,因为'System.Web.IHtmlString'和'string'之间没有隐式转换

所以我最终编写了以下语句,虽然不太好看,但即使在我的情况下也有效。
@if (String.IsNullOrEmpty(Model.MaidenName)) { @Html.Raw("&nbsp;") } else { @Model.MaidenName } 

注意:有趣的是,一旦进入花括号内部,您必须重新启动Razor块。

为什么不直接使用@(String.IsNullOrEmpty(Model.MaidenName) ? Html.Raw("&nbsp;") : Model.MaidenName)呢? - JP Hellemons
1
嗯...那么因为上述的编译器错误怎么样?;) - Damian Vogel
4
抱歉,我需要更多咖啡 :) - JP Hellemons
3
你可以通过让三元操作符的两个侧具有相同的类型来避免该错误,@(String.IsNullOrEmpty(Model.MaidenName) ? Html.Raw("&nbsp;") : Html.Raw(Model.MaidenName)) - NibblyPig

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接