如何在不关闭 HTML 编码的情况下正确显示 asp GridView BoundField 中的换行符

How to properly display line breaks in asp GridView BoundField without turning HTML encoding off

我需要在 asp GridView 中的 asp BoundField 的内容中显示换行符。我本来有\r\n,但是页面完全忽略了这个换行符。我做的第二件事是用字符串中的换行符替换我的换行符,但页面只是在字符串中的任何地方显示文字文本“”。我在技术上尝试的最后一件事是有效的,我通过将我的字符串放入字段中并将 HTML 编码的元素设置为 "false" 来实现这一点。这个解决方案的问题是我听说这会引起安全问题。如何在不将 HTML 编码设置为 false 的情况下在这些字段中换行。

您可以在 GridView 的 RowDataBound 事件中进行搜索和替换。

protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
    //check if the row is a datarow
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        //find the boundfield cell
        string cellValue = e.Row.Cells[0].Text;

        //replace the encoded <br> with a real one and put the string back
        e.Row.Cells[0].Text = cellValue.Replace("&lt;br /&gt;", "<br />");
    }
}

您可能需要扩展替换以包含更多 br 类型,例如 <br><br/><BR>

默认情况下,HTML 将换行符、制表符和 space 视为常见的白色-space,并将多个白色-space 字符折叠成单个 space 用于渲染。因此,在 HTML 中包含换行符通常不会影响文本在浏览器中的呈现方式。有关此主题的更多信息和背景,请参阅之前的 question,其中有一些非常有用的评论。

但是,如果您希望文本中的换行符在浏览器中呈现为换行符,您可以在纯 CSS 中实现此目的,而无需关闭 HTML 编码或引入任何安全问题. white-space CSS property 是标准的,所有主流浏览器都支持了很长时间,使您可以指示浏览器按原样呈现换行符。

更改由 ASP.Net GridView 生成的 HTML 以包含 CSS 样式可以通过使用 <ItemStyle> 标签来实现,如下所示:

<style>
    .preformatted 
    {
        white-space: pre-line;
    }
</style>

<asp:GridView runat="server" ...>
    <Columns>
        <asp:BoundField ...>
            <ItemStyle CssClass="preformatted"/>
        </asp:BoundField>
    </Columns>
</asp:GridView>

除了使用 white-space: pre-line;,您还可以尝试 white-space: pre;,但这会剥夺浏览器调整文本以适应可用 space 的能力,因此可能会导致您的网格如果您的文本没有包含足够的换行符,列会变得太宽。

这个问题特别提到了绑定字段,但是,我对 gridview 模板字段有类似的需求,我发现使用:

        style="white-space: pre-wrap;"

...满足我的需要(该选项也可能对绑定字段有所帮助)。 例如

            <asp:TemplateField HeaderText="Message" SortExpression="CommittedMessage">
                <EditItemTemplate>
                    <asp:TextBox ID="TextBox7" runat="server" 
                        Text='<%# Bind("CommittedMessage") %>'></asp:TextBox>
                </EditItemTemplate>
                <ItemTemplate>
                    <asp:Label ID="Label1" runat="server" 
                        ForeColor='<%# System.Drawing.Color.FromName(Eval("WarningForeColour").ToString()) %>'
                        style="white-space: pre-wrap;"
                        Text='<%# Bind("CommittedMessage") %>'></asp:Label>
                </ItemTemplate>
                <ItemStyle Font-Names="9px" HorizontalAlign="Left" />
            </asp:TemplateField>