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

时间:2010-11-18 22:42:02

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

我有一个接受输入的textarea控件。我试图稍后通过简单地使用:

将该文本呈现给视图
  

@ Model.CommentText

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

7 个答案:

答案 0 :(得分:617)

使用CSS white-space property代替自己打开XSS漏洞!

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

答案 1 :(得分:110)

尝试以下方法:

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

更新

根据对this related questionmarcind's评论,ASP.NET MVC团队正在寻求为Razor视图引擎实现类似于<%:<%=的内容。< / p>

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

答案 2 :(得分:9)

拆分换行符(环境不可知)并定期打印 - 无需担心编码或xss:

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

(删除空条目是可选的)

答案 3 :(得分:9)

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

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

答案 4 :(得分:4)

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漏洞的安全性。


我对雅各布的解决方案的关注是用CSS渲染换行会打破HTML semantics

答案 5 :(得分: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)

答案 6 :(得分: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;
}