ASP.NET 初學者常遇到:資料庫儲存含換行符(\r\n、\n)的文字,顯示在 Label、Literal、GridView 時卻不換行,全部擠在一行。根因為 HTML 忽略換行字元,需轉換為 <br /> 或使用 CSS white-space: pre-wrap。本文提供 C#、VB.NET 完整解決方案。
\r\n (CRLF)、Unix/Linux \n (LF)、Mac 舊版 \r (CR)。<br />、<p></p>。white-space: pre-wrap;(推薦現代做法)。public static string HtmlCode(string input)
{
if (string.IsNullOrEmpty(input)) return "無內容";
// 統一換行符為 \n
string text = input.Replace("\r\n", "\n").Replace("\r", "\n");
// 選項 A:替換為
(適合 Label、Literal Mode=Transform)
// return text.Replace("\n", "
");
// 選項 B:替換為 段落(適合語意化)
// return "
" + text.Replace("\n\n", "
").Replace("\n", "
") + "
";
// 選項 C:同時處理空白為 (保留縮排)
return text.Replace(" ", " ").Replace("\n", "
");
}
Public Function HtmlCode(ByVal fString As String) As String
If String.IsNullOrEmpty(fString) Then Return "無內容"
fString = fString.Replace(vbCrLf, vbLf).Replace(vbCr, vbLf)
fString = fString.Replace(vbLf & vbLf, "")
fString = fString.Replace(vbLf, "
")
fString = fString.Replace(" ", " ")
Return "
" & fString & "
"
End Function
// Label 控制項
lblContent.Text = HtmlCode(dt.Rows[0]["Content"].ToString());
// GridView TemplateField
<asp:TemplateField HeaderText="內容">
<ItemTemplate>
<%# HtmlCode(Eval("Content").ToString()) %>
</ItemTemplate>
</asp:TemplateField>
直接在 CSS 設定顯示元素樣式,瀏覽器原生保留換行與空白:
<style>
.preserve-newlines {
white-space: pre-wrap; /* 保留換行、空白,超寬自動換行 */
word-wrap: break-word; /* 長英文/網址強制換行 */
font-family: inherit; /* 繼承父元素字體 */
}
</style>
<asp:Label ID="lblContent" runat="server" CssClass="preserve-newlines" />
<asp:Literal ID="litContent" runat="server" Mode="PassThrough" />
Literal Mode="PassThrough":直接輸出原始文字,不轉換,配合 CSS 完美保留格式。Label 預設渲染 <span>,需加 display: block 或 inline-block 使 white-space 生效。<asp:BoundField DataField="Content" HeaderText="內容"
HtmlEncode="true"
ItemStyle-CssClass="preserve-newlines"
ItemStyle-Wrap="true" />
注意:HtmlEncode="true"(預設)會將 < > 編碼,若資料已含 HTML 標籤需設 false 並自行防 XSS。
| 方案 | 優點 | 缺點 | 適用場景 |
|---|---|---|---|
| 字串替換 <br/> | 相容舊瀏覽器、可控制段落結構 | 後端處理、HTML 編碼需自行管理、混合 HTML 內容易出錯 | Legacy 專案、需輸出 HTML 片段 |
| CSS white-space | 零後端邏輯、效能最佳、保留原始格式 | IE7 以下不支援、超長字串需配合 word-wrap | 現代專案、純文字內容、Markdown 輸出 |
| Literal Mode=PassThrough | 不編碼、不包裹標籤、最乾淨 | 需自行防 XSS、無法直接套用 CSS 類別(需外層包裹) | 高效能輸出、預覽原始碼 |
public static string SafeHtmlCode(string input)
{
if (string.IsNullOrEmpty(input)) return "無內容";
// 1. HTML 編碼:將 < > & " ' 轉為實體
string encoded = System.Web.HttpUtility.HtmlEncode(input);
// 2. 換行轉換
encoded = encoded.Replace("\r\n", "\n").Replace("\r", "\n");
encoded = encoded.Replace("\n", "
");
// 3. 空白保留(可選)
encoded = encoded.Replace(" ", " ");
return encoded;
}
現代 ASP.NET 專案推薦使用 Literal Mode="PassThrough" + CSS white-space: pre-wrap,零後端邏輯、效能最佳、標準相容。舊專案維護可沿用字串替換方案,但務必加上 HttpUtility.HtmlEncode 防禦 XSS。