我有一个绑定到ObjectDataSource的GridView。我也支持编辑,这很好用。但是,我想安全地显示HtmlEncode文本,因为我们允许在某些字段中使用特殊字符。这与标准的BoundFields有关,因为我只是将HtmlEncode设置为true。
但是为了设置验证控件,需要使用TemplateFields。如何轻松添加HtmlEncoding以这种方式输出?这是一个ASP.NET 2.0项目,因此我使用了较新的数据绑定快捷方式(例如Eval
和Bind
)。
我想做的事情如下:
<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>
然而,当我以这种方式尝试时,我收到以下错误:
CS0103:名称'Bind'不存在 在当前的背景下
答案 0 :(得分:30)
现在可以使用ASP.NET 4中引入的新HTML编码数据绑定语法。
您可以简单地使用:
<%#: Eval("MyField") %>
或者
<%#: Bind("MyField") %>
请注意磅/井号后的冒号就这么简单。
答案 1 :(得分:17)
没有绑定方法 在ASP.NET中。当ASP.NET 解析您的文件并看到您正在使用
它会产生一些 它的特殊代码。 当你使用它时 不是真正的函数调用。如果是ASP.NET 解析代码并检测Bind() 声明,它分裂声明 分为两部分。第一部分是 单向数据绑定部分,其中 最终只是一个普通的Eval() 呼叫。第二部分是相反的 部分,通常是一些代码 沿着“字符串名称= TextBox1.Text“抓住了价值 从它被绑定的地方退出。 但是,因为ASP.NET必须解析 Bind()语句,双向数据绑定 不支持除了以外的任何事情 绑定()。例如,以下内容 语法无效,因为它尝试 调用任意代码并使用Bind() 同时:双向支持的唯一格式 数据绑定是绑定(“字段”)和 绑定(“字段”,“格式字符串{0}”)。
您可以在EditItemTemplate中使用Eval而不是Bind。您还需要强制转换为字符串:
<asp:Label ID="LabelDescription"
runat="server"
Text='<%# System.Web.HttpUtility.HtmlEncode((string)Eval("Description")) %>' />
答案 2 :(得分:8)
正如Darin Dimitrov已经解释过的那样,你不能使用Bind
作为函数的参数。所以Text='<%# System.Web.HttpUtility.HtmlEncode(Bind("Description")) %>'
是不可能的。另一方面,通常没有必要在这里使用HtmlEncode,因为你将Bind
与一个允许更改数据的控件一起使用,例如与TextBox一起使用(如EditItemTemplate的例子)。但TextBox会自动编码,因此您可以安全地调用Bind
而无需HtmlEncode:
<EditItemTemplate>
<asp:TextBox ID="TextBoxDescription" runat="server"
Text='<%# Bind("Description") %>'
ValidationGroup="EditItemGrid"
MaxLength="30" />
<asp:Validator ... />
</EditItemTemplate>
如果TextBox不能使用Bind
自动编码将是一个巨大的安全漏洞(除非您绝对确定您的数据可以安全地呈现为HTML而无需编码)。
但自动编码不是例如标签的情况。虽然您也可以在标签的Text属性中使用Bind
,但标签的输出不会自动编码 - 使用Bind
标签的原因不是一个好习惯,因为您不能使用Bind
对标签文本进行编码。而是使用Eval
并将其包装到HtmlEncode中,就像在ItemTemplate中完成它一样:Text='<%# System.Web.HttpUtility.HtmlEncode((string)Eval("Description")) %>'
答案 3 :(得分:6)
<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>
答案 4 :(得分:2)
Bind()用于Two-Way Data Binding,为此,您必须使用gridview的RowUpdating事件。
void GridView_RowUpdating(Object sender, GridViewUpdateEventArgs e)
{
foreach (DictionaryEntry entry in e.NewValues)
{
e.NewValues[entry.Key] = System.Web.HttpUtility.HtmlEncode(entry.Value.ToString());
}
}
答案 5 :(得分:1)
简单的扩展方法怎么样?
public static string HtmlEncode(this string s)
{
s = HttpUtility.HtmlEncode(s);
return s;
}
然后你可以简单地运行:
<asp:Label runat="server" Text=<%# ((string)Eval("MyStringField")).HtmlEncode() %> />
答案 6 :(得分:1)
答案 7 :(得分:1)
在我的情况下,我被迫在mi EditItemTemplate的TextBox上使用“Bind”方法,因为需要在item_Updating事件处理中可以在NewValues数组中访问数据。所以我想出如下:
在我的EditItemTemplate上:
<EditItemTemplate>
<asp:TextBox runat="server" Text='<%# Bind("field")%>' ID="TextBox112" OnPreRender="TextBox_PreRender_decode"></asp:TextBox>
</EditItemTemplate>
然后在后面的代码中:
protected void TextBox_PreRender_decode(object sender, EventArgs e)
{
TextBox tb = (TextBox)sender;
tb.Text = WebUtility.HtmlDecode(tb.Text);
}
此解决方案允许我正确显示所有TextBox的html编码数据,同时在item_Updating事件触发时能够从newValues数组访问此数据。
答案 8 :(得分:0)
但是如果你使用Phaedrus中的以下代码并且你有一个复选框列,请注意!
void GridView_RowUpdating(Object sender, GridViewUpdateEventArgs e)
{
foreach (DictionaryEntry entry in e.NewValues)
{
e.NewValues[entry.Key] = System.Web.HttpUtility.HtmlEncode(entry.Value.ToString());
}
}
因为entry.Value.ToString()
会将Checkbox中的true变为True,然后您无法将其保存在数据库字段中!