DiscontentDisciple
DiscontentDisciple

Reputation: 466

C# MVC5 Validate in Model with a List

Within a Class I have a Static List of values which are allowed

private static List<string> allowedClassNames = new List<string> {"Real Estate", "Factored Debt"}; 

And I also have an attribute of that class, which I want to restrict to being values in that list.

        [Required]
        public string assetClassName { get; set; }

I want to do this at the model level, so it works in either a REST or view context.

How would I implement forcing the value in the submission to be limited to that list?

Thanks!

Here's Where I wound up - Not fully tested yet, but to give an idea to future posters.

    class MustContainAttribute : RequiredAttribute
{
    public string Field { get; private set; }
    List<string> allowed;

    public MustContainAttribute(string validateField)
    {
        this.Field = validateField;
    }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        switch (Field)
        {
            case "assetClassName":
                allowed = new List<string> { "Real Estate", "Factored Debt" }; 
                break;
            default:
                return ValidationResult.Success;
        }

        if (!allowed.Contains(Field))
        {
            return new ValidationResult("Invalid Value");
        }else{
            return ValidationResult.Success;
        }

    }

}

Upvotes: 1

Views: 3014

Answers (2)

Nogusta
Nogusta

Reputation: 919

As mentioned in the comments you can create your own ValidationAttribute. This is useful if you have this validation on multiple models or if you want to implement client side validation as well (JavaScript)

However, A quick and easy way to do one off validations like this is the IValidatableObject. You can use it as follows:

public class AssetModel:IValidatableObject
{
    private static List<string> allowedClassNames = new List<string> {"Real Estate", "Factored Debt"};

    [Required]
    public string assetClassName { get; set; }
    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        if (!allowedClassNames.Contains(assetClassName)
        {
            yield new ValidationResult("Not an allowed value", new string[] { "assetClassName" } );
        }
    }
}

Upvotes: 0

wooters
wooters

Reputation: 997

Create a custom validation attribute:

public class ClassNameRequiredAttribute : RequiredAttribute
{
    protected override ValidationResult IsValid(object value, ValidationContext context)
    {

        Object instance = context.ObjectInstance;
        Type type = instance.GetType();
        MyAssetClass myAssetClass = (MyAssetClass)type.GetProperty("MyAssetClass").GetValue(instance, null);

        if (!string.IsNullOrEmpty(myAssetClass.assetClassName))
        {
            if (myAssetClass.allowedClassNames.Contains(myAssetClass.assetClassName))
            {
                return ValidationResult.Success;
            }
        }
        return new ValidationResult(ErrorMessage);
    }
}

And in your model:

    [ClassNameRequired(ErrorMessage="Your error message.")]
    public string assetClassName { get; set; }

Upvotes: 1

Related Questions