LoginSignup
9
8

More than 3 years have passed since last update.

.NET MVC Frameworkにおける属性チェックの基本と実装について

Posted at

環境

  • Visual Studio 2019
  • .NET Framework 4.7.2
  • .NET MVC 5.2.7.0

検証の為の属性の付与と、その概要

.NET MVCでは、以下のようにSystem.ComponentModel.DataAnnotations namespaceに属する各Attributeクラスのメソッドを"[]"で囲んだ記法によって、POST時に必須等の属性チェックを行うことができる。

※例えば、[Required]は上記namespaceのRequiredAttributeクラス(ValidationAttributeクラスを継承)に属している。

HelperViewModel.cs
using System.ComponentModel.DataAnnotations;

namespace HtmlHelperTest.ViewModels
{
    public class HelperViewModel
    {
        [Required(ErrorMessage = "{0}は必須です。")]
        [StringLength(10, ErrorMessage = "{0}は{1}文字以内で入力してください。")]
        [Display(Name = "サンプルプロパティ")]
        public string TmpProperty { get; set; }
    }
}

個別の属性については説明を省くが、上記のような属性を付与した状態でPOSTすると、@Html.ValidationMessageFor()を記述した箇所に以下のようにエラーメッセージをレンダリングする。
※個別の属性についてはSystem.ComponentModel.DataAnnotations namespaceを参照

 POST前
キャプチャ.PNG

 POST後 必須チェックエラー
キャプチャ2.PNG

 POST後 桁数チェックエラー
キャプチャ3.PNG

実際に出力されるエラーメッセージは各属性の()内にあるErrorMessageで指定している。
ちなみに、[StringLength(10, ErrorMessage = "{0}は{1}文字以内で入力してください。")]のように{n}となっている個所にはそれぞれ、

  • {0}[Display(Name = "")]で指定したプロパティの表示名称
  • {1~n}:各属性の第一引数~第n引数

が表示される。

エラーメッセージの表示位置について

前節で@Html.ValidationMessageFor()に各プロパティの属性チェックのエラーメッセージがレンダリングされると書いたが、実際のViewファイルへの記述は以下のようになっている。

Index.cshtml
@model HtmlHelperTest.ViewModels.HelperViewModel

@using (@Html.BeginForm())
{
    @Html.AntiForgeryToken()
    <div>
        <div>
            @Html.LabelFor(model => model.SumpleProperty)
        </div>
        <div>
            @Html.TextBoxFor(model => model.SumpleProperty)
            @Html.ValidationMessageFor(model => model.SumpleProperty)
        </div>
        <div>
            <input type="submit" value="OK" />
        </div>
    </div>
}

他のHtmlHelper同様、@Html.ValidationMessageFor()の引数にプロパティを指定するだけだ。
このような記述によって、
キャプチャ3.PNG

このように任意の場所にエラーメッセージを表示させることができる。

しかし、場合によっては画面上部や特定の場所にエラーメッセージをまとめて表示させたい場合もある。
そのような場合には、以下のように@Html.ValidationSummary()を追加して、第一引数にfalseを指定すればよい。

Index.cshtml
@model HtmlHelperTest.ViewModels.HelperViewModel

@using (@Html.BeginForm())
{
    @Html.AntiForgeryToken()
    <!-- ↓変更箇所 コード追加↓ -->
    @Html.ValidationSummary(false)
    <!-- ↑変更箇所 コード追加↑ -->
    <div>
        <div>
            @Html.LabelFor(model => model.SumpleProperty)
        </div>
        <div>
            @Html.TextBoxFor(model => model.SumpleProperty)
            <!-- ↓変更箇所 エラー項目であることだけ分かるように"*"のみ表示↓ -->
            @Html.ValidationMessageFor(model => model.SumpleProperty, "*")
            <!-- ↑変更箇所 エラー項目であることだけ分かるように"*"のみ表示↑ -->
        </div>
        <div>
            <input type="submit" value="OK" />
        </div>
    </div>
}

こうすることで、以下のように箇条書きでエラー一覧が表示されるようになる。
また、ここではエラー項目が分かるように"*"をエラーメッセージの代わりに表示させている。
キャプチャ4.PNG
ちなみに、@Html.ValidationSummary()の第二引数に箇条書きの上に表示させるメッセージを指定できる。
※ここでは@Html.ValidationSummary(false, "エラー一覧")として実行。

Htmlタグに自動付与されるValidation関連クラス

ここまでで属性チェックによるエラーメッセージを任意の箇所に表示させることができたが、今のままだと以下のようにPOST前の状態でもエラーメッセージが表示されっぱなしになる。
キャプチャ5.PNG

GET時やエラーがない場合は非表示にしたい。
 ⇒@Html.ValidationSummary()Html.ValidationMessageFor()
  自動で付与してくれるクラスを利用する。

@Html.ValidationSummary()およびHtml.ValidationMessageFor()は、プロパティのエラーの有無によって自動的にHtmlタグへクラスを付与してくれる。
付与されるクラスの一覧は以下。

  • validation-summary-valid:エラーがない場合、@Html.ValidationSummary()の生成したdiv要素に付与。
  • validation-summary-errors:エラーがある場合、@Html.ValidationSummary()の生成したdiv要素に付与。
  • input-validation-error:エラーがある場合、エラーとなったプロパティを使用している要素に付与。
  • field-validation-valid:エラーがない場合、Html.ValidationMessageFor()の生成したspan要素に付与。
  • field-validation-error:エラーがある場合、Html.ValidationMessageFor()の生成したspsn要素に付与

つまり、class="validation-summary-valid"の要素は非表示とし、class="validation-summary-errors"の要素は表示させればよいことになる。
これらは基本的にSite.css内に記載する。

参考サイトによると以前はSite.cssに以下のような記述がデフォルトで用意されていたようだが、現在は自分で記載する必用があるようだ。
(もしかして今は別の方法がスタンダードになっている?)

Site.css
.field-validation-error
{
  color: #ff0000;
}

.field-validation-valid
{
  display: none;
}

.input-validation-error
{
  border: 1px solid #ff0000;
  background-color: #ffeeee;
}

.validation-summary-errors
{
  font-weight: bold;
  color: #ff0000;
}

.validation-summary-valid
{
  display: none;
}

この状態でビルドすると、当然以下のように必用な時のみ表示させることができる。
(ついでにエラーメッセージが赤字になっている)

GET時
キャプチャ6.PNG

POST時 桁数チェックエラー
キャプチャ7.PNG


参考サイト:@IT 連載:ASP.NET MVC入門

9
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
8