Asp.Net MVC Validation - dependent fields
asp.net, asp.net-mvc, validation
Solution
I would write the validation logic in the model, not the controller. The controller should only handle interaction between the view and the model. Since it's the model that requires validation, I think it's widely regarded as the place for validation logic.
For validation that depends on the value of another property or field, I (unfortunately) don't see how to completely avoid writing some code for that in the model, such as shown in the Wrox ASP.NET MVC book, sort of like:
public bool IsValid
{
get
{
SetRuleViolations();
return (RuleViolations.Count == 0);
}
}
public void SetRuleViolations()
{
if (this.PaymentMethod == "Cheque" && String.IsNullOrEmpty(this.ChequeName))
{
RuleViolations.Add("Cheque name is required", "ChequeName");
}
}
Doing all validation declaratively would be great. I'm sure you could make a `RequiredDependentAttribute`, but that would only handle this one type of logic. Stuff that is even slightly more complex would require yet another pretty specific attribute, etc. which gets crazy quickly.
Problem
I'm currently trying to work through MVC validation, and am coming up against some problems where a field is required depending on the value of another field. An example is below (that I haven't figured out yet) - If the PaymentMethod == "Cheque", then the ChequeName should be required, otherwise it can be let through. ``` [Required(ErrorMessage = "Payment Method must be selected")] public override string PaymentMethod { get; set; } [Required(ErrorMessage = "ChequeName is required")] public override string ChequeName { get; set; } ``` I'm using the System.ComponentModel.DataAnnotations for the [Required], and have also extended a ValidationAttribute to try and get this working, but I can't pass a variable through to do the validation (extension below) ``` public class JEPaymentDetailRequired : ValidationAttribute { public string PaymentSelected { get; set; } public string PaymentType { get; set; } public override bool IsValid(object value) { if (PaymentSelected != PaymentType) return true; var stringDetail = (string) value; if (stringDetail.Length == 0) return false; return true; } } ``` Implementation: ``` [JEPaymentDetailRequired(PaymentSelected = PaymentMethod, PaymentType = "Cheque", ErrorMessage = "Cheque name must be completed when payment type of cheque")] ``` Has anyone had experience with this sort of validation? Would it just be better to write it into the controller? Thanks for your help.