views:

13

answers:

1

I realize that I can simply add the [Required] attribute to a class property and MVC will automatically do validation in a very nice way.

What I would like to do however, is assign the attribute at run time, is this possible?

For example, say I have

public class Cert {       
  public string MedicalNum { get; set; }

  public int Certified { get; set; }

...
}

I would like to make the MedicalNum property [Required] (so it is properly validated in the View) if the Certified property is set to 1.

Is this possible?

+1  A: 

Take a look at this post on SO. Basically, take the sample propertiesMustMatch validation to get an idea on how to use Data Annotations with more than one property. Here is a quick stab at what your new code might be (note, probably not 100% syntactically correct on caps, semis)

[AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)]
public sealed class RequiredMedicalNum: ValidationAttribute
{
    private const string _defaultErrorMessage = "{0} is required when certified is true";

    private readonly object _typeId = new object();

public RequiredMedicalNum(string medicalNum, string Certified)
    : base(_defaultErrorMessage)
{
    _medicalNum = medicalNum;
    _certified= Certified;
}

public string _medicalNum 
{
    get;
    private set;
}

public string _certified
{
    get;
    private set;
}

public override object TypeId
{
    get
    {
        return _typeId;
    }
}

public override string FormatErrorMessage(string name)
{
    return String.Format(CultureInfo.CurrentUICulture, ErrorMessageString,
        _medicalNum, _certified);
}

public override bool IsValid(object value)
{
    PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(value);
    object medicalNum = properties.Find(_medicalNum, true /* ignoreCase */).GetValue(value);
    object certified= properties.Find(_certified, true /* ignoreCase */).GetValue(value);
    if(certified == 1){
        Return String.IsNullOrEmpty(medicalNum);  
    }
}
}
Tommy
Thanks Tommy, I'll take a look at the link and I appreciate your code. Will try it this afternoon and from the looks of it, should be exactly what I am looking for.
Mark Kadlec