Answers:
您没有从Razor的PM那里得到我的消息,但是在Razor 2(网页2和MVC 4)中,我们将在Razor中内置条件属性(自MVC 4 RC成功测试以来),所以您可以说这样的事情...
<input type="text" id="@strElementID" class="@strCSSClass" />
如果strCSSClass为null,则class属性将完全不呈现。
SSSHHH ...不要告诉。:)
请注意,您可以执行以下操作(至少在MVC3中):
<td align="left" @(isOddRow ? "class=TopBorder" : "style=border:0px") >
我认为剃须刀加引号实际上是浏览器。正如Rism指出的那样,在使用MVC 4进行测试时(我还没有使用MVC 3进行测试,但是我认为行为没有改变),这实际上可以产生效果,class=TopBorder
但是浏览器可以很好地进行解析。HTML解析器在某种程度上可以忽略缺少的属性引号,但是如果您有空格或某些字符,这可能会中断。
<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="border:0px"
仅当您通过网络查看响应时,才会看到此消息。如果使用HTML检查器,通常实际上您会看到DOM,而不是原始HTML。浏览器将HTML解析为DOM,而解析后的DOM表示已经应用了一些技巧。在这种情况下,浏览器会看到在属性值周围没有引号,将其添加:
style=""border:0px""
但是在DOM检查器中,HTML字符代码可以正确显示,因此您实际上可以看到:
style=""border:0px""
在Chrome浏览器中,如果右键单击并选择“编辑HTML”,它将切换回原来的位置,以便您可以看到那些讨厌的HTML字符代码,从而清楚地知道您有真正的外部引号和HTML编码的内部引号。
因此,尝试自己报价的问题是Razor避免了这些问题。
使用Html.Raw防止引号转义:
<td @Html.Raw( someBoolean ? "rel='tooltip' data-container='.drillDown a'" : "" )>
呈现为:
<td rel='tooltip' title='Drilldown' data-container='.drillDown a'>
上面是绝对安全的,因为我没有从变量输出任何HTML。唯一涉及的变量是三元条件。但是,请注意,如果根据用户提供的数据构建字符串,则后一种技术可能会使您面临某些安全问题。例如,如果您从源自用户提供的数据的数据字段中构建了一个属性,则使用Html.Raw意味着该字符串可能包含该属性和标记的过早结尾,然后开始执行一个脚本标记,该标记代表当前登录的行为用户(可能与登录用户不同)。也许您有一个包含所有用户图片列表的页面,并且正在将工具提示设置为每个人的用户名,并且一个用户命名为他自己'/><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)
如果这种方式对您有用,我建议htmlAttr
在模型中定义字典,这样您的视图就不需要任何@{ }
逻辑块了(更清楚)。