GridViewがObjectDataSourceにバインドされています。編集もサポートしているので、問題なく動作します。ただし、特定のフィールドで特殊文字を使用できるため、表示されるテキストを安全にHtmlEncodeしたいと思います。これは、HtmlEncodeをtrueに設定しただけなので、標準のBoundFieldsで簡単に実行できます。
ただし、検証コントロールを設定するには、代わりに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」は現在のコンテキストに存在しません
これは、ASP.NET 4で導入された新しいHTMLエンコーディングデータバインディング構文を使用して実行できるようになりました。
あなたは単に使うことができます:
<%#: Eval("MyField") %>
または
<%#: Bind("MyField") %>
ポンド/ハッシュ記号の後のコロンに注意してくださいそれはそれと同じくらい簡単です。
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")) %>' />
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")) %>'
<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>
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());
}
}
私の場合、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() %> />
ただし、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を作成し、データベースフィールドに保存できないためです。