0

I have a model defined this way:

public class AdvisoryViewModel : IValidatableObject
{
    [Display(Name = "Start Date")]
    [DisplayFormat(DataFormatString = "{0:d}", ApplyFormatInEditMode = true, ConvertEmptyStringToNull = true)]
    public DateTime? StartDate { get; set; }

    [Display(Name = "End Date")]
    [DisplayFormat(DataFormatString = "{0:d}", ApplyFormatInEditMode = true, ConvertEmptyStringToNull = true)]
    public DateTime? EndDate { get; set; }

    [Display(Name = "Instructions")]
    [Required(ErrorMessage = "Instructions are required")]
    [MaxLength(500, ErrorMessage = "Instructions cannot be longer than 500 characters.")]
    public string Instruction { get; set; }

    IEnumerable<ValidationResult> IValidatableObject.Validate(ValidationContext validationContext)
    {
        List<ValidationResult> results = new List<ValidationResult>();
        if (StartDate.HasValue &&
            EndDate.HasValue &&
            StartDate.Value > EndDate.Value)
        {
            ValidationResult result = new ValidationResult("Start date must be after end date.");
            results.Add(result);
        }
        return results;
    }

And I am validating it as follows:

        var validationResults = new List<ValidationResult>();

        if (!Validator.TryValidateObject(advisoryViewModel, new ValidationContext(advisoryViewModel), validationResults,  true))
        {
            return Json(new { success = false, message = string.Join("; ", validationResults.Select(r => r.ErrorMessage)) });
        }

What happens on validation is it first only calls the "Required" attributes - for example, if the start date is later than end date AND the instructions are null, it returns with only the message that instructions cannot be null. Once they are not null, it returns the start/end date error message.

Is there a way to have it do ALL of the validations up front rather than two attempts?

Also, is there a way the start/end validation can be added to client side results?

James F
  • 535
  • 9
  • 26
  • 2
    No. This is how `IValidatableObject` works. As far as client-side validation goes, you'll just have to manually add that. See the documentation for jQuery Validation for details (https://jqueryvalidation.org/documentation/). – Chris Pratt Mar 02 '17 at 19:12
  • Gotcha - I figured that must be the case, but I was hoping there was a different option. Understood on the jqueryval, thanks! – James F Mar 02 '17 at 19:25
  • Well, there *is* an alternative in the sense that you can dump `IValidatableObject` and use data annotations instead. If the built-ins don't satisfy your needs, you can always create your own or borrow from various different libraries already out there. This answer might help: http://stackoverflow.com/a/19882534/654031 – Chris Pratt Mar 02 '17 at 19:26
  • 1
    Refer also [The Complete Guide To Validation In ASP.NET MVC 3 - Part 2](http://www.devtrends.co.uk/blog/the-complete-guide-to-validation-in-asp.net-mvc-3-part-2) for creating custom validation attributes that give both client and server side validation –  Mar 02 '17 at 20:44

0 Answers0