แทนที่อักขระขึ้นบรรทัดใหม่ด้วย <br /> ในมุมมอง ASP.NET MVC Razor


241

ฉันมีตัวควบคุม textarea ที่รับอินพุต ฉันพยายามที่จะทำให้ข้อความในมุมมองในภายหลังโดยใช้:

@ Model.CommentText

นี่เป็นการเข้ารหัสค่าอย่างเหมาะสม อย่างไรก็ตามฉันต้องการแทนที่ตัวแบ่งบรรทัดด้วย<br />และฉันไม่สามารถหาวิธีเพื่อให้แน่ใจว่าแท็ก br ใหม่ไม่ได้รับการเข้ารหัส ฉันได้ลองใช้ HtmlString แล้วแต่ยังไม่มีโชค


1
ฉันเชื่อว่าการกระจายบรรทัดถูกจัดเก็บไว้\nในฐานข้อมูลและคุณต้องการแปลงเป็น<br />?
Marko

ใช่ - แค่พยายามแทนที่ \ n ด้วย <br /> ในมุมมอง
bkaid

คำตอบ:


681

ใช้คุณสมบัติพื้นที่สีขาว CSSแทนการเปิดช่องโหว่ XSS ด้วยตัวคุณเอง!

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

9
@Jacob Krall - ฉันลงชื่อเข้าใช้แล้วเพื่อให้ +1 เคล็ดลับเล็ก ๆ น้อย ๆ ที่ยอดเยี่ยม
Levi Botelho

6
quirksmode.org/css/whitespace.htmlมีคำอธิบายที่ดีเกี่ยวกับpre-line(ฉันเพิ่งทราบnowrapและpre)
James Skemp

7
ไม่ทราบเกี่ยวกับสิ่งนี้ คำตอบที่ดีกว่าแน่นอน
โอมาร์

39
จริง ๆ แล้วwhite-space: pre-wrap;จะดีกว่าเนื่องจากpre-lineจะยุ่งกับข้อความของคุณโดยการจัดกลุ่มช่องว่างสีขาวไว้ในที่เดียว
Chtiwi Malek

4
น่าเสียดายที่นี่ใช้งานไม่ได้กับไคลเอนต์อีเมลเกือบทุกตัว (รวมถึง Office 2013)
Roger Far

115

ลองทำสิ่งต่อไปนี้:

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

ปรับปรุง:

ตามmarcind'sความคิดเห็นเกี่ยวกับคำถามที่เกี่ยวข้องนี้ทีม ASP.NET MVC กำลังมองหาที่จะใช้บางสิ่งที่คล้ายกับ<%:และ<%=สำหรับเอ็นจิ้นมุมมองมีดโกน

อัปเดต 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 />"))

13
โอ้พระเจ้าของฉันไม่ <script>ถ้าฉันตัดสินใจที่จะแสดงความคิดเห็นเกี่ยวกับบางส่วน
ดารินทินดิมิทรอฟ

4
ขอบคุณ - ที่ใช้งานได้ อยู่ใกล้มาก แต่ต้องทำการเปลี่ยนใหม่เร็วเกินไปหรือช้าเกินไป ฉันลงเอยด้วยการใช้สิ่งนี้: @ MvcHtmlString.Create (Html.Encode (Model.CommentText). แทนที่ ("\ n", "<br />")) เนื่องจาก Environment.NewLine ทำงานไม่ถูกต้อง
bkaid

2
Environment.NewLine ไม่ได้ใช้กับโพสต์แบบฟอร์มจริงๆเนื่องจากเบราว์เซอร์มักจะกลับมา\nแทน\r\n
Buildstarted

20
สำหรับ MVC 3 เวอร์ชันที่วางจำหน่ายข้อเสนอแนะจะปรากฏเป็น @ Html.Raw (Html.Encode (Model.CommentText). แทนที่ (Environment.NewLine, "<br />") แทนการใช้ MvcHtmlString อย่างน้อยสำหรับการแสดงผล
James Skemp

2
Environment.NewLine เป็นตัวแทนของ "\ r \ n" หากผู้ใช้ของฉันป้อนข้อมูลโดยใช้ linux หรือ mac linebreaks เป็นเพียง "\ n" หรือ "\ r" ไม่มีวิธีใดที่จะนำสิ่งนี้มาพิจารณาหรือไม่?
SandRock

11

แยกบรรทัดใหม่ (ผู้ไม่เชื่อเรื่องสิ่งแวดล้อม) และพิมพ์อย่างสม่ำเสมอ - ไม่จำเป็นต้องกังวลเกี่ยวกับการเข้ารหัสหรือ xss:

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

(ลบรายการที่ว่างเปล่าเป็นตัวเลือก)


10

วิธีที่สามของ 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));
        }
    }
}

การใช้งาน (ปรับปรุง regex):

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

สิ่งนี้ยังมีประโยชน์เพิ่มเติมในการลดความรับผิดชอบลงบนผู้พัฒนา Razor View เพื่อรับประกันความปลอดภัยจากช่องโหว่ XSS


ความกังวลของฉันกับการแก้ปัญหาของยาโคบก็คือว่าการแสดงผลแบ่งบรรทัดที่มีการแบ่งแบบ CSS ความหมาย HTML


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)

0

ฉันชอบวิธีนี้มากกว่าเพราะไม่ต้องทำการมาร์คอัปด้วยตนเอง ฉันใช้สิ่งนี้เพราะฉันกำลังแสดงผลหน้ามีดโกนให้กับสตริงและส่งออกทางอีเมลซึ่งเป็นสภาพแวดล้อมที่พื้นที่จัดแต่งทรงผมในพื้นที่สีขาวจะไม่ทำงาน

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;
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.