Подтвердить что ты не робот

Как использовать HtmlEncode с TemplateFields, привязкой данных и GridView

У меня есть GridView, привязанный к объекту ObjectDataSource. У меня есть также поддержка редактирования, которая работает отлично. Тем не менее, я хотел бы безопасно отобразить текст HtmlEncode, поскольку мы разрешаем специальные символы в определенных полях. Это - cinch, чтобы сделать со стандартным BoundFields, поскольку я только установил HtmlEncode к истинному.

Но для того, чтобы настроить элементы управления проверкой, вместо этого нужно использовать 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" не существует в текущем контексте

4b9b3361

Ответ 1

Теперь это возможно сделать, используя новый синтаксис привязки данных кодов HTML, введенный в ASP.NET 4.

Вы можете просто использовать:

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

или

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

Обратите внимание на двоеточие после знака фунта/хэша. Это так просто.

Ответ 2

Цитата из http://weblogs.asp.net/leftslipper/archive/2007/06/29/how-asp-net-databinding-deals-with-eval-and-bind-statements.aspx

Не существует метода Bind в ASP.NET. Когда ASP.NET анализирует ваш файл и видит, что вы используете

 он генерирует некоторые специальный код для него. Когда вы используете его не является реальным вызовом функции. Если ASP.NET анализирует код и обнаруживает привязку() оператор, он разбивает утверждение на две части. Первая часть односторонняя привязка данных, которая заканчивается просто регулярным Eval() вызов. Вторая часть - обратная часть, которая обычно представляет собой некоторый код по строкам "string name = TextBox1.Text", который захватывает значение назад, откуда он был связан. Однако, поскольку ASP.NET должен анализировать Операторы Bind(), двусторонняя привязка данных не поддерживает ничего, кроме Bind(). Например, следующее синтаксис недействителен, поскольку он пытается вызывать произвольный код и использовать Bind() в то же время:

Единственные форматы, поддерживаемые в двух направлениях привязкой данных являются Bind ( "поле" ) и Bind ( "поле", "строка формата {0}" ).

Вы можете использовать Eval вместо Bind в свой EditItemTemplate. Вам также нужно указать строку:

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

Ответ 3

Как уже объяснил Дарин Димитров, вы не можете использовать 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 без кодирования).

Но автоматическое кодирование не относится к ярлыку, например. Хотя вы также можете использовать Bind в свойстве "Текст" метки, вывод на метку НЕ кодируется автоматически - причина, по которой использование Bind с меткой не является хорошей практикой, поскольку вы не можете кодировать текст метки с Bind. Вместо этого используйте Eval и заверните его в HtmlEncode, как вы это сделали в своем ItemTemplate: Text='<%# System.Web.HttpUtility.HtmlEncode((string)Eval("Description")) %>'

Ответ 4

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

Ответ 5

Bind() используется для Двусторонняя привязка данных, для этого вам нужно будет использовать RowUpdating событие 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());
    }
}

Ответ 6

Как насчет простого метода расширения?

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

Затем вы можете просто запустить:

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

Ответ 7

Пожалуйста, обратитесь к

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

Я получил рабочее решение отсюда. Его работа как шарм для меня.

Ответ 8

В моем случае я был вынужден использовать метод "Bind" в mi EditItemTemplate TextBox, потому что для доступа к данным в массиве NewValues ​​при обработке событий item_Updating нужны данные. Поэтому я понял, как это сделать:

на моей странице 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);
}

Это решение позволило мне правильно отобразить html-кодированные данные для всех моих текстовых полей и в то же время иметь возможность доступа к этим данным из массива newValues ​​при возникновении события item_Updating.

Ответ 9

Но будьте осторожны, если вы используете следующий код от 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() сделает true из флажка в поле Истина, а затем вы не сможете сохранить его в поле базы данных!