使用 Razor MVC3 的条件 HTML 属性
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8061647/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Conditional HTML Attributes using Razor MVC3
提问by tony722
The variable strCSSClass often has a value but sometimes is empty.
变量 strCSSClass 通常有一个值,但有时为空。
I do not want to include an empty class="" in this input element's HTML, which means if strCSSClass is empty, I don't want the class= attribute at all.
我不想在这个输入元素的 HTML 中包含一个空的 class="",这意味着如果 strCSSClass 是空的,我根本不需要 class= 属性。
The following is one way to do a conditional HTML attribute:
以下是执行条件 HTML 属性的一种方法:
<input type="text" id="@strElementID" @(CSSClass.IsEmpty() ? "" : "class=" + strCSSClass) />
Is there a more elegant way of doing this? Specifically one where I could follow the same syntax as is used in the other parts of the element: class="@strCSSClass" ?
有没有更优雅的方法来做到这一点?特别是一个我可以遵循元素其他部分使用的相同语法的地方: class="@strCSSClass" ?
回答by Erik Porter
You didn't hear it from me, the PM for Razor, but in Razor 2 (Web Pages 2 and MVC 4) we'll have conditional attributes built into Razor(as of MVC 4 RC tested successfully), so you can just say things like this...
你没有从我这里听到,Razor 的 PM,但在 Razor 2(网页 2 和 MVC 4)中,我们将在 Razor 中内置条件属性(从 MVC 4 RC 成功测试开始),所以你可以说这样的事情...
<input type="text" id="@strElementID" class="@strCSSClass" />
If strCSSClass is null then the class attribute won't render at all.
如果 strCSSClass 为 null,则 class 属性根本不会呈现。
SSSHHH...don't tell. :)
SSHHH...别说。:)
回答by AaronLS
Note you can do something like this(at least in MVC3):
请注意,您可以执行以下操作(至少在 MVC3 中):
<td align="left" @(isOddRow ? "class=TopBorder" : "style=border:0px") >
What I believed was razor adding quotes was actually the browser. As Rism pointed out when testing with MVC 4(I haven't tested with MVC 3 but I assume behavior hasn't changed), this actually produces class=TopBorder
but browsers are able to parse this fine. The HTML parsers are somewhat forgiving on missing attribute quotes, but this can break if you have spaces or certain characters.
我相信剃刀添加引号实际上是浏览器。正如 Rism 在使用 MVC 4 进行测试时指出的(我没有使用 MVC 3 进行测试,但我认为行为没有改变),这实际上会产生,class=TopBorder
但浏览器能够很好地解析。HTML 解析器对缺少的属性引号有些宽容,但如果您有空格或某些字符,这可能会中断。
<td align="left" class="TopBorder" >
OR
或者
<td align="left" style="border:0px" >
What goes wrong with providing your own quotes
提供自己的报价有什么问题
If you try to use some of the usual C# conventions for nested quotes, you'll end up with more quotes than you bargained for because Razor is trying to safely escape them. For example:
如果您尝试对嵌套引号使用一些常见的 C# 约定,您最终会得到比您讨价还价更多的引号,因为 Razor 正试图安全地逃避它们。例如:
<button type="button" @(true ? "style=\"border:0px\"" : string.Empty)>
This shouldevaluate to <button type="button" style="border:0px">
but Razor escapes all output from C# and thus produces:
这应该评估为,<button type="button" style="border:0px">
但 Razor 会转义 C# 的所有输出,从而产生:
style="border:0px"
You will only see this if you view the response over the network. If you use an HTML inspector, often you are actually seeing the DOM, not the raw HTML. Browsers parse HTML into the DOM, and the after-parsing DOM representation already has some niceties applied. In this case the Browser sees there aren't quotes around the attribute value, adds them:
只有在通过网络查看响应时才会看到这一点。如果您使用 HTML 检查器,通常您实际上看到的是 DOM,而不是原始 HTML。浏览器将 HTML 解析为 DOM,解析后的 DOM 表示已经应用了一些细节。在这种情况下,浏览器发现属性值周围没有引号,添加它们:
style=""border:0px""
But in the DOM inspector HTML character codes display properly so you actually see:
但是在 DOM 检查器中 HTML 字符代码正确显示,所以你实际上看到:
style=""border:0px""
In Chrome, if you right-click and select Edit HTML, it switch back so you can see those nasty HTML character codes, making it clear you have real outer quotes, and HTML encoded inner quotes.
在 Chrome 中,如果您右键单击并选择“编辑 HTML”,它会切换回来,以便您可以看到那些令人讨厌的 HTML 字符代码,从而清楚地表明您有真正的外部引号和 HTML 编码的内部引号。
So the problem with trying to do the quoting yourself is Razor escapes these.
所以尝试自己引用的问题是 Razor 逃避了这些。
If you want complete control of quotes
如果您想完全控制报价
Use Html.Raw to prevent quote escaping:
使用 Html.Raw 防止引用转义:
<td @Html.Raw( someBoolean ? "rel='tooltip' data-container='.drillDown a'" : "" )>
Renders as:
呈现为:
<td rel='tooltip' title='Drilldown' data-container='.drillDown a'>
The above is perfectly safe because I'm not outputting any HTML from a variable. The only variable involved is the ternary condition. However, bewarethat this last technique might expose you to certain security problems if building strings from user supplied data. E.g. if you built an attribute from data fields that originated from user supplied data, use of Html.Raw means that string could contain a premature ending of the attribute and tag, then begin a script tag that does something on behalf of the currently logged in user(possibly different than the logged in user). Maybe you have a page with a list of all users pictures and you are setting a tooltip to be the username of each person, and one users named himself '/><script>$.post('changepassword.php?password=123')</script>
and now any other user who views this page has their password instantly changed to a password that the malicious user knows.
以上是完全安全的,因为我没有从变量输出任何 HTML。唯一涉及的变量是三元条件。但是,请注意,如果从用户提供的数据构建字符串,则最后一种技术可能会使您面临某些安全问题。例如,如果您从源自用户提供的数据的数据字段构建属性,则使用 Html.Raw 意味着字符串可能包含属性和标记的过早结束,然后开始一个脚本标记代表当前登录的用户执行某些操作用户(可能与登录用户不同)。也许您有一个包含所有用户图片列表的页面,并且您正在将工具提示设置为每个人的用户名,并且一个用户命名为他自己'/><script>$.post('changepassword.php?password=123')</script>
现在,查看此页面的任何其他用户的密码都会立即更改为恶意用户知道的密码。
回答by Yaschur
I guess a little more convenient and structured way is to use Html helper. In your view it can be look like:
我想更方便和结构化的方法是使用 Html helper。在您看来,它可能如下所示:
@{
var htmlAttr = new Dictionary<string, object>();
htmlAttr.Add("id", strElementId);
if (!CSSClass.IsEmpty())
{
htmlAttr.Add("class", strCSSClass);
}
}
@* ... *@
@Html.TextBox("somename", "", htmlAttr)
If this way will be useful for you i recommend to define dictionary htmlAttr
in your model so your view doesn't need any @{ }
logic blocks (be more clear).
如果这种方式对你有用,我建议htmlAttr
在你的模型中定义字典,这样你的视图就不需要任何@{ }
逻辑块(更清楚)。