.NET TIPS

[ASP.NET]検証コントロールのパラメータを動的に設定するには?

山田 祥寛
2004/12/10

 「TIPS:[ASP.NET]検証コントロールで条件付きの検証処理を行うには?」では、検証コントロールのEnabledプロパティを動的に変更することで、条件付き検証の処理を実現する方法について紹介した。しかし、この手法は単に「条件付き検証」処理の局面だけではなく、以下のような局面にも応用することができるだろう。

 例えば、オークション・アプリケーションで入札を行う局面を想定してほしい。入札額は、必ず現在の入札最高額よりも高くなければならない。

 このような場合、読者諸氏はどのような実装を考えるだろうか。ページをロードするタイミング(Page_Loadメソッド)で、データベースなどから現在の入札最高額を取得し、CompareValidatorコントロールのValueToCompareプロパティにセットするのが、最もシンプルな方法だろう。

 しかし、よく考えてみてほしい。ページをロードしてから、ユーザーはしばらくページを眺める(あるいはそのまま放置する)可能性がある。この間に、ほかのユーザーが新たな入札を行ってしまったら、そこで最高入札額は変わってしまうのだ。その可能性は、たとえユーザーがどんなに素早くデータを入力したとしても、完全に排除することはできない。つまり、このようなアプリケーションでは、最終的に[入札]ボタンをクリックしたタイミングで、リアルタイムに最高入札額を判断するのが好ましい。

 以上を踏まえたうえで、具体的なコードを実装してみよう。なお、本稿のサンプルを実行する場合には、あらかじめデータベース上に以下のようなテーブルを作成しておく必要がある。

フィールド名 データ型 概要
id INT 入札ID(主キー。連番)
price INT 入札額
auctionテーブルのフィールド・レイアウト
 
<%@ Page ContentType="text/html" Language="C#" %>
<%@ Import Namespace="System.Data" %>
<%@ Import Namespace="System.Data.SqlClient" %>
<script runat="Server">
void btn_Click(Object sender, EventArgs e) {
  // auctionテーブルから最高入札額を取得
  SqlConnection objDb = new SqlConnection("Data Source=(local);User ID=sa;Password=sa;Persist Security Info=True;Initial Catalog=dotnet");
  SqlCommand objCom = new SqlCommand("SELECT max(price) FROM auction",objDb);
  objDb.Open();
  String maxPrice = objCom.ExecuteScalar().ToString();
  if (maxPrice == "") { maxPrice = "0"; }
  objDb.Close();
  // 取得した最高入札額をValueToCompareプロパティに設定
  txtCmp.ValueToCompare = maxPrice;
  if (Page.IsValid) {
    // 任意の処理
  }
}
</script>
<html>
<head>
<title>オークション・サンプル</title>
</head>
<body>
<h1 style="color:white;background:#525D76">オークション・サンプル</h1>
<form runat="Server">
<table border="0">
<tr>
  <th align="right">希望入札額:</th>
  <td>
    <asp:TextBox id="txt" runat="Server" size="5" />円
    <asp:CompareValidator id="txtCmp" runat="Server"
      ControlToValidate="txt" Type="Integer" Operator="GreaterThan"
      ValueToCompare="0" EnableClientScript="False"
      ErrorMessage="希望入札額は現在の最高入札額よりも高くなければいけません。"
     />
  </td>
</tr>
<tr>
  <td rowspan="2"><asp:Button id="btn" runat="Server"
    Text="登録" OnClick="btn_Click" /></td>
