web-dev-qa-db-ja.com

TemplateFields、データバインディング、GridViewでHtmlEncodeを使用する方法

GridViewがObjectDataSourceにバインドされています。編集もサポートしているので、問題なく動作します。ただし、特定のフィールドで特殊文字を使用できるため、表示されるテキストを安全にHtmlEncodeしたいと思います。これは、HtmlEncodeをtrueに設定しただけなので、標準のBoundFieldsで簡単に実行できます。

ただし、検証コントロールを設定するには、代わりに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」は現在のコンテキストに存在しません

23
Sean Hanley

これは、ASP.NET 4で導入された新しいHTMLエンコーディングデータバインディング構文を使用して実行できるようになりました。

あなたは単に使うことができます:

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

または

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

ポンド/ハッシュ記号の後のコロンに注意してくださいそれはそれと同じくらい簡単です。

31
pattermeister

http://weblogs.asp.net/leftslipper/archive/2007/06/29/how-asp-net-databinding-deals-with-eval-and-bind-statements.aspx からの引用

ASP.NETにはBindメソッドはありません。 ASP.NETがファイルを解析し、使用していることがわかると

それはいくつかの特別なコードを生成します。使用する場合、それは実際の関数呼び出しではありません。 ASP.NETがコードを解析してBind()ステートメントを検出すると、ASP.NETはステートメントを2つの部分に分割します。最初の部分は一方向のデータバインディング部分で、通常のEval()呼び出しにすぎません。 2番目の部分は逆の部分です。これは通常、 "string name = TextBox1.Text"の行に沿った、バインドされた場所から値を取得するコードです。ただし、ASP.NETはBind()ステートメントを解析する必要があるため、双方向データバインディングはBind()以外をサポートしません。たとえば、次の構文は、任意のコードを呼び出し、同時にBind()を使用しようとするため無効です。

双方向のデータバインディングでサポートされる唯一の形式は、Bind( "field")とBind( "field"、 "format string {0}")です。

EditItemTemplateでBindの代わりにEvalを使用できます。また、文字列にキャストする必要があります:

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

Darin Dimitrovによって既に説明されているように、Bindを関数のパラメーターとして使用することはできません。したがって、Text='<%# System.Web.HttpUtility.HtmlEncode(Bind("Description")) %>'は使用できません。一方、Bindを使用して(たとえば、EditItemTemplateの例のように)TextBoxとともにデータを変更できるようにするため、通常はここでHtmlEncodeを使用する必要はありません。ただし、TextBoxは自動的にエンコードするため、HtmlEncodeを使用せずにBindを安全に呼び出すことができます。

_<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を使用し、ItemTemplateで行ったようにHtmlEncodeにラップします:Text='<%# System.Web.HttpUtility.HtmlEncode((string)Eval("Description")) %>'

8
Slauma
<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> 
6
satya

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());
    }
}
2
Phaedrus

親切に参照してください

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

私はここから実用的な解決策を得ました。それは私にとって魅力のように機能します。

1
Rajan Arora

私の場合、item_Updatingイベント処理でNewValues配列のデータにアクセスできる必要があるため、mi EditItemTemplateのTextBoxで「Bind」メソッドを使用する必要がありました。だから私は次のように考えました:

私の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配列からこのデータにアクセスできるようになりました。

単純な拡張メソッドはどうですか?

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

次に、単に実行することができます:

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

ただし、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にtrueを作成し、データベースフィールドに保存できないためです。

0
user285967