LoginSignup
3
3

More than 5 years have passed since last update.

Model Validationの順序

Last updated at Posted at 2017-06-18

ValidationAttributeIValidatableObjectValidate() を使ってバリデーションを行うコードを実行していたら、Validate()が呼び出されないことがあったので、何が起きているのか調べてみました。

Modelバリデーションの処理の呼び出しには順序がある

  • Propertyレベルのバリデーション
  • (↑でバリデーションに引っかかったら、この時点でエラーを返し、バリデーション中断)
  • Objectレベルのバリデーション
  • (↑でバリデーションに引っかかったら、この時点でエラーを返し、バリデーション中断)
  • IValidatableObjectValidateメソッド

コード

  • 各レベルのバリデーションを実装したので、良ければ動かしてみてくださいませー
ExampleController.cs
public class ExampleController: Controller
{
    {
        [HttpPost]
        public ActionResult CustomValidationExample(ExampleInputModel inputModel)
        {
            if (ModelState.Values.Any(v => v.Errors.Count != 0))
            {
                var errorMessage = ModelState.Values.First(v => v.Errors.Count != 0).Errors.First().ErrorMessage;
                return Content(errorMessage);
            }

            return Content("Errorはなかったよ");
        }
}
ExampleInputModel.cs
[NotNullInputModelAtrribute(ErrorMessage = "objectレベルのバリデーションに引っかかったよ")]
public class CustomValidationTestInputModel : IValidatableObject
{
    [Required(ErrorMessage = "propertyレベルのバリデーションに引っかかったよ")]
    public string RequiredProperty { get; set; }

    public bool IsInvalidModel { get; set; }

    [AttributeUsage(AttributeTargets.Class)]
    private class NotNullInputModelAtrribute : ValidationAttribute
    {
        public override bool IsValid(object value)
        {
            var inputModel = value as CustomValidationTestInputModel;
            if (inputModel.IsInvalidModel)
                return false;

            return true;
        }
    }

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        yield return new ValidationResult("ValidatableObjectのバリデーションに引っかかったよ");
    }
}
Example.cshtml
@using (Html.BeginForm("CustomValidationExample", "Projects", new AjaxOptions { HttpMethod = "POST" }))
{
    <p>空にするとPropertyレベルのエラーを発生させられるよ</p>
    @Html.TextBox("RequiredProperty", null, new { style = "display: block" })
    <p>チェックを付けるとObjectレベルのエラーを発生させられるよ</p>
    @Html.CheckBox("IsInvalidModel", new { style = "display: block" })
    @Html.SubmitButton()
})

参考

3
3
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
3
3