如何在TemplateFields,Data Binding和GridView中使用HtmlEncode

时间:2009-02-04 17:51:41

标签: asp.net data-binding gridview html-encode templatefield

我有一个绑定到ObjectDataSource的GridView。我也支持编辑,这很好用。但是,我想安全地显示HtmlEncode文本,因为我们允许在某些字段中使用特殊字符。这与标准的BoundFields有关,因为我只是将HtmlEncode设置为true。

但是为了设置验证控件,需要使用TemplateFields。如何轻松添加HtmlEncoding以这种方式输出?这是一个ASP.NET 2.0项目,因此我使用了较新的数据绑定快捷方式(例如EvalBind)。

我想做的事情如下:

<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'不存在   在当前的背景下

9 个答案:

答案 0 :(得分:30)

现在可以使用ASP.NET 4中引入的新HTML编码数据绑定语法。

您可以简单地使用:

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

或者

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

请注意磅/井号后的冒号就这么简单。

答案 1 :(得分:17)

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

  

没有绑定方法   在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)

请参阅

http://forums.asp.net/p/1056231/1504717.aspx

我从这里得到了有效的解决方案。它对我来说就像一个魅力。

答案 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,然后您无法将其保存在数据库字段中!