net example dinamicamente crear columnas asp asp.net data-binding gridview html-encode templatefield

asp.net - example - Cómo usar HtmlEncode con TemplateFields, Data Binding y un GridView



templatefield gridview c# asp net (9)

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.

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 lo intento de esta manera, obtengo el siguiente error:

CS0103: El nombre ''Bind'' no existe en el contexto actual


¡Pero ten cuidado si usas el siguiente código de Phaedrus y tienes 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 entry.Value.ToString() convertirá el verdadero de Checkbox en True y luego no podrá guardarlo en el campo de la base de datos.


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

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

Entonces simplemente podría ejecutar:

<asp:Label runat="server" Text=<%# ((string)Eval("MyStringField")).HtmlEncode() %> />



Bind () se utiliza para la vinculación de datos bidireccional , para que esto funcione tendrá que usar el evento RowUpdating de 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()); } }


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

No hay un método Bind en ASP.NET. Cuando ASP.NET analiza su archivo y ve que está usando

genera algún código especial para ello. Cuando lo usas no es una llamada de función real. Si ASP.NET analiza el código y detecta una instrucción Bind (), divide la declaración en dos partes. La primera parte es la parte de enlace de datos unidireccional, que termina siendo solo una llamada regular Eval (). La segunda parte es la parte inversa, que generalmente es un código a lo largo de las líneas de "string name = TextBox1.Text" que retoma el valor desde donde estaba enlazado. Sin embargo, debido a que ASP.NET tiene que analizar sentencias Bind (), el enlace de datos bidireccional no admite nada más que Bind (). Por ejemplo, la siguiente sintaxis no es válida porque intenta invocar código arbitrario y usar Bind () al mismo tiempo:

Los únicos formatos admitidos en el enlace de datos bidireccional son Bind ("campo") y Bind ("campo", "formato cadena {0}").

Puede usar Eval en lugar de Bind en su EditItemTemplate. También necesitas lanzar a la secuencia:

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


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 los datos, por ejemplo junto con un TextBox (como en el ejemplo de su EditItemTemplate). Pero un TextBox codifica automáticamente, por lo que puede llamar a Bind sin necesidad de HtmlEncode:

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

Si un TextBox no se codificara automáticamente con Bind sería un gran agujero de seguridad (a menos que esté absolutamente seguro de que sus datos pueden procesarse en HTML sin codificación).

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


En mi caso, me vi obligado a usar el método "Bind" en mi TextBox EditItemTemplate porque necesitaba que los datos estuvieran accesibles en la matriz NewValues ​​en el manejo del evento item_Updating. Así que descubrí lo siguiente:

en mi EditItemTemplate:

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

luego 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 me permitió mostrar correctamente los datos codificados en html para todos mis cuadros de texto y al mismo tiempo poder acceder a estos datos desde la nueva matriz de valores cuando se activa el evento item_Updating.


Esto ahora es posible con la nueva sintaxis de enlace de datos de codificación HTML introducida en ASP.NET 4.

Puedes simplemente usar:

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

O

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

Tenga en cuenta los dos puntos después del signo libra / hash Es tan simple como eso.


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