代码之家  ›  专栏  ›  技术社区  ›  bkaid

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

  •  228
  • bkaid  · 技术社区  · 14 年前

    我有一个接受输入的文本区域控件。稍后,我试图将该文本呈现为一个视图,只需使用:

    @模型.CommentText

    这是对任何值的正确编码。但是,我想用 <br /> 而且我找不到方法来确保新的br标记不会被编码。我试过使用HtmlString,但还没有任何运气。

    6 回复  |  直到 14 年前
        1
  •  649
  •   Jacob Krall    7 年前

    使用 CSS white-space property 而不是打开自己的XSS漏洞!

    <span style="white-space: pre-line">@Model.CommentText</span>
    
        2
  •  116
  •   Community Jaime Torres    7 年前

    请尝试以下操作:

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

    更新:

    根据 marcind's 评论 this related question ,ASP.NET MVC团队正在寻找实现类似于 <%: <%= 用于Razor view引擎。

    更新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 />"))
    
        3
  •  10
  •   drzaus tranceporter    10 年前

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

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

    (删除空条目是可选的)

        4
  •  10
  •   thelem    9 年前

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

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

    应用 DRY principle 对于Omar的解决方案,这里有一个HTML帮助程序扩展:

    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));
            }
        }
    }
    

    用法(使用改进的regex):

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

    这还有一个额外的好处,就是减少Razor视图开发人员的负担,以确保XSS漏洞的安全性。


    我对Jacob的解决方案的关注是,用CSS将换行符转换为 HTML semantics .

        6
  •  4
  •   Andrea    10 年前

    我需要将一些文本分成段落(“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
  •  0
  •   James S.    5 年前

    我更喜欢这种方法,因为它不需要手动发出标记。我使用这个是因为我将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;
    }