Tsuの雑記¯\_(ツ)_/¯

主に製作メモ・備忘録として使用。製作したアプリのリンクもあります。

【ASP.NET Core】データモデルの Required 属性を一時的に無視する【Razor Pages】

モデルクラス内の入力必須プロパティを、局所的に無効化する方法です。


始めに

ASP.NET Core とは、C# と HTML の組み合わせでウェブアプリが作れるフレームワークです。

docs.microsoft.com

本稿では ASP.NET Core の中でも、「Razor ページ」という仕組みを取り上げます。

(具体的には、下記チュートリアルの「パート3」まで理解している程度を想定しております)

docs.microsoft.com


Required 属性とは

RequiredAttributeは、nullの格納を認めないデータに付与するための属性です。

docs.microsoft.com

Movie.cs内のTitleプロパティに、Required属性を与えてみましょう。

/Movie/Movie.cs

[Required(ErrorMessage = "The Title field is required.")]
public string Title { get; set; }

この状態でデータを新規作成すると、下図のようにエラーメッセージが表示されます。

Title 項目が空白なのでエラーメッセージが出ている画像
Title が入力必須に

ReleaseDatePriceにもエラーメッセージが出ているのは、そもそもnull非許容型であるためです。


新しい項目の追加

本題の「入力必須だが局所的に無効化する」という要素を考えてみます。

例えば、Summary(概要)という項目はいかがでしょう。

「映画リストには必要だが、リスト追加時には取りあえず入力しなくてよい」といった考えかたが出来ます。

下記のようにSummaryプロパティを追加し、Create.cshtmlはそのままでリストを追加してみましょう。

/Movie/Movie.cs

[Required(ErrorMessage = "The Summary field is required.")]
public string Summary { get; set; }

おそらく画面が切り替わらず、リストも更新されないはずです。

これはCreate.cshtml.csOnPostAsync()メソッド内で、フォーム送信時のエラーを検知しているためです。

/Pages/Movies/Create.cshtml.cs

if (!ModelState.IsValid)
{
    return Page();
}

docs.microsoft.com

Summarynullのままフォームが送信されたため、IsValidfalseを返しているわけですね。

ここでいよいよ、一時的にnullを許可する方法の出番です。


一時的にnullを許可する

前項のIsValid検出前に、ModelState.Remove()を記述します。

docs.microsoft.com

プロパティ名をパラメータに取る事で、指定したプロパティのnullチェックが行われなくなります。

同時にSummaryには適当な値を代入する事で、フォームに存在しない入力必須項目を無視できます。

/Pages/Movies/Create.cshtml.cs

ModelState.Remove($"{nameof(Movie)}.{nameof(Movie.Summary)}");
Movie.Summary = $"({nameof(Movie.Summary)} of \"{Movie.Title}\")";

if (!ModelState.IsValid)
{
    return Page();
}

Summaryへの代入は宣言時の初期化でも行えますが、上記のように変数を含む場合はこのタイミングが良いと思います。

最後にEdit.cshtmlSummaryの編集フォームを追加して、編集画面を確認しましょう。

空白の Summary 入力欄とエラーメッセージが表示された画像
Summary が空白のままでは編集完了できない

ModelState.Remove()によってSummaryの入力必須状態が無効化されたのは新規作成時のみなので、編集時は元どおり入力必須になっています。


終わりに

作例ではいまいち実用性が感じられませんが、覚えておくとどこかで使えるかもしれませんよ。

以上、入力必須プロパティを局所的に無効化する方法でした。