【问题标题】:Replace line break characters with <br /> in ASP.NET MVC Razor view在 ASP.NET MVC Razor 视图中用 <br /> 替换换行符
【发布时间】:2011-05-12 08:19:11
【问题描述】:

我有一个接受输入的 textarea 控件。我试图稍后通过简单地使用将该文本呈现到视图中:

@Model.CommentText

这是正确编码任何值。但是,我想用&lt;br /&gt; 替换换行符,但我找不到确保新的 br 标签不被编码的方法。我曾尝试使用 HtmlString 但还没有任何运气。

【问题讨论】:

  • 我认为换行符在数据库中存储为\n,您想转换为&lt;br /&gt;
  • 是的 - 只是尝试在视图中将 \n 替换为

标签: asp.net-mvc asp.net-mvc-3 razor


【解决方案1】:

使用CSS white-space property 而不是让自己暴露于 XSS 漏洞!

<span style="white-space: pre-line">@Model.CommentText</span>

【讨论】:

  • @Jacob Krall - 我登录只是为了给你一个 +1。很棒的小技巧。
  • quirksmode.org/css/whitespace.htmlpre-line 有很好的解释(我只知道nowrappre)。
  • 不知道这个。绝对比我的答案更好。
  • 实际上white-space: pre-wrap; 更好,因为pre-line 会通过将空格组合成一个空格来混淆您的文本。
  • 不幸的是,这几乎不适用于任何电子邮件客户端(包括 Office 2013)。
【解决方案2】:

尝试以下方法:

@MvcHtmlString.Create(Model.CommentText.Replace(Environment.NewLine, "<br />"))

更新:

根据marcind'sthis related question 的评论,ASP.NET MVC 团队正在寻求为 Razor 视图引擎实现类似于 &lt;%:&lt;%= 的东西。

更新 2:

我们可以将任何关于 HTML 编码的问题转化为对有害用户输入的讨论,但已经存在足够多的问题了。

无论如何,请注意潜在的有害用户输入。

@MvcHtmlString.Create(Html.Encode(Model.CommentText).Replace(Environment.NewLine, "<br />"))

更新 3(Asp.Net MVC 3):

@Html.Raw(Html.Encode(Model.CommentText).Replace("\n", "<br />"))

【讨论】:

  • 天哪,不。如果我决定评论一些&lt;script&gt;.
  • 谢谢 - 成功了。非常接近,但一定是太早或太晚了。我最终使用了这个:@MvcHtmlString.Create(Html.Encode(Model.CommentText).Replace("\n", "
    ")) 因为 Environment.NewLine 工作不正常。
  • Environment.NewLine 并不真正适用于表单帖子,因为浏览器通常只返回 \n 而不是 \r\n
  • 对于 MVC 3 的发布版本,建议似乎是 @Html.Raw(Html.Encode(Model.CommentText).Replace(Environment.NewLine, "
    ")),而不是使用 MvcHtmlString。至少是为了展示。
  • 即使使用 MVC3,这个解决方案看起来也很丑陋。它相当长,您必须仔细查看以确保所有内容都正确编码,并且您在使用不同类型的换行符时遇到问题。下面的基于 CSS 的解决方案要好得多!
【解决方案3】:

在换行符处拆分(与环境无关)并定期打印——无需担心编码或 xss:

@if (!string.IsNullOrWhiteSpace(text)) 
{
    var lines = text.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
    foreach (var line in lines)
    {
        <p>@line</p>
    }
}

(删除空条目是可选的)

【讨论】:

    【解决方案4】:

    Omar 作为 HTML Helper 的第三个解决方案是:

    public static IHtmlString FormatNewLines(this HtmlHelper helper, string input)
    {
        return helper.Raw(helper.Encode(input).Replace("\n", "<br />"));
    }
    

    【讨论】:

      【解决方案5】:

      DRY principle 应用于 Omar 的解决方案,这是一个 HTML Helper 扩展:

      using System.Web.Mvc;
      using System.Text.RegularExpressions;
      
      namespace System.Web.Mvc.Html {
          public static class MyHtmlHelpers {
              public static MvcHtmlString EncodedReplace(this HtmlHelper helper, string input, string pattern, string replacement) {
                  return new MvcHtmlString(Regex.Replace(helper.Encode(input), pattern, replacement));
              }
          }
      }
      

      用法(使用改进的正则表达式):

      @Html.EncodedReplace(Model.CommentText, "[\n\r]+", "<br />")
      

      这还有一个额外的好处,那就是减轻 Razor View 开发人员的负担,以确保免受 XSS 漏洞的影响。


      我对 Jacob 的解决方案的担忧是,使用 CSS 渲染换行符会破坏 HTML semantics

      【讨论】:

        【解决方案6】:

        我需要将一些文本分成段落(“p”标签),所以我使用以前答案中的一些建议创建了一个简单的助手(谢谢你们)。

        public static MvcHtmlString ToParagraphs(this HtmlHelper html, string value) 
            { 
                value = html.Encode(value).Replace("\r", String.Empty);
                var arr = value.Split('\n').Where(a => a.Trim() != string.Empty);
                var htmlStr = "<p>" + String.Join("</p><p>", arr) + "</p>";
                return MvcHtmlString.Create(htmlStr);
            }
        

        用法:

        @Html.ToParagraphs(Model.Comments)
        

        【讨论】:

          【解决方案7】:

          我更喜欢这种方法,因为它不需要手动发出标记。我使用它是因为我将 Razor 页面呈现为字符串并通过电子邮件发送出去,这是一个空白样式并不总是有效的环境。

          public static IHtmlContent RenderNewlines<TModel>(this IHtmlHelper<TModel> html, string content)
          {
              if (string.IsNullOrEmpty(content) || html is null)
              {
                  return null;
              }
          
              TagBuilder brTag = new TagBuilder("br");
              IHtmlContent br = brTag.RenderSelfClosingTag();
              HtmlContentBuilder htmlContent = new HtmlContentBuilder();
          
              // JAS: On the off chance a browser is using LF instead of CRLF we strip out CR before splitting on LF.
              string lfContent = content.Replace("\r", string.Empty, StringComparison.InvariantCulture);
              string[] lines = lfContent.Split('\n', StringSplitOptions.None);
              foreach(string line in lines)
              {
                  _ = htmlContent.Append(line);
                  _ = htmlContent.AppendHtml(br);
              }
          
              return htmlContent;
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2013-11-04
            • 2011-11-14
            • 1970-01-01
            • 2022-08-07
            • 1970-01-01
            • 2011-07-13
            • 1970-01-01
            相关资源
            最近更新 更多