Why does StringBuilder.AppendLine not add a new line with some strings?
Asked Answered
H

6

43

I'm trying to use stringbuilder to create a body of string to be used in a text (not HTML) email. However some lines (where i include dynamic data, a new line is not added, but in some the newline works as intended.

Is there something basic i'm missing when using the stringbuilder class or is there some more fundamental process that should be happening?

in the below code:

sbUser.AppendLine("Please find below confirmation of your registration details. If any of these details are incorrect, please email [email protected]");
sbUser.AppendLine();
sbUser.AppendLine("Selected event : " + ContentPage.FetchByID(int.Parse(ddlEvent.SelectedValue)).PageTitle); 
sbUser.AppendLine("Date of event : " + thisEvent.EventStartDate.ToString("dd MMM yyyy"));
sbUser.AppendLine("==============================================================");
sbUser.AppendLine();

(ContentPage and thisEvent are custom classes built using Subsonic(v2). PageTitle is an output type of string)

is get this as an output:

    Please find below confirmation of your registration details. If any of these details are incorrect, please email [email protected]

Selected event : My Event Date of event : 16 Sept 2012 ==============================================================

as you can see, everything after the 3rd line in the code makes everything go on to one line.

however, further down the code i use:

sbRR.AppendLine("First name : " + txtFirstname.Text.Trim());
sbRR.AppendLine("Surname : " + txtSurname.Text.Trim());
etc,

and all these appear on seperate lines correctly. I can't see why this is happening.

the email is composed as such

mailMessage.Body = sbUser.ToString() + sbRR.ToString();


adding the following code:

sbUser.AppendLine("Selected event : " + ContentPage.FetchByID(int.Parse(ddlEvent.SelectedValue)).PageTitle + Environment.NewLine); 
sbUser.AppendLine("Date of event : " + thisEvent.EventStartDate.ToString("dd MMM yyyy") + Environment.NewLine);

produces the following output:

Selected event : My Event

Date of event : 16 Sept 2012

==============================================================

which works i suppose, except it's added 2 newlines (the AppendLine and the Environment.NewLine). it seems that pulling the data directly straight from the database into a stringbuilder seems to be messing with the line ending. Even if I add text after the database pull, it still stays on one line.

UPDATE

doing StringBuilder.Append("blah"+Environment.NewLine) produces the correct result, however i'm still not understanding why that works and .AppendLine("blah"+<database content>) doesn't work.

Hogback answered 22/6, 2012 at 12:4 Comment(7)
Are you doing anything to the string after the sbUser.ToString() call?Cindicindie
Is there any chance that PageTitle returns strange values that could interrupt the text flow? Or else that the called code temporarily changes culture or the newline setting? In other words, if you hardcode "my event", does the problem persist? edit guess your edit answers confirms that suspicion ;)Williemaewillies
Could you try to create the StringBuilder with a default capacity? For example: StringBuilder sb = new StringBuilder(1024);Haycock
@Williemaewillies the database the data is returned from has a collation of SQL_Latin1_General_CP1_CI_AS and the column data type is nvarchar(150) not sure why this would change the culture (en-GB) although the language of the database server is english (US)Hogback
@Haycock - how would this make a difference?Hogback
I'm just trying something different. Looking at the source code of StringBuilder.AppendLine, your code should work as is, no need to add Environment.NewLine. Another try will be to copy the result of ContentPage.FetchByID in a temporary string and look in a debug session its content.Haycock
@Steve, the temporary string results in that, it's just a string with no extraneous characters or space.Hogback
N
29

Instead of

sbUser.AppendLine();

Try using

sbUser.Append(Environment.NewLine);

No idea why this works...

Non answered 22/6, 2012 at 12:7 Comment(5)
AppendLine simply calls this.Append(Environment.NewLine);Cindicindie
this gives the correct result, but why would this work and not AppendLine?Hogback
After de-compiling StringBuilder class it shows that it is internally executing this.Append(Environment.NewLine);. So technically both should give the same resultSulfurous
I know and that's a problem. On my machine this gives correct result and it is puzzling.Non
You simply call ToString() on StringBuilder, and get your new lines;)Vilmavim
L
48

I know the question is old and has been marked as answered, but I thought I'd add this here in case anyone else comes across this as it's the first hit on Google for StringBuilder.AppendLine() not working.

