我有一个接受输入的 textarea 控件。我试图稍后通过简单地使用将该文本呈现到视图中:
@Model.CommentText
这是正确编码任何值。但是,我想用 <br />
替换换行符,但我找不到确保新 br 标记不会被编码的方法。我曾尝试使用 HtmlString 但还没有任何运气。
\n
,您想转换为 <br />
?
使用 CSS white-space property 而不是让自己暴露于 XSS 漏洞!
<span style="white-space: pre-line">@Model.CommentText</span>
尝试以下操作:
@MvcHtmlString.Create(Model.CommentText.Replace(Environment.NewLine, "<br />"))
更新:
根据对 this related question 的 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 />"))
<script>
发表评论怎么办。
\n
而不是 \r\n
拆分换行符(与环境无关)并定期打印——无需担心编码或 xss:
@if (!string.IsNullOrWhiteSpace(text))
{
var lines = text.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
foreach (var line in lines)
{
<p>@line</p>
}
}
(删除空条目是可选的)
Omar 作为 HTML Helper 的第三个解决方案是:
public static IHtmlString FormatNewLines(this HtmlHelper helper, string input)
{
return helper.Raw(helper.Encode(input).Replace("\n", "<br />"));
}
将 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。
我需要将一些文本分成段落(“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)
我更喜欢这种方法,因为它不需要手动发出标记。我使用它是因为我将 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;
}
pre-line
有很好的解释(我只知道nowrap
和pre
)。white-space: pre-wrap;
更好,因为pre-line
会通过将空格组合成一个空格来弄乱您的文本。