|   | 
          
 
            
|  
              
 .NET TIPS 
[ASP.NET]検証コントロールのエラー・メッセージを一元管理するには?
山田 祥寛 
2005/04/22 | 
  | 
          
 
            
 
              
 
             | 
        
  「Visual Studio .NETでプログラム・レス開発を学ぶ(前編)」などでも紹介しているように、ASP.NETでは検証コントロールを利用することで手軽にページに検証機能を実装することができる。ただし、そんな検証コントロールにもメッセージ管理といった観点で見た場合には、ちょっとした弱点がある。
 それは、ASP.NETの検証コントロールではエラー・メッセージを一元的に管理できないという点だ。多くの場合、検証時のエラー・メッセージに個性は必要ない。必須チェックのエラーであれば「○●は必須入力です」であるとか、範囲チェックであれば「○●は0〜999までの値で入力してください」など、読者諸兄も多くの場合は決まりきった文言を設定しているはずだ。
 しかし、同じ必須チェックに対するエラー・メッセージなのに、あるページでは「○●は必須入力です」、またあるページでは「○●は必ず入力しなければなりません」、はたまたあるページでは「○●は空にすることはできません」などとメッセージに一貫性がない場合、かえってエンド・ユーザーを混乱させてしまう原因となる。ASP.NETの検証コントロールでは、こうしたメッセージの一貫性を管理するのはあくまで開発者の手に委ねられているのだ。
 そこで本稿では、検証コントロールにおいて、メッセージ・リソースを一元的に管理する仕組みを紹介する。
 本稿のサンプルを利用すれば、本来はエラー・メッセージを設定するErrorMessage属性に、メッセージそのものではなくエラー・メッセージに最低限必要な文言部分を指定するだけでし、後は検証の種類に応じて適切なメッセージを動的に生成できるようになる。
 それではさっそく、具体的なコードを見ていくことにしよう。
<%@ Page ContentType="text/html" Language="C#" %> 
<script runat="Server"> 
void Page_Load(Object sender, EventArgs e){ 
 
  // ページ内の検証コントロールを順番に走査。 
  // もともと設定されていたErrorMessage属性(項目名)や 
  // そのほかのパラメータから、 
  // それぞれの検証型に応じたメッセージを動的に生成する 
  if (!Page.IsPostBack) { 
    foreach (BaseValidator valid in Page.Validators) { 
 
      switch (valid.GetType().Name) { 
 
        case "RequiredFieldValidator" : 
          valid.ErrorMessage = String.Format( 
            "{0}は必須です。", valid.ErrorMessage); 
          break; 
 
        case "CompareValidator" : 
          // CompareValidatorでは、項目名は「項目1,項目2」の 
          // 形式で指定されているものとする。 
          // 項目名をカンマで分割し、配列aryMsgにセット 
          String[] aryMsg = valid.ErrorMessage.Split(','); 
 
          // Operator属性の値によって、メッセージを分岐 
          switch (((CompareValidator)valid).Operator) { 
 
            case ValidationCompareOperator.Equal : 
              valid.ErrorMessage = String.Format( 
                "{0}は{1}と等しい値でなければなりません。", 
                aryMsg[0], aryMsg[1]); 
              break; 
 
            case ValidationCompareOperator.NotEqual : 
              valid.ErrorMessage = String.Format( 
                "{0}は{1}と異なる値でなければなりません。", 
                aryMsg[0], aryMsg[1]); 
              break; 
 
            case ValidationCompareOperator.GreaterThan : 
              valid.ErrorMessage = String.Format( 
                "{0}は{1}より大きい値でなければなりません。", 
                "c", "x"); 
              break; 
 
            case ValidationCompareOperator.GreaterThanEqual : 
              valid.ErrorMessage = String.Format( 
                "{0}は{1}以上でなければなりません。", 
                aryMsg[0], aryMsg[1]); 
              break; 
 
            case ValidationCompareOperator.LessThan : 
              valid.ErrorMessage = String.Format( 
                "{0}は{1}より小さい値でなければなりません。", 
                aryMsg[0], aryMsg[1]); 
              break; 
 
            case ValidationCompareOperator.LessThanEqual : 
              valid.ErrorMessage = String.Format( 
                "{0}は{1}以下でなければなりません。", 
                aryMsg[0], aryMsg[1]); 
              break; 
 
            case ValidationCompareOperator.DataTypeCheck : 
              valid.ErrorMessage = String.Format( 
                "{0}は正しい型でありません。", 
                aryMsg[0]); 
              break; 
          } 
          break; 
 
        case "RangeValidator" : 
          valid.ErrorMessage = String.Format( 
            "{0}は{1}〜{2}の間でなければなりません。", 
            valid.ErrorMessage, 
            ((RangeValidator)valid).MinimumValue, 
            ((RangeValidator)valid).MaximumValue); 
          break; 
 
        case "RegularExpressionValidator" : 
          valid.ErrorMessage = String.Format( 
            "{0}は正しい形式ではありません。", 
            valid.ErrorMessage); 
          break; 
      } 
    } 
  } 
} 
</script> 
<html> 
<head> 
<title>エラー・メッセージの一元管理</title> 
</head> 
<body> 
<h1>エラー・メッセージの一元管理</h1> 
<form runat="server"> 
 
  名前:<asp:TextBox id="txtNam" runat="Server" Size="20" /> 
 
  <asp:RequiredFieldValidator id="reqNam" runat="Server" 
    ControlToValidate="txtNam" ErrorMessage="名前" /><br /> 
 
  年齢:<asp:TextBox id="txtOld" runat="Server" Size="3" />歳 
 
  <asp:RangeValidator id="rngOld" runat="Server" 
    ControlToValidate="txtOld" 
    MinimumValue="0" MaximumValue="150" 
    Type="Integer" ErrorMessage="年齢" /> 
 
  <asp:CompareValidator id="cmpOld" runat="Server" 
    ControlToValidate="txtOld" 
    Type="Integer" Operator="DataTypeCheck" 
    ErrorMessage="年齢" /><br /> 
 
  E-Mail:<asp:TextBox id="txtMail" runat="Server" Size="40" /> 
 
  <asp:RegularExpressionValidator id="regMail" runat="Server" 
    ControlToValidate="txtMail" 
    ErrorMessage="E-Mail" 
    ValidationExpression="\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*" /><br /> 
 
  <asp:Button id="btnSend" runat="Server" Text="送信" /> 
 
