LoginSignup
7

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入門

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
What you can do with signing up
7