ASP.NET MVC Razor görünümünde satır sonu karakterlerini <br /> ile değiştirin


241

Girdiyi kabul eden bir metin denetimi var. Daha sonra basitçe kullanarak bir görünüme bu metni işlemeye çalışıyorum:

@ Model.CommentText

Bu, herhangi bir değeri doğru bir şekilde kodlamaktadır. Ancak, satır sonu karakterleri değiştirmek istiyorum <br />ve yeni br etiketleri kodlanmış olmadığından emin olmak için bir yol bulamıyorum. HtmlString kullanmayı denedim ama henüz şansım olmadı.


1
Satır çizgilerinin \nveritabanında olduğu gibi depolandığını ve bir <br />?
Marko

Evet - sadece görünümde \ n yerine <br /> değiştirmeye çalışıyorum.
bkaid

Yanıtlar:


681

Kullanım CSS white-space özelliğini yerine XSS açıkları için kendini açma!

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

9
@Jacob Krall - Sadece +1 vermek için giriş yaptım. Fantastik küçük numara.
Levi Botelho

6
quirksmode.org/css/whitespace.html'nin iyi bir açıklaması var pre-line(sadece farkındaydım nowrapve pre).
James Skemp

7
Bunu bilmiyordum. Kesinlikle benimkinden daha iyi cevap.
Omar

39
aslında white-space: pre-wrap;daha iyi çünkü pre-linebeyaz boşlukları tek bir boşlukta gruplandırarak metninizi kirletecek.
Chtiwi Malek

4
Ne yazık ki bu hemen hemen hiçbir e-posta istemcisinde (Office 2013 dahil) çalışmaz.
Roger Far

115

Takip etmeyi dene:

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

Güncelleme:

Bu ilgili soruya yapılanmarcind's yoruma göre , ASP.NET MVC ekibi, benzer bir şey ve<%:<%= Jilet görünümü motoru için.

Güncelleme 2:

HTML kodlamasıyla ilgili herhangi bir soruyu zararlı kullanıcı girdileriyle ilgili bir tartışmaya dönüştürebiliriz, ancak bunun yeterli bir kısmı zaten mevcuttur.

Her neyse, potansiyel zararlı kullanıcı girdilerine dikkat edin.

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

Güncelleme 3 (Asp.Net MVC 3):

@Html.Raw(Html.Encode(Model.CommentText).Replace("\n", "<br />"))

13
Aman tanrım, hayır. Bazıları hakkında yorum yapmaya karar verirsem ne olur <script>?
Darin Dimitrov

4
Teşekkürler - işe yaradı. Çok yakın ama yerine çok geç veya çok geç yapmış olması gerekir. Bunu kullanarak sona erdirdim: @ MvcHtmlString.Create (Html.Encode (Model.CommentText) .Replace ("\ n", "<br />")) çünkü Environment.NewLine düzgün çalışmıyor.
bkaid

2
\n\r\n
Çevre.NewLine

20
MVC 3'ün yayınlanan sürümü için öneri, MvcHtmlString yerine @ Html.Raw (Html.Encode (Model.CommentText) .Replace (Environment.NewLine, "<br />")) gibi görünüyor. En azından görüntüleme için.
James Skemp

2
Environment.NewLine "\ r \ n" yi temsil eder. Kullanıcım linux veya mac kullanarak veri girdiyse, satır aralıkları yalnızca "\ n" veya "\ r" olur. Bir yerde bunu dikkate alan bir yöntem yok mu?
SandRock

11

Yeni satırlara bölün (çevre agnostik) ve düzenli olarak yazdırın - kodlama veya xss için endişelenmenize gerek yok:

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

(boş girişleri kaldırmak isteğe bağlıdır)


10

Omar'ın HTML Yardımcısı olarak üçüncü çözümü:

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

5

DRY prensibini Omar'ın çözümüne uygulayan bir HTML Yardımcısı uzantısı:

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

Kullanımı (iyileştirilmiş normal ifade ile):

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

Bu ayrıca, XSS güvenlik açıklarından güvenlik sağlamak için Razor View geliştiricisine daha az önem verme avantajına da sahiptir.


Jacob'un çözümü ile ilgili endişem, satır sonlarının CSS ile oluşturulmasının HTML anlambilimini kırmasıdır .


4

Bazı metinleri paragraflara bölmem gerekiyordu ("p" etiketleri), bu yüzden önceki yanıtlardaki bazı önerileri kullanarak basit bir yardımcı oluşturdum (teşekkürler çocuklar).

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

Kullanımı:

@Html.ToParagraphs(Model.Comments)

0

İşaretleme manuel olarak yayan gerektirmediği için bu yöntemi tercih ederim. Bunu kullanıyorum çünkü Razor Pages'ı dizelere dönüştürüyorum ve e-posta yoluyla gönderiyorum, bu da beyaz boşluk stilinin her zaman işe yaramayacağı bir ortam.

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;
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.