views:

25

answers:

1

I am using DataAnnotations for validation (including client side)

I have a form with multiple fields. Basic validation for individual fields work fine. Now there are a couple of fields of which atleast one needs to have a value (if there are 3 fields then either 1st or 2nd or 3rd field should have a value).

I have read quite a few posts on this site and couple of blog entries. But I couldn't find a solution that works in the above mentioned scenario. I might have missed something or doing it incorrectly.

Can you help with this please?

+1  A: 

try this

[AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)]
public sealed class EitherOr : ValidationAttribute
{
    private const string _defaultErrorMessage = "'{0}' OR '{1}' OR '{2}' must have a value";
    private readonly object _typeId = new object();

    public EitherOr(string prop1, string prop2, string prop3)
        : base(_defaultErrorMessage)
    {
        Prop1 = prop1;
        Prop2 = prop2;
        Prop3 = prop3;

    }

    public string Prop1 { get; private set; }
    public string Prop2 { get; private set; }
    public string Prop3 { get; private set; }

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

    public override string FormatErrorMessage(string name)
    {
        return String.Format(CultureInfo.CurrentUICulture, ErrorMessageString, Prop1, Prop2,Prop3);
    }

    public override bool IsValid(object value)
    {
        if(string.IsNullOrEmpty(Prop1)&&string.IsNullOrEmpty(Prop2) && string.IsNullOrEmpty(Prop3))
        {
            return false;
        }
        return true;
    }

then mark your class with the EitherOr attribute:

[EitherOr("Bar","Stool","Hood", ErrorMessage = "please supply one of the properties")]
    public class Foo
    {
        public string Bar{ get; set;}
        public string Stool{ get; set;}
        public string Hood{ get; set;}
    }

Please note that i made use of string properties, if your property is of other type, makle sure to change the IsValid(object value) validation

Dusty Roberts
Thanks Dusty, what javacript validation script should I write in this case? should I still implement DataAnnotationsModelValidator and register it?
byte
You shouldn't have to write any javascript if you use the default `Html.ValidationSummary`. the error messagfe will be displayed in your validation summary. however, if you want it displayed next to each of the form fields you will have to make use of: ModelState.AddModelError("Bar", "requires a value");
Dusty Roberts
Thanks. Does this validation happen at server side then? I am looking at input validation on client side as well to give better UI and avoid server trip where possible. Server side validation will always be around.
byte
You can enable clientside validation on mvc2, have a look here http://dotnetaddict.dotnetdevelopersjournal.com/clientvalidation_mvc2.htm, it will validate against your model and it's appropriate data annotations
Dusty Roberts
Also take note that if you go the ModelState.AddModelError route you will have to validate server side
Dusty Roberts
Dusty, Looks like I have to use reflection. I used your example and in IsValid I see the values of Prop1 = "Bar" and not the value of "Bar"
byte