ASP.NET MVC将\n转换为HTML断行

33

我在MVC中有一个textarea。 当在其中输入数据并将其显示给用户时,如何显示换行符?

我是这样显示的:

<%= Model.Description%>

在一行中。没有创建<br /> - Shawn Mclean
2
实际上,这里接受的答案提供了一个更好的实现: https://dev59.com/J2855IYBdhLWcg3wpmLw - Nullius
这个回答解决了你的问题吗?在ASP.NET MVC Razor视图中使用<br />替换换行符 - avs099
11个回答

51
以下类实现了一个HtmlHelper,可以正确地对文本进行编码:
public static class HtmlExtensions
{
    public static MvcHtmlString Nl2Br(this HtmlHelper htmlHelper, string text)
    {
        if (string.IsNullOrEmpty(text))
            return MvcHtmlString.Create(text);
        else
        {
            StringBuilder builder = new StringBuilder();
            string[] lines = text.Split('\n');
            for (int i = 0; i < lines.Length; i++)
            {
                if (i > 0)
                    builder.Append("<br/>\n");
                builder.Append(HttpUtility.HtmlEncode(lines[i]));
            }
            return MvcHtmlString.Create(builder.ToString());
        }
    }
}

在视图中使用它非常容易:

<%= Html.Nl2Br(Model.MultilineText) %>

或使用 Razor:

@Html.Nl2Br(Model.MultilineText)

15
这个HtmlExtensions业务正是我所寻找的。但是,为什么不用 return MvcHtmlString.Create(HttpUtility.HtmlEncode(text).Replace("\n", "<br />")); 来替换整个body呢? - Chris
我会自己编辑你的答案,添加文本空引用检查。 - horgh
为什么要用 br 替换 \n,如果你可以保留 \n 并添加 br,这样在查看源代码时会更容易阅读。因此,最终结果应该选择 \n br 或 br \n,而不是仅使用 br。 - Michiel Cornille
这是正确的方法:https://dev59.com/J2855IYBdhLWcg3wpmLw - Guido Zanon
2
请显示所有的导入/包含,因为MvcHtmlString不是默认存在的。 - rollsch
@rolls 我已经有一段时间没有使用ASP.NET MVC进行开发了,也没有系统可以检查导入。 - Codo

28

为了以稍微不同(而且,我认为更好、更安全)的方式解决这个问题,请参见类似问题的这个答案

基本上,与其费力地将所有换行符转换为<br>元素,还不如将以下CSS应用于显示输入文本的元素:

white-space: pre-line

2
我可能是唯一一个遇到这个问题的傻瓜,但为了节省下一个人的时间:如果你这样做,请确保删除你的 div 内所有多余的换行符。 - Hugh Seagraves
这在所有邮件客户端中都不起作用。请使用@Codo的解决方案。 - Flappy

11

为确保安全性,始终对用户输入的文本进行编码,然后在视图中显示。

您可以像Cybernate建议的那样操作,也可以将其添加到HtmlHelper扩展方法中。

public static string EncodedMultiLineText(this HtmlHelper helper, string text) {
  if (String.IsNullOrEmpty(text)) {
    return String.Empty;
  }
  return Regex.Replace(helper.Encode(text), Environment.NewLine, "<br/>")
}

这样它可以在视图中轻松地被重复使用

<%= Html.EncodedMultiLineText(Model.Description) %>

2
抱歉在我的评论中鼓励编码,却在自己的代码中忘了。失败了。 - David Glenn

7
对于Asp.net MVC razor,我使用Html.Encode来防止XSS攻击。
@Html.Raw(Html.Encode(Model.Description).Replace(Environment.NewLine, "<br />"))

6

尝试类似以下代码:

<%=
Regex.Replace(
              Html.Encode(Model.Description), 
              Environment.NewLine, 
              "<br/>", 
              RegexOptions.IgnoreCase||RegexOptions.Multiline
             )
%>

1
为什么这个得票最高?是因为它最有效率还是最安全? - Shawn Mclean
它可能因为是最古老的而具有一些优势。 - patridge
2
这里不应该使用 Regex.Replace - SLaks

5
上面提供的静态HTML帮助器扩展的答案提供了一个过时的构造函数:
return new MvcHtmlString(builder.ToString());

这行代码可以被以下代码替换:

return MvcHtmlString.Create((builder.ToString()));

发现示例还有另一个问题。当输入为空时会出错。可以通过在方法的第一行插入以下代码来解决:if(text == null) return MvcHtmlString.Create(text); - Roland Schaer
非常感谢您。我从来不知道它会出问题。 - Shawn Mclean
感谢您的点赞。现在我可以添加评论,而不必将这些愚蠢的片段发布为答案了。 - Roland Schaer

4

1

输出未经编码的用户输入文本非常危险。即使在原始问题中没有使用编码,也应该鼓励使用编码。 - David Glenn

1

我喜欢使用HtmlExtensions、Environment.NewLine和Regex,它们分别在不同的答案中提到,因此我将以上答案整合到一个方法中。

public static MvcHtmlString MultiLineText(this HtmlHelper htmlHelper, string text) {
 if (string.IsNullOrEmpty(text)) {
     return MvcHtmlString.Create(string.Empty);
 }
 return MvcHtmlString.Create(Regex.Replace(HttpUtility.HtmlEncode(text), Environment.NewLine, "<br/>"));
}

使用

<%= Html.MultiLineText(Model.MultilineText) %>

或者

@Html.MultiLineText(Model.MultilineText)

0
这对我很有用 -

<%= HttpUtility.HtmlDecode(Html.ActionLink("AOT <br/> Claim #", "actionName" ))%>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接