ValidationAttribute
・IValidatableObject
のValidate()
を使ってバリデーションを行うコードを実行していたら、Validate()
が呼び出されないことがあったので、何が起きているのか調べてみました。
Modelバリデーションの処理の呼び出しには順序がある
- Propertyレベルのバリデーション
- (↑でバリデーションに引っかかったら、この時点でエラーを返し、バリデーション中断)
- Objectレベルのバリデーション
- (↑でバリデーションに引っかかったら、この時点でエラーを返し、バリデーション中断)
-
IValidatableObject
のValidate
メソッド
コード
- 各レベルのバリデーションを実装したので、良ければ動かしてみてくださいませー
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()
})
参考