23

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?

ProfK
  • 49,207
  • 121
  • 399
  • 775

7 Answers7

27

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);
}
Jørn Schou-Rode
  • 37,718
  • 15
  • 88
  • 122
  • HtmlEncode="false" is not recommended due to potential XSS attacks https://learn.microsoft.com/en-us/dotnet/api/system.web.ui.webcontrols.boundfield.htmlencode?view=netframework-4.8 – Michael Freidgeim Oct 01 '19 at 04:15
10

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

    }
}
Cesar Duran
  • 377
  • 3
  • 8
7

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
JMS
  • 71
  • 1
  • 1
3

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;
            }
        }
    }
R0man
  • 41
  • 2
2

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.

Joel Etherton
  • 37,325
  • 10
  • 89
  • 104
2

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.

DavidScherer
  • 863
  • 1
  • 14
  • 26
1

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;
        }
    }
}
Manish Nayak
  • 635
  • 9
  • 18