我有一个接受输入的textarea控件。我试图稍后通过简单地使用:
将该文本呈现给视图@ Model.CommentText
这正确编码任何值。但是,我想用<br />
替换换行符,我找不到确保新的br标签不被编码的方法。我尝试过使用HtmlString,但还没有运气。
答案 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 question的marcind's
评论,ASP.NET MVC团队正在寻求为Razor视图引擎实现类似于<%:
和<%=
的内容。< / p>
我们可以将有关HTML编码的任何问题转变为有害用户输入的讨论,但已经存在足够的内容。
无论如何,要注意潜在的有害用户输入。
@MvcHtmlString.Create(Html.Encode(Model.CommentText).Replace(Environment.NewLine, "<br />"))
@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;
}