【问题标题】:Html literal in Razor ternary expressionRazor 三元表达式中的 Html 文字
【发布时间】:2011-10-14 23:49:08
【问题描述】:

我正在尝试执行以下操作

<div id="test">
    @(
        string.IsNullOrEmpty(myString)
          ? @:&nbsp;
          : myString   
    )
</div>

上述语法无效,我尝试了很多不同的方法,但无法正常工作。

【问题讨论】:

  • err...这不是一个真正的问题吗?如果你不明白,也许你应该要求澄清而不是试图关闭它。
  • 如果你只替换@会发生什么: 用“ ”?你需要 @: 做什么?
  • @Jamie:它将&amp;nbsp; 写入页面(作为字符串,而不是 html 代码)
  • 如果是这种情况,那么一定有一个 HTMLEncode 在某处进行。如果你看问题的根源,我猜它是:&nbsp;

标签: html asp.net-mvc-3 razor ternary-operator


【解决方案1】:
@(string.IsNullOrEmpty(myString)? ":&nbsp;": myString)

【讨论】:

    【解决方案2】:

    尝试以下方法:

    @Html.Raw(string.IsNullOrEmpty(myString) ? "&nbsp;" : Html.Encode(myString))
    

    但我建议你编写一个助手来完成这项工作,这样你就不必把你的观点变成意大利面条:

    public static class HtmlExtensions
    {
        public static IHtmlString ValueOrSpace(this HtmlHelper html, string value)
        {
            if (string.IsNullOrEmpty(value))
            {
                return new HtmlString("&nbsp;");
            }
            return new HtmlString(html.Encode(value));
        }
    }
    

    然后在你看来很简单:

    @Html.ValueOrSpace(myString)
    

    【讨论】:

    • 不,这也不起作用(打印   字符串)。我喜欢 html 助手的想法。 (在视图中使用 if/else 语句也很容易)。虽然我对 Razor 还是很陌生,但我很想将语法作为一种学习练习。
    • @fearofawhackplanet,这应该可以。你一定忘记了什么。你注意到我表情开头的Html.Raw了吗?正是因为开头使用了 Html.Raw,所以必须确保在字符串不为空的情况下正确地对字符串进行 HTML 编码。
    • 啊...呃,这很奇怪。我只是仔细检查了它,你是对的,它有效。昨天好像没有用,我想我一定是在某个地方打错了。谢谢!
    • 啊,谢谢你,达林。我将 Html.Raw() 放在三元组的一侧,这一直导致问题。也没想过要放在外面。 SMH。
    【解决方案3】:

    你可以这样做:

    @{
       Func<dynamic, object> a = (true ? 
            (Func<dynamic, object>)(@<text> Works1 </text>) 
            : (Func<dynamic, object>)(@<text> Works2 </text>));
       @a(new object());
    }
    

    或者让它内联:

    @(
      ((Func<dynamic, object>)(true == false 
          ? (Func<dynamic, object>)(@<text> Works2 </text>) 
          : (Func<dynamic, object>)(@<text> Works3 </text>)))
       (new object())
     )
    

    (请注意,以上所有内容也适用于一行,为了清楚起见,我只是将它们分开)

    不过OP的初衷也可以修改为可以工作,但是这个时候换行一定要保留:

    @(((Func<dynamic, object>)( true == true ? (Func<dynamic,object>)(@: Works
    ): (Func<dynamic, object>)(@: Not Works
    )))("").ToString())
    

    注意

    事实上,您只需要对运算符中的一个选项进行强制转换,而且您不必将动态作为 Func 的第一个选项,您可以给出任何内容,并且在评估时您可以给出相同的只要它与 Func 的第一个参数匹配即可。

    例如,您可以执行以下操作(我认为这是最短的版本):

        @(
          ((Func<int, object>)(true == false 
              ? (Func<int, object>)(@<text> Works2 </text>) 
              : @<text></text>))
           (0)
         )
    

    如果你经常使用它,继承Func是个好主意

    public class Razor : Func<dynamic, object>{}
    

    或者甚至可以为三元运算符编写一个包装器方法(或者甚至是一个 lambda 表达式,在这种情况下 [我不确定,但可能] 使用常规三元运算符并将强制转换推迟到被调用者)。

    【讨论】:

    • 这很优雅:)
    【解决方案4】:

    得益于新功能的另一种更新方法是在视图中创建一个辅助函数。这具有使语法更简洁的优点,特别是如果您要多次调用它。这对于跨站点脚本攻击也是安全的,无需调用 @Html.Encode(),因为它不依赖于 @Html.Raw()。

    只需将以下内容放在最顶部的视图中:

    @helper NbspIfEmpty(string value) {
      if (string.IsNullOrEmpty(value)) {
        @:&nbsp;
      } else {
        @value
      }
    }
    

    然后你可以像这样使用函数:

    <div id="test">
        @NbspIfEmpty(myString)
    </div>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-02-08
      • 2018-09-05
      • 2017-12-24
      • 2017-09-26
      • 2015-07-13
      • 1970-01-01
      • 2013-06-20
      • 1970-01-01
      相关资源
      最近更新 更多