tags:

views:

39

answers:

0

I am surprised how much work is involved in MVC to check if at least one of 2 fields has been entered. My solution is derived from a book, you may recognise it! What does not exist in the book is a way to display the error message. So how do I do that? In global.asax, Application_Start I put; ModelValidatorProviders.Providers.Add(new CustomValidatorProvider());

I set up the attribute as follows; private sealed class Metadata { [DisplayName("Client Order Instruction")] [MustExistProperty("ClientOrderNumber")] public string InstructionWithoutClientOrder { get; set; }

The attribute is defined as follows; public class MustExistPropertyAttribute : Attribute { public readonly string OtherProperty;

    public MustExistPropertyAttribute(string otherProperty)
    {
        OtherProperty = otherProperty;
    }
}
public class MustExistPropertyValidator : ModelValidator
{
    private readonly string OtherProperty;

    public MustExistPropertyValidator(ModelMetadata metadata,
        ControllerContext context, string otherProperty)
        : base(metadata, context)
    {
        this.OtherProperty = otherProperty;
    }

    public override IEnumerable<ModelValidationResult> Validate(object container)
    {
        if (Metadata.Model == null)
            yield break;

        var propertyInfo = container.GetType().GetProperty(OtherProperty);
        if (propertyInfo == null)
            throw new InvalidOperationException("Unknown property:" + OtherProperty);
        var valueToCompare = propertyInfo.GetValue(container, null);
        if (Metadata.Model.ToString().Trim().Length + valueToCompare.ToString().Trim().Length == 0)
        {
            yield return new ModelValidationResult 
            { Message = "You must enter either this value or " + this.OtherProperty };
        }
    }
}

public class CustomValidatorProvider : AssociatedValidatorProvider
{
    protected override IEnumerable<ModelValidator> GetValidators(
        ModelMetadata metadata, ControllerContext context, IEnumerable<Attribute> attributes)
    {
        foreach (var attrib in attributes.OfType<MustExistPropertyAttribute>())
            yield return new MustExistPropertyValidator(metadata, context, attrib.OtherProperty);
    }
}