为什么 StringBuilder.AppendLine() 方法在某些字符串中不添加换行符?

42

我正在尝试使用StringBuilder创建一个纯文本邮件正文,但是某些行(包含动态数据的行)没有添加换行符,而在某些行上换行符按预期工作。

我是否在使用StringBuilder类时遗漏了一些基本内容,或者应该发生一些更基本的过程?

以下是代码:

sbUser.AppendLine("Please find below confirmation of your registration details. If any of these details are incorrect, please email someone@somewhere.com");
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和thisEvent是使用Subsonic(v2)构建的自定义类。PageTitle是一个字符串输出类型)

将得到以下输出:

    Please find below confirmation of your registration details. If any of these details are incorrect, please email someone@somewhere.com

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

你可以看到,代码中第三行后的所有内容都在一行上。

然而,在代码的下方我使用了:

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

所有这些内容都单独显示在正确的行上。我不明白为什么会这样。

电子邮件是这样组成的

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


添加以下代码:

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

将会产生以下输出:

Selected event : My Event

Date of event : 16 Sept 2012

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

这个方法似乎是有效的,但它添加了两个新行(AppendLine和Environment.NewLine)。直接从数据库中将数据提取到StringBuilder中似乎会对行结尾产生影响。即使我在数据库提取后添加文本,它仍然保持在一行上。

更新

使用以下代码:StringBuilder.Append("blah"+Environment.NewLine)可以产生正确的结果,不过我仍然不明白为什么 .AppendLine("blah"+<database content>) 不起作用。


PageTitle返回的值是否有可能会出现奇怪的值来打断文本流?或者被调用的代码是否暂时更改了区域设置或换行设置?换句话说,如果您硬编码“我的事件”,问题是否仍然存在?编辑猜测您的编辑回答了这种怀疑;) - Me.Name
你能否尝试使用默认容量创建StringBuilder?例如:StringBuilder sb = new StringBuilder(1024); - Steve
@Steve - 这会有什么不同吗? - kolin
我只是在尝试一些不同的东西。查看 StringBuilder.AppendLine 的源代码,你的代码应该可以直接使用,无需添加 Environment.NewLine。另一个尝试是将 ContentPage.FetchByID 的结果复制到临时字符串中,并在调试会话中查看其内容。 - Steve
@Steve,临时字符串的结果就是一个没有多余字符或空格的字符串。 - kolin
显示剩余2条评论
6个回答

46

我知道这个问题很旧并且已经被标记为已回答,但我想在这里添加一些内容,以防其他人遇到这个问题,因为它是在Google上搜索 StringBuilder.AppendLine() 时的第一个结果。

我遇到了同样的问题,原来是Outlook的问题。 Outlook会通过删除额外的换行符来重新格式化基于文本的电子邮件。您可以在每封电子邮件的标题中单击“我们删除了此消息中的额外换行符->恢复换行符”,或更改执行此不良小花招的设置 “选项->邮件->邮件格式->在纯文本消息中删除额外的换行符”

解决方法(因为您无法控制每个潜在电子邮件目标上的设置)在这里找到 Newsletter Formatting And The Remove Extra Line Breaks Issue. 基本上,如果您在每行开头添加两个空格字符,Outlook就不会重新格式化该电子邮件。

这是一个扩展方法来帮助您(方法名称有点冗长,所以请根据您的喜欢进行更改 :))

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

谢谢!它甚至在消息上方说它为我剥离了“不必要的换行符”(在阅读您的答案后我意识到了这一点)。很棒的默认行为...我只是这样做的:" " + myString.Replace(Environment.NewLine, Environment.NewLine + " ") - Knickedi
1
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - PBMe_HikeIt
前缀每行两个空格(此答案)是正确的答案。只使用其他答案建议的Environment.NewLine不起作用。 - Marquez

29

不要使用

sbUser.AppendLine();

尝试使用

sbUser.Append(Environment.NewLine);

不知道为什么这个方法有效...


12
AppendLine 方法只是调用 this.Append(Environment.NewLine)。 - Chris S
3
这可以得到正确的结果,但为什么这样做有效而不是使用AppendLine? - kolin
3
在反编译 StringBuilder 类后,它显示它在内部执行 this.Append(Environment.NewLine);。因此从技术上讲,两者应该给出相同的结果。 - Parag Meshram
2
我知道,这是一个问题。在我的机器上,这给出了正确的结果,这让人感到困惑。 - oleksii
3
只需在 StringBuilder 上调用 ToString(),即可获得您的新行;) - Nickmaovich

6
使用Environment.NewLine
sbUser.AppendLine("Please find below confirmation of your registration details. If any of these details are incorrect, please email someone@somewhere.com");
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);

sbUser.appendline("=======..... 之后,行附加会自动恢复正常。 - kolin
你是在执行sbUser.ToString()后面的吗?还是只是执行了它本身? - Liam
2
默认的行终止符是 Environment.NewLine 属性的当前值。 - V4Vendetta
3
AppendLine简单地调用this.Append(Environment.NewLine)。 - Chris S

0

在每行末尾或需要新行的地方使用 Environment.NewLine

例如:

  sbUser.AppendLine("Please find below confirmation of your registration details. If any of these details are incorrect, please email someone@somewhere.com" + Environment.NewLine);
  sbUser.AppendLine("Selected event : " + ContentPage.FetchByID(int.Parse(ddlEvent.SelectedValue)).PageTitle); 

0

Windows 10 Insider 预览版 Build 15007。默认的行终止符和 Environment.NewLine 都是 "\n"。要使用 "\r\n",我必须创建一个字符串常量并使用它。


1
我有一种感觉,这种事情永远不会发生,因为那将是一个破坏性的变化。你是在使用 .Net Core 而不是 .Net Framework 吗?当针对 4.6.2 版本时,在构建 16199 .Net Framework 时我得到了 CRLF。 - binki

-3

首先 sbUser.Appendline();

其次 sbUser.Append("texto loco ");

大功告成!

=)


你的意思真的不太清楚。请格式化你的回答,并添加更多解释为什么这样做是有效的。 - ryanyuyu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接