2009-02-04 24 views
23

Tengo un GridView vinculado a un ObjectDataSource. Lo tengo también apoyando la edición, que funciona bien. Sin embargo, me gustaría escribir texto HtmlEncode de forma segura, ya que permitimos caracteres especiales en ciertos campos. Esto es muy fácil de hacer con BoundFields estándar, ya que acabo de establecer HtmlEncode en verdadero.Cómo usar HtmlEncode con TemplateFields, Data Binding y un GridView

Pero para configurar los controles de validación, uno necesita usar TemplateFields en su lugar. ¿Cómo puedo agregar fácilmente HtmlEncoding a la salida de esta manera? Este es un proyecto ASP.NET 2.0, por lo que estoy usando los atajos de enlace de datos más nuevos (por ejemplo, Eval y Bind).

Lo que me gustaría hacer es algo como lo siguiente:

<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> 

Sin embargo, cuando trato de esta manera, me sale el siguiente error:

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

Respuesta

17

Presupuesto de 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}").

Puede usar Eval en lugar de Bind en su EditItemTemplate. También es necesario para echar a cadena:

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

Descripción de manejar cuando es NULL, donde la fundición causará un accidente, puede utilizar el método ToString(): HtmlEncode (. Eval ("Descripción") ToString()) –

2

bind() se utiliza para Two-Way Data Binding, para que esto funcione, tendrá que utilizar el evento RowUpdating del gridview.

void GridView_RowUpdating(Object sender, GridViewUpdateEventArgs e) 
{ 
    foreach (DictionaryEntry entry in e.NewValues) 
    { 
     e.NewValues[entry.Key] = System.Web.HttpUtility.HtmlEncode(entry.Value.ToString()); 
    } 
} 
0

¡Pero tenga cuidado si utiliza el siguiente código de Phaedrus y tiene una columna de casilla de verificación!

void GridView_RowUpdating(Object sender, GridViewUpdateEventArgs e) 
{ 
    foreach (DictionaryEntry entry in e.NewValues) 
    { 
     e.NewValues[entry.Key] = System.Web.HttpUtility.HtmlEncode(entry.Value.ToString()); 
    } 
} 

Debido a que el entry.Value.ToString() hará que la verdad de la casilla de verificación en True y entonces no se puede guardar en el campo de la base de datos!

8

Como ya explicó Darin Dimitrov, no puede usar Bind como parámetro de una función. Por lo tanto, Text='<%# System.Web.HttpUtility.HtmlEncode(Bind("Description")) %>' no es posible. Por otro lado, generalmente no es necesario usar HtmlEncode aquí porque usará Bind con un control que permite cambiar datos, por ejemplo junto con un TextBox (como en el ejemplo de su EditItemTemplate). Sin embargo, un cuadro de texto codifica de forma automática, por lo que se puede llamar Bind de forma segura sin la necesidad de HtmlEncode:

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

Si un cuadro de texto no se codificará automáticamente utilizando Bind sería un enorme agujero de seguridad (a menos que esté absolutamente seguro de que su es seguro que los datos se procesen en HTML sin codificación).

Pero la codificación automática NO es el caso para una etiqueta, por ejemplo. Aunque también puede usar Bind en la propiedad Texto de una etiqueta, la salida a la etiqueta NO está codificada automáticamente, razón por la cual no es una buena práctica usar Bind, ya que no puede codificar el texto de la etiqueta con Bind. En su lugar use Eval y envuélvalo en HtmlEncode como lo ha hecho en su ItemTemplate: Text='<%# System.Web.HttpUtility.HtmlEncode((string)Eval("Description")) %>'

1

¿Qué tal un simple método de extensión?

public static string HtmlEncode(this string s) 
    {    
     s = HttpUtility.HtmlEncode(s); 
     return s; 
    } 

A continuación, puede simplemente ejecutar:

<asp:Label runat="server" Text=<%# ((string)Eval("MyStringField")).HtmlEncode() %> /> 
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> 
28

Esto es ahora posible hacer uso de la nueva sintaxis de enlace de datos de codificación HTML introducido en ASP.NET 4.

puede simplemente usar:

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

O

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

Tenga en cuenta los dos puntos después del signo de almohadilla/almohadilla Es como si como eso.

+1

Waww .. Un millón de dólares respuesta .. Gracias –

1

En mi caso, me vi obligado a utilizar el método "Vincular" en mi TextBox EditItemTemplate porque necesitaba los datos para ser accesible en la matriz NewValues ​​en el manejo de eventos item_Updating. Así que me di cuenta de la siguiente manera:

en mi EditItemTemplate:

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

a continuación en el código detrás:

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

Esta solución permitió que se mostrarán correctamente un conjunto de datos codificados en HTML para todos mis TextBoxes y, al mismo tiempo, poder acceder a estos datos desde la nueva matrizValues ​​cuando se desencadena el evento item_Updating.

Cuestiones relacionadas