MVC 5自定义验证:下拉框选特定值后关联控件必填配置咨询
Hey there! Let's tackle your two questions one by one, using your existing MVC code as a starting point.
Question 1: Do I need to add boolean properties for each control to manage validation pass/fail?
Nope, you don't need extra boolean fields for this. Instead, you can handle conditional validation directly within your model's logic—either by enhancing your custom validation attribute or using MVC's built-in IValidatableObject interface. This keeps your model clean, avoids cluttering it with unnecessary flags, and centralizes all validation logic in one place.
Question 2: How to set individual validation messages for each field when Usage = 2?
The key here is to associate validation errors with specific fields so their corresponding @Html.ValidationMessageFor() helpers display the right message. Here are two solid approaches:
Option 1: Enhance your custom CheckDropDown validation attribute
Modify the IsValid method to check each field separately and return errors tied to specific member names:
protected override ValidationResult IsValid(object value, ValidationContext validationContext) { var model = (PartNumberViewModel)validationContext.ObjectInstance; var validationErrors = new List<ValidationResult>(); // Handle Usage = 1 case if (model.Usage == 1) { if (!string.IsNullOrEmpty(model.RequiredProject)) { validationErrors.Add(new ValidationResult( "If there are 'No Immediate Requirements' for this part number, then a 'Required Project' is not necessary.", new[] { nameof(model.RequiredProject) })); } } // Handle Usage = 2 case else if (model.Usage == 2) { // Check RequiredProject if (string.IsNullOrEmpty(model.RequiredProject)) { validationErrors.Add(new ValidationResult( "Required Project is required when Usage is 'Procure for Projects listed'.", new[] { nameof(model.RequiredProject) })); } // Check Quantity (since it's an int, 0 is the default—adjust if you need to allow 0 in other scenarios) if (model.Quantity <= 0) { validationErrors.Add(new ValidationResult( "Quantity must be greater than 0 when Usage is 'Procure for Projects listed'.", new[] { nameof(model.Quantity) })); } // Check Units if (!model.Units.HasValue) { validationErrors.Add(new ValidationResult( "Units is required when Usage is 'Procure for Projects listed'.", new[] { nameof(model.Units) })); } } // Return the first error, or combine if needed (though IValidatableObject is better for multiple errors) return validationErrors.Any() ? validationErrors.First() : ValidationResult.Success; }
Option 2: Use IValidatableObject (Recommended for multiple conditional validations)
Implement the IValidatableObject interface on your view model—this lets you return multiple validation errors at once, each linked to its respective field:
public class PartNumberViewModel : IValidatableObject { [Required] public int Usage { get; set; } [Display(Name = "Required Project(s)")] public string RequiredProject { get; set; } [Range(0, Int32.MaxValue)] public int Quantity { get; set; } public int? Units { get; set; } public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) { var errors = new List<ValidationResult>(); if (Usage == 1) { if (!string.IsNullOrEmpty(RequiredProject)) { errors.Add(new ValidationResult( "If there are 'No Immediate Requirements' for this part number, then a 'Required Project' is not necessary.", new[] { nameof(RequiredProject) })); } } else if (Usage == 2) { if (string.IsNullOrEmpty(RequiredProject)) { errors.Add(new ValidationResult( "Required Project is required when Usage is 'Procure for Projects listed'.", new[] { nameof(RequiredProject) })); } if (Quantity <= 0) { errors.Add(new ValidationResult( "Quantity must be greater than 0 when Usage is 'Procure for Projects listed'.", new[] { nameof(Quantity) })); } if (!Units.HasValue) { errors.Add(new ValidationResult( "Units is required when Usage is 'Procure for Projects listed'.", new[] { nameof(Units) })); } } return errors; } }
Why this works:
- By passing
new[] { nameof(FieldName) }to theValidationResult, you tell MVC to display the error message in the corresponding@Html.ValidationMessageFor(x => x.FieldName)element. - Your existing view is already set up correctly with these validation message helpers, so no changes are needed there—messages will automatically appear next to the right inputs.
内容的提问来源于stack exchange,提问作者Bigbear

