Help us understand the problem. What is going on with this article?

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

環境

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

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした