在ASP.NET MVC Razor视图中将换行符替换为<br />


241

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

@ Model.CommentText

这可以正确编码任何值。但是,我想将换行符替换为<br />,但我找不到确保新的br标签不会被编码的方法。我尝试使用HtmlString,但还没有任何运气。


1
我假设换行符存储\n在数据库中,并且您想要转换为<br />
Marko 2010年

是的-只是尝试在视图中用<br />替换\ n。
bkaid 2010年

Answers:


678

使用CSS空格属性,而不是向XSS漏洞开放!

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

9
@Jacob Krall-我登录是为了给您+1。奇妙的小把戏。
Levi Botelho 2012年

6
quirksmode.org/css/whitespace.htmlpre-line(我只知道nowrappre)有很好的解释。
James Skemp 2012年

7
对此一无所知。绝对比我的答案更好。
奥马尔2012年

39
实际white-space: pre-wrap;情况更好,因为pre-line通过将空白分组为一个空格会弄乱您的文本。
Chtiwi Malek

4
不幸的是,这在几乎所有电子邮件客户端(包括Office 2013)中均不起作用。
罗杰·法尔(Roger Far)

115

尝试以下方法:

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

更新:

根据marcind's对此问题的评论,ASP.NET MVC团队正在寻求为Razor视图引擎实现与<%:和类似的东西<%=

更新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 />"))

13
哦,我的上帝,不。如果我决定的一些评论<script>
Darin Dimitrov

4
谢谢-很好。距离很近,但一定做得太早或太晚。我最终使用了这个:@ MvcHtmlString.Create(Html.Encode(Model.CommentText).Replace(“ \ n”,“ <br />”))),因为Environment.NewLine无法正常工作。
bkaid 2010年

2
Environment.NewLine并不真正适用于表单帖子,因为浏览器通常只返回\n而不是\r\n
Buildstarted

20
对于MVC 3的发行版本,建议似乎是@ Html.Raw(Html.Encode(Model.CommentText).Replace(Environment.NewLine,“ <br />”)),而不是使用MvcHtmlString。至少用于显示。
James Skemp 2011年

2
Environment.NewLine代表“ \ r \ n”。如果我的用户使用linux或mac输入数据,则换行符仅为“ \ n”或“ \ r”。那里没有一种方法可以考虑到这一点吗?
SandRock 2012年

11

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

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

(删除空条目是可选的)


10

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

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

5

DRY原理应用于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语义


4

我需要将一些文本分成几段(“ 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)

0

我更喜欢这种方法,因为它不需要手动发出标记。我之所以使用它,是因为我将Razor Pages渲染为字符串并通过电子邮件发送出去,而在这种环境下,空白样式不能总是起作用。

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;
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.