使用Razor MVC3的条件HTML属性

variablesstrCSSClass通常有一个值,但有时是空的。

我不想在这个input元素的HTML中包含一个空的class =“”,这意味着如果strCSSClass是空的,我根本不需要class =属性。

以下是执行条件HTML属性的一种方法:

<input type="text" id="@strElementID" @(CSSClass.IsEmpty() ? "" : "class=" + strCSSClass) /> 

有没有更好的方法来做到这一点? 具体来说,我可以按照在元素的其他部分使用相同的语法:class =“@ strCSSClass”?

您从Razor的PM中没有听到这个消息,但是在Razor 2(Web Page 2和MVC 4)中,我们将拥有内置在Razor中的条件属性(从MVC 4 RC开始testing成功),所以您可以说像这样的事情…

 <input type="text" id="@strElementID" class="@strCSSClass" /> 

如果strCSSClass为null,那么class属性根本就不会渲染。

SSSHHH …不说。 🙂

注意你可以做这样的事情(至less在MVC3中):

 <td align="left" @(isOddRow ? "class=TopBorder" : "style=border:0px") > 

我相信剃刀join报价实际上是浏览器。 正如Rism在使用MVC 4进行testing时指出的(我没有使用MVC 3进行testing,但是我认为行为并没有改变),这实际上产生了class=TopBorder但浏览器能够parsing这个问题。 HTMLparsing器对于缺less的属性引用有些宽容,但是如果你有空格或者某些字符这可能会中断

 <td align="left" class="TopBorder" > 

要么

 <td align="left" style="border:0px" > 

提供自己的报价出了什么问题

如果您尝试将一些常用的C#约定用于嵌套引号,那么您最终会得到比您讨价还价更多的引号,因为Razor正试图安全地将它们转义出来。 例如:

 <button type="button" @(true ? "style=\"border:0px\"" : string.Empty)> 

应该评估为<button type="button" style="border:0px">但是Razor转义所有来自C#的输出,从而产生:

 style=&quot;border:0px&quot; 

如果您通过networking查看响应,您将只能看到这一点。 如果您使用HTML检查器,通常您会看到DOM,而不是原始的HTML。 浏览器将HTMLparsing到DOM中,parsing后的DOM表示已经应用了一些细节。 在这种情况下,浏览器会看到属性值周围没有引号,并添加它们:

 style="&quot;border:0px&quot;" 

但在DOM检查器中,HTML字符代码正确显示,因此您可以看到:

 style=""border:0px"" 

在Chrome中,如果右键单击并select“编辑HTML”,则会切换回来,以便您可以看到那些令人讨厌的HTML字符代码,从而清楚地表明您具有实际的外部引号和HTML编码的内部引号。

所以试图自己做报价的问题是剃刀逃脱这些。

如果你想完全控制报价

使用Html.Raw来防止报价转义:

 <td @Html.Raw( someBoolean ? "rel='tooltip' data-container='.drillDown a'" : "" )> 

呈现为:

 <td rel='tooltip' title='Drilldown' data-container='.drillDown a'> 

以上是完全安全的,因为我不是从一个variables输出任何HTML。 所涉及的唯一variables是三元条件。 但是, 请注意 ,如果从用户提供的数据构buildstring,最后这种技术可能会使您遇到某些安全问题。 例如,如果您从源自用户提供的数据的数据字段构build属性,则使用Html.Raw意味着string可能包含属性和标记的提前结束,然后开始一个代表当前login的脚本标记用户(可能与login用户不同)。 也许你有一个包含所有用户图片列表的页面,你正在设置一个工具提示作为每个人的用户名,一个用户名为'/><script>$.post('changepassword.php?password=123')</script> ,现在任何其他查看此页面的用户都会立即将其密码更改为恶意用户知道的密码。

我想更方便一些,有条理的方法是使用Html帮手。 在你看来,它可以看起来像:

 @{ var htmlAttr = new Dictionary<string, object>(); htmlAttr.Add("id", strElementId); if (!CSSClass.IsEmpty()) { htmlAttr.Add("class", strCSSClass); } } @* ... *@ @Html.TextBox("somename", "", htmlAttr) 

如果这种方式对您有用,我build议您在模型中定义字典htmlAttr ,这样您的视图就不需要任何@{ }逻辑块(更清晰)。