ASP.NET MVC Razorビューで改行文字を<br />に置き換えます


241

入力を受け入れるtextareaコントロールがあります。私は後でそのテキストを単にビューを使用してビューにレンダリングしようとしています:

@ Model.CommentText

これは値を適切にエンコードしています。しかし、改行文字を置き換えたいのです<br />が、新しいbrタグがエンコードされないようにする方法が見つかりません。私はHtmlStringを使用してみましたが、まだ運がありません。


1
\nデータベースと同じように改行が保存されていると思いますが、変換したい<br />ですか?
マルコ

はい-ビューで\ nを<br />に置き換えようとしています。
bkaid 2010年

回答:


678

XSSの脆弱性を利用する代わりに、CSSの空白スペースプロパティを使用してください。

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

9
@Jacob Krall-+1するためにログインしました。素晴らしい小さなトリック。
Levi Botelho

6
quirksmode.org/css/whitespace.htmlpre-line(私が知っていたのはnowrappre)の良い説明です。
James Skemp

7
これについて知りませんでした。私より間違いなく良い答え。
オマール

39
white-space: pre-wrap;は、pre-line空白を1つのスペースにグループ化することによってテキストを混乱させるので、実際には優れています。
Chtiwi Malek 2013

4
残念ながら、これはほとんどすべての電子メールクライアント(Office 2013を含む)では機能しません。
Roger Far

115

以下を試してください:

@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 />"))

13
ああ、神様、いいえ。一部についてコメントすることにした場合はどうなり<script>ますか。
Darin Dimitrov

4
ありがとう-うまくいきました。非常に近かったが、交換が早すぎたり遅すぎたりしたに違いない。私はこれを使用することになりました:@ MvcHtmlString.Create(Html.Encode(Model.CommentText).Replace( "\ n"、 "<br />")))。Environment.NewLineが正しく機能していなかったためです。
bkaid 2010年

2
Environment.NewLineは実際にはフォームの投稿には適用されません。ブラウザは通常、次の\n代わりに返されるためです\r\n
Buildstarted

20
MVC 3のリリースバージョンでは、MvcHtmlStringを使用する代わりに、提案は@ Html.Raw(Html.Encode(Model.CommentText).Replace(Environment.NewLine、 "<br />"))のようです。少なくとも表示用。
James Skemp、2011年

2
Environment.NewLineは「\ r \ n」を表します。ユーザーがLinuxまたはMacを使用してデータを入力した場合、改行は単に「\ n」または「\ r」になります。これを考慮に入れる方法はどこにもありませんか?
SandRock、2012年

11

改行(環境に依存しない)で分割し、定期的に印刷します-エンコーディングやxssを心配する必要はありません:

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

(空のエントリの削除はオプションです)


10

HTMLヘルパーとしてのOmarの3番目のソリューションは次のとおりです。

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

5

DRYの原則をOmarのソリューションに適用すると、HTMLヘルパー拡張機能が次のようになります。

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のセマンティクスが壊れることです


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

手動でマークアップを発行する必要がないため、この方法をお勧めします。これは、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;
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.