Замените символы разрыва строки с помощью <br/"> в представлении ASP.NET MVC Razor

У меня есть элемент управления textarea, который принимает ввод. Я пытаюсь позже сделать этот текст для просмотра, просто используя:

@Model.CommentText

Это правильно кодирует любые значения. Тем не менее, я хочу заменить символы разрыва строки на <br />, и я не могу найти способ убедиться, что новые br-теги не закодированы. Я пробовал использовать HtmlString, но еще не успел.

Ответ 1

Используйте свойство белого пробела CSS вместо того, чтобы открывать себя для уязвимостей XSS!

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

Ответ 2

Попробуйте следующее:

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

Обновление:

В соответствии с 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 />"))

Ответ 3

Разделить на новые строки (агностик среды) и регулярно печатать - не нужно беспокоиться о кодировке или xss:

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

(удалить пустые записи необязательно)

Ответ 4

Третьим решением Omar в качестве HTML-помощника будет:

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

Ответ 5

Применяя принцип DRY к решению 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.

Ответ 6

Мне нужно было разбить текст на абзацы ( "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)