</tr>
</table>
</form>
</body>
</html>
入札機能を実装する.aspxファイル(C#の場合)
 
<%@ Page ContentType="text/html" Language="VB" %>
<%@ Import Namespace="System.Data" %>
<%@ Import Namespace="System.Data.SqlClient" %>
<script runat="Server">
Sub btn_Click(sender As Object, e As EventArgs)
  ' auctionテーブルから最高入札額を取得
  Dim objDb As New SqlConnection("Data Source=(local);User ID=sa;Password=sa;Persist Security Info=True;Initial Catalog=dotnet")
  Dim objCom As New SqlCommand("SELECT max(price) FROM auction",objDb)
  objDb.Open()
  Dim maxPrice As String=objCom.ExecuteScalar().ToString()
  If maxPrice="" Then maxPrice="0"
  objDb.Close()
  ' 取得した最高入札額をValueToCompareプロパティに設定
  txtCmp.ValueToCompare=maxPrice
  If Page.IsValid Then
    ' 任意の処理
  End If
End Sub
</script>
<html>
<head>
<title>オークション・サンプル</title>
</head>
<body>
<h1 style="color:white;background:#525D76">オークション・サンプル</h1>
<form runat="Server">
<table border="0">
<tr>
  <th align="right">希望入札額:</th>
  <td>
    <asp:TextBox id="txt" runat="Server" size="5" />円
    <asp:CompareValidator id="txtCmp" runat="Server"
      ControlToValidate="txt" Type="Integer" Operator="GreaterThan"
      ValueToCompare="0" EnableClientScript="False"
      ErrorMessage="希望入札額は現在の最高入札額よりも高くなければいけません。"
     />
  </td>
</tr>
<tr>
  <td rowspan="2"><asp:Button id="btn" runat="Server"
    Text="登録" OnClick="btn_Click" /></td>
</tr>
</table>
</form>
</body>
</html>
入札機能を実装する.aspxファイル(VB.NETの場合)

 btn_Clickメソッドで検証パラメータを動的に設定しているのは、前述のTIPSでも紹介した流れと同様だ。ここで注目していただきたいのは、クリック・イベントによって検証パラメータを決定する場合、あらかじめクライアント検証の機能を無効にする必要があるという点だ。

 検証コントロールでは、デフォルトでクライアント/サーバ双方の検証が有効になっている。しかし、今回のようにクリック・イベントで検証パラメータが決定される場合、クライアント検証のタイミングでは正しい検証パラメータが決まっていないので、検証を行う意味がない。デフォルトの設定値によっては、意図しない検証エラーが発生する可能性がある。このような場合には、EnableClientScriptプロパティをFalseに設定し、クライアント検証を無効にしておく必要がある。

 以下は、上記のサンプル・コードで不正な値を入力した場合の実行結果だ。ページをロードしてからauctionテーブルの値を変更しても、その内容が検証に反映される点に注目していただきたい。

入札額の検証
auctionテーブルに格納された最高入札額よりも小さな値を入力した場合はエラーとなる。

 なお、検証パラメータを動的に設定する際に、最終的にクリック・イベントのタイミングで行うことは、処理パフォーマンスという意味でも有効だ。というのも、前述のTIPSではチェックボックスのOn/Offを切り替えるたびに、ポストバック処理が発生するため、処理的には無駄が多い。このような場合にも、パラメータ決定の処理を変更イベントからクリック・イベントに移動することで、余計なポストバックの発生を抑えられるというわけだ。End of Article

カテゴリ:Webフォーム 処理対象:検証
使用ライブラリ:CompareValidatorコントロール
関連TIPS:[ASP.NET]検証コントロールで条件付きの検証処理を行うには?
 
この記事と関連性の高い別の.NET TIPS
[ASP.NET]CustomValidatorコントロールでクライアント検証を有効にするには?
[ASP.NET]CustomValidatorコントロールでマスタ重複チェックを実装するには?
[ASP.NET]検証コントロールで条件付きの検証処理を行うには?
[ASP.NET]複数のボタンを持つフォームで検証コントロールを利用するには?
[ASP.NET]検証コントロールのエラー・メッセージを一元管理するには?
このリストは、(株)デジタルアドバンテージが開発した
自動関連記事探索システム Jigsaw(ジグソー) により自動抽出したものです。
generated by

「.NET TIPS」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間