How can I have New Line in Blazor

Viewed 8312

I'm trying to create a newline, and having already looked on other forums, some are using '\n', '\r' or Environment.NewLine but personally nothing works. I give you the code and the result :

1:

string n1 = SomeText;
string n2 = AnotherText;
string beforeStr = n1 + Environment.NewLine + n2;

2:

string n1 = SomeText;
string n2 = AnotherText;
string beforeStr = n1 + '\r' + n2;

3:

string n1 = SomeText;
string n2 = AnotherText;
string beforeStr = n1 + '\n' + n2;

always same result :

SomeText AnotherText
7 Answers

The MarkupString solution will swallow/interpret all non-escaped html characters. This can lead to a XSS attack with dynamic user input strings.
The way to go here is to html-escape first and then replace all line breaks with <br />

@using System.Web
@using System.Text.RegularExpressions;

<div>
  @((MarkupString)Regex.Replace(
    HttpUtility.HtmlEncode(@multilineString), "\r?\n|\r", "<br />"))
</div>

The regex \r?\n|\r will replace \r (old Mac), \r\n (Windows) and \n (Unix)

This can also be implemented as a Component.

MultilineString.razor

@using System.Web
@using System.Text.RegularExpressions;

@((MarkupString)Regex.Replace(HttpUtility.HtmlEncode(@Value), "\r?\n|\r", "<br />"))

@code {
    [Parameter]
    public string Value { get; set; } = default!;
}

Now it's easier to use with <MultilineString Value=@yourInput />

The only way I can think of is using Razor templates. \r\n, Envirnoment.Newline, and anything else cannot make the compiler budge.

Here is a working solution using Razor Template:

<p>@resultString</p>

@code {
    RenderFragment resultString =  @<p>Series not found <br />Error message</p>;
                          
}

Update: You can also use this:

MarkupString  resultString = (MarkupString) $"Series not found <br />Error message"; 

Update 2: From the documents:

Render raw HTML Blazor normally renders strings using DOM text nodes, which means that any markup they may contain will be ignored and treated as literal text. This new feature lets you render special MarkupString values that will be parsed as HTML or SVG and then inserted into the DOM.

WARNING: Rendering raw HTML constructed from any untrusted source is a major security risk!

Use the MarkupString type to add blocks of static HTML content.

@((MarkupString)myMarkup)

@functions {
    string myMarkup = "<p class='markup'>This is a <em>markup string</em>.</p>";
}

The document structure in the browser will be in HTML, so you need to be using HTML tags (<br />, specifically) to control the flow of the document.

string beforeStr = n1 + '<br />' + n2;

As mentioned by Panagiotis Kanavos, and presumably because you're using Blazor, you'll probably end up with something like this in your .razor component instead:

<p>
    @n1 <br /> @n2
</p>

I created a simple component LineBreaksToBRs. It avoids the risks of MarkupString.

@if (lines != null)
    for (int i = 0; i < lines.Length; i++)
    {
        @lines[i];
        <br />
    }

@code {
    string[] lines;

    [Parameter]
    public string InputString { get; set; }

    protected override void OnParametersSet()
    {
        lines = InputString?.Split('\n');
    }
}

and usage

...
<div class="field">
    <span>My Field</span>
    <span>
        <LineBreaksToBRs InputString=@Record.MyField />
    </span>
</div>
...

This is what I got to work for me. In my razor file I added this:

@foreach (var item in References)
{
    <br />
    @item
}

In my C# class I added this:

protected List<string> References { get; set; } = new List<string>();

Just fill in the reference with each line of text you ant and it works great. I found a lot of other solutions but this was easiest to me.

This works pretty good with me

@foreach (var sub in beforeStr.Split('\n'))
{
    @sub <br/>
}

@code{
string n1 = SomeText;
string n2 = AnotherText;
string beforeStr = n1 + '\n' + n2;
}

I am not very good at html, and this is what I use to create a new line. There is probably a better way, but this works for me:

<div style="display:inline;"> one line</div>

Another way for an empty line is:

<div style="height:1em;"></div>
Related