[asp.net-mvc] Replace line break characters with <br /> in ASP.NET MVC Razor view

I have a textarea control that accepts input. I am trying to later render that text to a view by simply using:

@Model.CommentText

This is properly encoding any values. However, I want to replace the line break characters with <br /> and I can't find a way to make sure that the new br tags don't get encoded. I have tried using HtmlString but haven't had any luck yet.

This question is related to asp.net-mvc asp.net-mvc-3 razor

The answer is


Use the CSS white-space property instead of opening yourself up to XSS vulnerabilities!

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

Omar's third solution as an HTML Helper would be:

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

Try the following:

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

Update:

According to marcind's comment on this related question, the ASP.NET MVC team is looking to implement something similar to the <%: and <%= for the Razor view engine.

Update 2:

We can turn any question about HTML encoding into a discussion on harmful user inputs, but enough of that already exists.

Anyway, take care of potential harmful user input.

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

Update 3 (Asp.Net MVC 3):

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

Split on newlines (environment agnostic) and print regularly -- no need to worry about encoding or xss:

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

(remove empty entries is optional)


I prefer this method as it doesn't require manually emitting markup. I use this because I'm rendering Razor Pages to strings and sending them out via email, which is an environment where the white-space styling won't always work.

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

I needed to break some text into paragraphs ("p" tags), so I created a simple helper using some of the recommendations in previous answers (thank you guys).

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

Usage:

@Html.ToParagraphs(Model.Comments)

Applying the DRY principle to Omar's solution, here's an HTML Helper extension:

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

Usage (with improved regex):

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

This also has the added benefit of putting less onus on the Razor View developer to ensure security from XSS vulnerabilities.


My concern with Jacob's solution is that rendering the line breaks with CSS breaks the HTML semantics.


Examples related to asp.net-mvc

Using Lato fonts in my css (@font-face) Better solution without exluding fields from Binding Vue.js get selected option on @change You must add a reference to assembly 'netstandard, Version=2.0.0.0 How to send json data in POST request using C# VS 2017 Metadata file '.dll could not be found The default XML namespace of the project must be the MSBuild XML namespace How to create roles in ASP.NET Core and assign them to users? The model item passed into the dictionary is of type .. but this dictionary requires a model item of type How to use npm with ASP.NET Core

Examples related to asp.net-mvc-3

Better solution without exluding fields from Binding IIs Error: Application Codebehind=“Global.asax.cs” Inherits=“nadeem.MvcApplication” Can we pass model as a parameter in RedirectToAction? return error message with actionResult Why is this error, 'Sequence contains no elements', happening? Failed to load resource: the server responded with a status of 500 (Internal Server Error) in Bind function 500.19 - Internal Server Error - The requested page cannot be accessed because the related configuration data for the page is invalid String MinLength and MaxLength validation don't work (asp.net mvc) How to set the value of a hidden field from a controller in mvc How to set a CheckBox by default Checked in ASP.Net MVC

Examples related to razor

Uncaught SyntaxError: Invalid or unexpected token How to pass a value to razor variable from javascript variable? error CS0103: The name ' ' does not exist in the current context how to set radio button checked in edit mode in MVC razor view @Html.DropDownListFor how to set default value Razor MVC Populating Javascript array with Model Array How to add "required" attribute to mvc razor viewmodel text input editor How to correctly use Html.ActionLink with ASP.NET MVC 4 Areas Multiple radio button groups in MVC 4 Razor How to hide a div element depending on Model value? MVC