开发者

Prevent HTML encoding in auto-generated GridView columns

I have开发者_如何学运维 a GridView bound to a DataTable that I construct. Most columns in the table contain the raw HTML for a hypelinklink, and I would like that HTML to render as a link in the browser, but the GridView is automatically encoding the HTML, so it renders as markup.

How can I avoid this without explicitly adding HyperLink, or any other, columns?


Simply set the BoundColumn.HtmlEncode property to false:

<asp:BoundField DataField="HtmlLink" HtmlEncode="false" />


I am afraid that there is no easy way to disable HTML encoding of the contents in a GridView with AutoGenerateColumns= true. However, I can think of two workarounds that might solve the problem you are facing:

Option 1: Inherit the GridView class, override the Render method, loop through all cells, decode their contents, before executing the base method:

for (int i = 0; i < Rows.Count; i++) 
{
    for (int j = 0; j < Rows[i].Cells.Count; j++) 
    {
        string encoded = Rows[i].Cells[j].Text;
        Rows[i].Cells[j].Text = Context.Server.HtmlDecode(encoded);
    }
}

Option 2: In a class inheriting from GridView or in the Page or Control using it, make your own inspection of the DataTable and create an explicit BoundColumn for each column:

foreach (DataColumn column in dataTable.Columns)
{
    GridViewColumn boundColumn = new BoundColumn
        {
            DataSource = column.ColumnName,
            HeaderText = column.ColumnName,
            HtmlEncode = false
        };
    gridView.Columns.Add(boundColumn);
}


I was able to achieve this by using the solution that Jørn Schou-Rode provided, I modified a little bit to make it work from the RowDataBound Event of my Gridview.

protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
           for (int j = 0; j < e.Row.Cells.Count; j++) 
           {
               string encoded = e.Row.Cells[j].Text;
               e.Row.Cells[j].Text = Context.Server.HtmlDecode(encoded);
           }

    }
}


Another way is to add something like the following to the RowDataBound event handler...

    If e.Row.RowType = DataControlRowType.Header Then
        For Each col As TableCell In e.Row.Cells
            Dim encoded As String = col.Text
            col.Text = Context.Server.HtmlDecode(encoded)
        Next
    End If


Use OnRowCreated

    protected void gvFm_RowCreated(object sender, GridViewRowEventArgs e)
    {
        foreach (TableCell cell in e.Row.Cells)
        {
            BoundField fldRef = (BoundField)((DataControlFieldCell)cell).ContainingField;
            switch (fldRef.DataField)
            {
                case "ColToHide":
                    fldRef.Visible = false;                        
                    break;
                case "ColWithoutEncode":
                    fldRef.HtmlEncode = false;                        
                    break;
            }
        }
    }


Well since the html for the link is in your db already, you could just output the html to a literal control.

<asp:TemplateField HeaderText="myLink" SortExpression="myLink">
    <ItemTemplate>
        <asp:Literal ID="litHyperLink" runat="server" Text='<%# Bind("myLink", "{0}") %>' />
    </ItemTemplate>
</asp:TemplateField>

This should render your link as raw text allowing the browser to render it as the link you expect it to be.


Since all the answers seem to be in C# and the questions was not specific, I ran into this issue using ASP.Net and VB.Net and the accepted solution did not work for me in VB (though I imagine it does work in C#). Hopefully this helps anyone working with VB.Net in ASP who stumbles upon this as I have.

In VB.Net BoundColumn cannot be added to Gridview.Columns as it is not a System.Web.UI.WebControls.DataControlField so instead one must use a BoundField which is a DataControlField.

BoundColoumn also does not have an HtmlEncode property however BoundField does. Also, in VB.Net DataSource becomes DataField.

        For Each dataCol As DataColumn In dv.Table.Columns
            Dim boundCol As New BoundField With {
                .DataField = dataCol.ColumnName,
                .HeaderText = dataCol.ColumnName,
                .HtmlEncode = False
            }

            gvResult.Columns.Add(boundCol)
        Next

        gvResult.DataSource = dv
        gvResult.Databind()

Also note that you must explicitly set AutoGenerateColumns="False" or the GridView will still generate columns along with the columns added above.


You can use this code in RowDataBound event if you want to disable HTML encoding in all rows and columns.

protected void GV_Product_RowDataBound(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        foreach (TableCell ObjTC in e.Row.Cells)
        {
            string decodedText = HttpUtility.HtmlDecode(ObjTC.Text);
            ObjTC.Text = decodedText;
        }
    }
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