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 displa
<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>
But take care if you use following code from Phaedrus and you have a checkbox column!
void GridView_RowUpdating(Object sender, GridViewUpdateEventArgs e)
{
foreach (DictionaryEntry entry in e.NewValues)
{
e.NewValues[entry.Key] = System.Web.HttpUtility.HtmlEncode(entry.Value.ToString());
}
}
Because the entry.Value.ToString()
will make the true from the Checkbox to True and then you can not save it in the database field!
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")) %>' />
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.
What about a simple extension method?
public static string HtmlEncode(this string s)
{
s = HttpUtility.HtmlEncode(s);
return s;
}
You could then simply run:
<asp:Label runat="server" Text=<%# ((string)Eval("MyStringField")).HtmlEncode() %> />
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")) %>'