よく会員登録などのフォームにある、会員規約に同意しますというチェックボックスってありますよね。
ASP.NET MVC でチェックされていない時にエラーを表示する場合、Required 属性を使えば対応出来そうだと考える人は多いと思います。
public class FormModel { // チェックされていない時にエラーになることを期待 [Required(ErrorMessage = "会員規約に同意してください")] public bool Agree { get; set; } }
しかし、Required 属性では期待通りに動作しません。
理由は ASP.NET MVC の CheckBoxFor メソッドで作成したチェックボックスは、チェックされていない場合には false を投げるようになっていて、Required 属性は値が存在しない場合にのみエラーを出すからです。
ということで、現状では IValidatableObject を実装して、Validate メソッドで false かどうかをチェックする必要がありますが、データアノテーションと IValidatableObject の組み合わせは多少問題がある*1ので、指定された値が入力されているか検証する属性を作りました。*2
public class RequiredValueAttribute : ValidationAttribute { public RequiredValueAttribute(object requiredValue) { if (requiredValue == null) { throw new ArgumentNullException("requiredValue"); } _requiredValue = requiredValue; } private readonly object _requiredValue; public override bool IsValid(object value) { if (value.GetType() != _requiredValue.GetType()) { return false; } if (!requiredValue.Equals(value)) { return false; } return true; } }
作成した RequiredValue 属性はコンストラクタで指定された値と、フォームからの値が型を含めて同じものか検証するようになっています。
なので、先程のケースでは以下のように指定すれば解決できますね。
public class FormModel { // チェックされていない時にエラーになることを期待 [RequiredValue(true, ErrorMessage = "会員規約に同意してください")] public bool Agree { get; set; } }
これでチェックを入れずにフォームを送信した場合にはエラーが出るようになりました。
今回はチェックボックスで実装しましたが、ラジオボタンやドロップダウンリストにも応用出来そうです。