1

I'm using Simon Ince's RequiredIf custom validation attribute implementation. For most situations it has been working, however, I have come into a situation that doesn't work and I can't seem to figure out why.

Here is the relevant portion of the model:

public class SiteOptionsViewModel
{
    public short? RetrievalVendorID { get; set; }
    public short? CopyServiceID { get; set; }
    [Required(ErrorMessage = "Select Retrieval Method For Site")]
    public short? RetrievalMethodID { get; set; }
    //drop down list items
    [DisplayName(@"Retrieval Vendor")]
    public IEnumerable<SelectListItem> RetrievalVendors { get; set; }
    [RequiredIf("RetrievalMethodID", 10, ErrorMessage = @"Copy Service required if Retrieval Method = OS")]
    [DisplayName(@"Copy Service")]
    public IEnumerable<SelectListItem> CopyServices { get; set; }
    [DisplayName(@"Record Format")]
    public IEnumerable<ExtendedSelectListItem> RetrievalMethods { get; set; }
}

In the RequiredIfAttribute class, we have to override the IsValid() method:

protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
    // check if the current value matches the target value
    if (ShouldRunValidation(value, this.DependentProperty, this.TargetValue, validationContext))
    {
        // match => means we should try validating this field
        if (!_innerAttribute.IsValid(value))
            // validation failed - return an error
            return new ValidationResult(FormatErrorMessage(validationContext.DisplayName), new[] { validationContext.MemberName });
    }
    return ValidationResult.Success;
}

You'll notice that the two properties in the model that are relevant are both IEnumerable<SelectedListItem> types for use by dropdowns. The requirement is that when a user selects a particular value from the Retrieval Method dropdown, the form must now require a value to be selected from the Copy Service dropdown. The problem I'm having is that when IsValid() is called on the RequiredIf attribute, the value parameter is null, even when a value has been selected in the Copy Service dropdown. So, the Copy Service gets flagged as being required even though a value has been selected. Any suggestions on how to fix this?

Dar
  • 383
  • 1
  • 5
  • 16
  • 1
    You do not apply the attribute to the `IEnumerable` property (or the `DisplayName` attributes) - that property is just used for providing the values to generate the options). You apply it to the property your binding to (which I assume is `CopyServiceID` but you have not shown your view) –  Jun 03 '16 at 22:20
  • But using a `[RequiredIf]` in this case makes no sense. You already have a [Required]` attribute on `RetrievalMethodID` so therefore you only need to add a `[Required]` attribute to `CopyServiceID` - there is not conditional evaluation since `RetrievalMethodID` is also required –  Jun 03 '16 at 22:38
  • @StephenMuecke You are, of course, correct. I am certainly not at my best on Friday afternoons. As my mind worked on it over the weekend, I came to the same conclusion as you did. While your second comment would also normally be correct, I left out a requirement that I didn't think was pertinent but I suppose it was. The property I am applying the RequireIf attribute to, is only required for one particular client. I'm taking a shortcut here since the particular RetrievalMethodID value of 10 only exists for the client making the request. Thanks for the response. – Dar Jun 06 '16 at 14:49

0 Answers0