I had the same problem and it turned out to be an Outlook issue. Outlook re-formats text based emails by removing extra line breaks. You can click "We removed extra line breaks in this message -> Restore line breaks" in the header of the individual email, or change the setting that does this nasty little trick "Options->Mail->Message Format->Remove extra line breaks in plain text messages"

The workaround (since you can't control the settings on every potential email target) I found here Newsletter Formatting And The Remove Extra Line Breaks Issue. Basically, if you add two white space characters to the beginning of each line, Outlook won't reformat the email.

Here's an extension method to help (method name is a bit verbose so change to your liking :))

namespace System.Text
{
    public static class StringBuilderExtensions
    {
        public static void AppendLineWithTwoWhiteSpacePrefix(this StringBuilder sb, string value)
        {
            sb.AppendFormat("{0}{1}{2}", "  ", value, Environment.NewLine);
        }

        public static void AppendLineWithTwoWhiteSpacePrefix(this StringBuilder sb)
        {
            sb.AppendFormat("{0}{1}", "  ", Environment.NewLine);
        }
    }
}
Lambdacism answered 21/7, 2014 at 8:26 Comment(3)
Thank you! It did even say it above the message that it stripped "unnecessary line breaks" for me (which I realized after reading your answer). Great default behaviour... I just did this: " " + myString.Replace(Environment.NewLine, Environment.NewLine + " ")Annoy
This actually does not seem to work if the message is formatted as HTML. See https://mcmap.net/q/295346/-how-to-create-a-multi-line-body-in-c-system-net-mail-mailmessage using <br /> tagsGredel
Prefixing each line with two blank spaces (this answer) is the correct answer. Just using Environment.NewLine as suggested by the other answers does not work.Biagio
N
29

Instead of

sbUser.AppendLine();

Try using

sbUser.Append(Environment.NewLine);

No idea why this works...

Non answered 22/6, 2012 at 12:7 Comment(5)
AppendLine simply calls this.Append(Environment.NewLine);Cindicindie
this gives the correct result, but why would this work and not AppendLine?Hogback
After de-compiling StringBuilder class it shows that it is internally executing this.Append(Environment.NewLine);. So technically both should give the same resultSulfurous
I know and that's a problem. On my machine this gives correct result and it is puzzling.Non
You simply call ToString() on StringBuilder, and get your new lines;)Vilmavim
P
6

use Environment.NewLine

sbUser.AppendLine("Please find below confirmation of your registration details. If any of these details are incorrect, please email [email protected]");
sbUser.AppendLine(Environment.NewLine);
sbUser.AppendLine("Selected event : " + ContentPage.FetchByID(int.Parse(ddlEvent.SelectedValue)).PageTitle); 
sbUser.AppendLine("Date of event : " + thisEvent.EventStartDate.ToString("dd MMM yyyy"));
sbUser.AppendLine("==============================================================");
sbUser.AppendLine(Environment.NewLine);
Privily answered 22/6, 2012 at 12:7 Comment(4)
after sbUser.appendline("=======..... the line appending returns to normal by itself.Hogback
does it? Or are you doing sbUser.ToString()? after that?Privily
The default line terminator is the current value of the Environment.NewLine propertyMaillot
AppendLine simply calls this.Append(Environment.NewLine);Cindicindie
I
0

use Environment.NewLine after each line or where you want new line

eg:-

  sbUser.AppendLine("Please find below confirmation of your registration details. If any of these details are incorrect, please email [email protected]" + Environment.NewLine);
  sbUser.AppendLine("Selected event : " + ContentPage.FetchByID(int.Parse(ddlEvent.SelectedValue)).PageTitle); 
Impenetrable answered 22/6, 2012 at 12:8 Comment(0)
T
0

Windows 10 Insider preview Build 15007. The Default Line Terminator and the Environment.NewLine are both "\n". To use "\r\n" I had to create a string constant and use it instead.

Tipton answered 15/1, 2017 at 23:11 Comment(1)
I have a feeling that such a thing would never happen because that’d be a breaking change. Are you using .Net Core instead of .Net Framework or something? I get CRLF on build 16199 .Net Framework when targeting 4.6.2.Marmot
R
-3

First sbUser.Appendline();

Second sbUser.Append("texto loco ");

Voila!

=)

Resupinate answered 11/6, 2015 at 18:54 Comment(1)
It's really not clear what you mean. Please format your answer and add more explanation to why this works.Timmy

© 2022 - 2024 — McMap. All rights reserved.