</form> 
</body> 
</html>
 | 
 
 
 | 
 
| 検証メッセージを動的に生成するためのWebフォーム(C#版:ValidateManage_cs.aspx) | 
 
<%@ Page ContentType="text/html" Language="VB" %> 
<script runat="Server"> 
Sub Page_Load(sender As Object, e As EventArgs) 
  ' ページ内の検証コントロールを順番に走査。 
  ' もともと設定されていたErrorMessage属性(項目名)や 
  ' そのほかのパラメータから、 
  ' それぞれの検証型に応じたメッセージを動的に生成する 
  If Not Page.IsPostBack Then 
    For Each valid As BaseValidator In Page.Validators 
      Select Case valid.GetType().Name 
        Case "RequiredFieldValidator" 
          valid.ErrorMessage= _ 
            String.Format("{0}は必須です。",valid.ErrorMessage) 
        Case "CompareValidator" 
          ' CompareValidatorでは、項目名は「項目1,項目2」の形式で 
          ' 指定されているものとする。 
          ' 項目名をカンマで分割し、配列aryMsgにセット 
          Dim aryMsg As String()=valid.ErrorMessage.Split(New Char(){","}) 
          Dim objCmp As CompareValidator=CType(valid,CompareValidator) 
          Select Case objCmp.Operator 
            Case ValidationCompareOperator.Equal 
              objCmp.ErrorMessage=String.Format( _ 
                "{0}は{1}と等しい値でなければなりません。", _ 
                aryMsg(0),aryMsg(1)) 
            Case ValidationCompareOperator.NotEqual 
              objCmp.ErrorMessage=String.Format( _ 
                "{0}は{1}と異なる値でなければなりません。", _ 
                aryMsg(0),aryMsg(1)) 
            Case ValidationCompareOperator.GreaterThan 
              objCmp.ErrorMessage=String.Format( _ 
                "{0}は{1}より大きい値でなければなりません。", _ 
                aryMsg(0),aryMsg(1)) 
            Case ValidationCompareOperator.GreaterThanEqual 
              objCmp.ErrorMessage=String.Format( _ 
                "{0}は{1}以上でなければなりません。", _ 
                aryMsg(0),aryMsg(1)) 
            Case ValidationCompareOperator.LessThan 
              objCmp.ErrorMessage=String.Format( _ 
                "{0}は{1}より小さい値でなければなりません。", _ 
                aryMsg(0),aryMsg(1)) 
            Case ValidationCompareOperator.LessThanEqual 
              objCmp.ErrorMessage=String.Format( _ 
                "{0}は{1}以下でなければなりません。", _ 
                aryMsg(0),aryMsg(1)) 
            Case ValidationCompareOperator.DataTypeCheck 
              objCmp.ErrorMessage=String.Format( _ 
                "{0}は正しい型でありません。",aryMsg(0)) 
          End Select 
        Case "RangeValidator" 
          Dim objRng As RangeValidator=CType(valid,RangeValidator) 
          valid.ErrorMessage=String.Format( _ 
            "{0}は{1}〜{2}の間でなければなりません。", _ 
            objRng.ErrorMessage, _ 
            objRng.MinimumValue, _ 
            objRng.MaximumValue) 
        Case "RegularExpressionValidator" 
          valid.ErrorMessage=String.Format( _ 
            "{0}は正しい形式ではありません。", _ 
            valid.ErrorMessage) 
      End Select 
    Next 
  End If 
End Sub 
</script> 
<html> 
<head> 
<title>エラーメッセージの一元管理</title> 
</head> 
<body> 
<h1>エラーメッセージの一元管理</h1> 
<form runat="server"> 
名前:<asp:TextBox id="txtNam" runat="Server" Size="20" /> 
<asp:RequiredFieldValidator id="reqNam" runat="Server" 
  ControlToValidate="txtNam" ErrorMessage="名前" /><br /> 
年齢:<asp:TextBox id="txtOld" runat="Server" Size="3" />歳 
<asp:RangeValidator id="rngOld" runat="Server" 
  ControlToValidate="txtOld" MinimumValue="0" MaximumValue="150" 
  Type="Integer" ErrorMessage="年齢" /> 
<asp:CompareValidator id="cmpOld" runat="Server" 
  ControlToValidate="txtOld" Type="Integer" Operator="DataTypeCheck" 
  ErrorMessage="年齢" /><br /> 
E-Mail:<asp:TextBox id="txtMail" runat="Server" Size="40" /> 
<asp:RegularExpressionValidator id="regMail" runat="Server" 
  ControlToValidate="txtMail" ErrorMessage="E-Mail" 
  ValidationExpression="\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*" /><br /> 
<asp:Button id="btnSend" runat="Server" Text="送信" /> 
</form> 
</body> 
</html>
 | 
 
 
 | 
 
| 検証メッセージを動的に生成するためのWebフォーム(VB.NET版:ValidateManage_vb.aspx) | 
 検証コントロールの型によって処理を分岐しているため、必要以上にコードが複雑に見えるかもしれないが、行っていることは非常にシンプルだ。検証コントロールの型に従って、元のErrorMessage属性(項目名)をあらかじめ定義しておいたメッセージ・フォーマットに従って整形しているだけにすぎない。
 以上が理解できたら、さっそくサンプルを実行してみよう。ErrorMessage属性には項目名しか定義していないのに、画面上には正しく整形されたエラー・メッセージが出力されるはずだ。
 
  | 
 
| サンプル・プログラム(ValidateManage_cs.aspx/ValidateManage_vb.aspx)の実行結果 | 
 なお、このような処理は(当然のことながら)個々のページ単位に実装しても意味がないものだ。仕組み自体はPage派生クラスとして一元的に管理しておき、個々の.aspxファイルはこのPage派生クラスを継承して実装するのが好ましい。Page派生クラスを利用する方法については、「TIPS:[ASP.NET]アプリケーション共通の処理をPage派生クラスで実装するには?」で紹介している。
          
 
            
カテゴリ:Webフォーム 処理対象:検証 
使用ライブラリ:RequiredFieldValidatorコントロール(System.Web.UI.WebControls名前空間) 
使用ライブラリ:CompareValidatorコントロール(System.Web.UI.WebControls名前空間) 
使用ライブラリ:RangeValidatorコントロール(System.Web.UI.WebControls名前空間) 
使用ライブラリ:RegularExpressionValidatorコントロール(System.Web.UI.WebControls名前空間) 
関連TIPS:アプリケーション共通の処理をPage派生クラスで実装するには? | 
        
 
        
 
|  
 | 
 
generated by  
 | 
 
 
 | 
 
 
	
		Insider.NET 記事ランキング
		
		
			本日
			月間