How to use HtmlEncode with TemplateFields, Data Binding, and a GridView

53,402

Solution 1

This is now possible to do using the new HTML encoding databinding syntax introduced in ASP.NET 4.

You can simply use:

<%#: Eval("MyField") %>

Or

<%#: Bind("MyField") %>

Note the colon after the pound/hash sign It's as simple as that.

Solution 2

Quote from http://weblogs.asp.net/leftslipper/archive/2007/06/29/how-asp-net-databinding-deals-with-eval-and-bind-statements.aspx

There isn’t a Bind method in ASP.NET. When ASP.NET parses your file and sees you're using

it generates some special code for it. When you use it's not a real function call. If ASP.NET parses the code and detects a Bind() statement, it splits the statement into two parts. The first part is the one-way databinding portion, which ends up being just a regular Eval() call. The second part is the reverse portion, which is typically some code along the lines of "string name = TextBox1.Text" that grabs the value back out from where it was bound. However, because ASP.NET has to parse Bind() statements, two-way databinding doesn’t support anything other than Bind(). For example, the following syntax is invalid because it tries to invoke arbitrary code and use Bind() at the same time:

The only formats supported in two-way databinding are Bind("field") and Bind("field", "format string {0}").

You could use Eval instead of Bind in your EditItemTemplate. You also need to cast to string:

<asp:Label ID="LabelDescription" 
           runat="server" 
           Text='<%# System.Web.HttpUtility.HtmlEncode((string)Eval("Description")) %>' />

Solution 3

As already explained by Darin Dimitrov you cannot use Bind as a parameter of a function. So Text='<%# System.Web.HttpUtility.HtmlEncode(Bind("Description")) %>' is not possible. On the other side it's usually not necessary to use HtmlEncode here because you will use Bind with a control which allows to change data, for instance along with a TextBox (as in the example of your EditItemTemplate). But a TextBox encodes automatically, so you can safely call Bind without the need of HtmlEncode:

<EditItemTemplate>
    <asp:TextBox ID="TextBoxDescription" runat="server"
                 Text='<%# Bind("Description") %>'
                 ValidationGroup="EditItemGrid"
                 MaxLength="30" />
    <asp:Validator ... />
</EditItemTemplate>

If a TextBox would not encode automatically using Bind would be a huge security hole (unless you are absolutely sure that your data are safe to be rendered to HTML without encoding).

But automatic encoding is NOT the case for a label for instance. Although you can also use Bind in the Text property of a label, the output to the label is NOT encoded automatically - a reason why using Bind with a label isn't a good practice, since you cannot encode the label text with Bind. Instead use Eval and wrap it into HtmlEncode as you have done it in your ItemTemplate: Text='<%# System.Web.HttpUtility.HtmlEncode((string)Eval("Description")) %>'

Solution 4

<asp:TemplateField HeaderText="Description">     
  <EditItemTemplate>         
    <asp:TextBox ID="TextBoxDescription" runat="server" Text='<%# System.Web.HttpUtility.HtmlEncode(Bind("Description")) %>'                ValidationGroup="EditItemGrid"  MaxLength="30" />
     <asp:Validator ... />     
  </EditItemTemplate>     
  <ItemTemplate>         
     <asp:Label ID="LabelDescription" runat="server"  Text='<%# System.Web.HttpUtility.HtmlEncode(Convert.ToString(Eval("Description"))) %>' /> 
  </ItemTemplate> 
</asp:TemplateField> 

Solution 5

In my case I was forced to use the "Bind" method on mi EditItemTemplate's TextBox because needed the data to be accessible in the NewValues array at the item_Updating event handling. So i figured out as follow:

on my EditItemTemplate :

<EditItemTemplate>
     <asp:TextBox runat="server" Text='<%# Bind("field")%>' ID="TextBox112" OnPreRender="TextBox_PreRender_decode"></asp:TextBox>                                            
</EditItemTemplate> 

then in the code behind :

protected void TextBox_PreRender_decode(object sender, EventArgs e)
{
    TextBox tb = (TextBox)sender;
    tb.Text = WebUtility.HtmlDecode(tb.Text);
}

This solution allowed me to show properly an html-encoded data for all of my TextBoxes and at the same time being able to access this data from the newValues array when the item_Updating event fires.

Share:
53,402
Sean Hanley
Author by

Sean Hanley

I'm a software developer primarily in .NET Core web apps. Over the years I've done many other stacks and languages and all sorts of odd jobs, but my preference lies in .NET Core web apps. My free time is mostly sucked up by games, cooking, manga, dogs, and, of course, the wife. Since I've been doing this programming for awhile, there's scattered articles and blogs and such out there I've done if you really look for them. I do have a background in writing but rarely get to use it professionally. CV

Updated on September 01, 2020

Comments

  • Sean Hanley
    Sean Hanley over 3 years

    I have a GridView bound to an ObjectDataSource. I've got it supporting editing as well, which works just fine. However, I'd like to safely HtmlEncode text that is displayed as we do allow special characters in certain fields. This is a cinch to do with standard BoundFields, as I just set HtmlEncode to true.

    But in order to setup validation controls, one needs to use TemplateFields instead. How do I easily add HtmlEncoding to output this way? This is an ASP.NET 2.0 project, so I'm using the newer data binding shortcuts (e.g. Eval and Bind).

    What I'd like to do is something like the following:

    <asp:TemplateField HeaderText="Description">
        <EditItemTemplate>
            <asp:TextBox ID="TextBoxDescription" runat="server"
                         Text='<%# System.Web.HttpUtility.HtmlEncode(Bind("Description")) %>'
                         ValidationGroup="EditItemGrid"
                         MaxLength="30" />
            <asp:Validator ... />
        </EditItemTemplate>
        <ItemTemplate>
            <asp:Label ID="LabelDescription" runat="server"
                       Text='<%# System.Web.HttpUtility.HtmlEncode(Eval("Description")) %>' />
        </ItemTemplate>
    </asp:TemplateField>
    

    However, when I try it this way, I get the following error:

    CS0103: The name 'Bind' does not exist in the current context