How to force MVC to Validate IValidatableObject

前端 未结 2 2148
不思量自难忘°
不思量自难忘° 2020-11-27 03:06

It seems that when MVC validates a Model that it runs through the DataAnnotation attributes (like required, or range) first and if any of those fail it skips running the Val

2条回答
  •  慢半拍i
    慢半拍i (楼主)
    2020-11-27 03:29

    You can manually call Validate() by passing in a new instance of ValidationContext, like so:

    [HttpPost]
    public ActionResult Create(Model model) {
        if (!ModelState.IsValid) {
            var errors = model.Validate(new ValidationContext(model, null, null));
            foreach (var error in errors)                                 
                foreach (var memberName in error.MemberNames)
                    ModelState.AddModelError(memberName, error.ErrorMessage);
    
            return View(post);
        }
    }
    

    A caveat of this approach is that in instances where there are no property-level (DataAnnotation) errors, the validation will be run twice. To avoid that, you could add a property to your model, say a boolean Validated, which you set to true in your Validate() method once it runs and then check before manually calling the method in your controller.

    So in your controller:

    if (!ModelState.IsValid) {
        if (!model.Validated) {
            var validationResults = model.Validate(new ValidationContext(model, null, null));
            foreach (var error in validationResults)
                foreach (var memberName in error.MemberNames)
                    ModelState.AddModelError(memberName, error.ErrorMessage);
        }
    
        return View(post);
    }
    

    And in your model:

    public bool Validated { get; set; }
    
    public IEnumerable Validate(ValidationContext validationContext) {
        // perform validation
    
        Validated = true;
    }
    

提交回复
热议问题