0

I am using Microsoft.Extension.Options in ASP.NET Core 3.1 and I want to validate entries in an configuration file.

For this I want that, e.g. a RangeAttribute is applied to each element of an IEnumerable.

class MyConfiguration
{
    [ApplyToItems]
    [Range(1, 10)]
    publlic IList<int> MyConfigValues { get; set; }
}

Or something like that. How do I write the ApplyToItems method?

As far as I know there is no way to retrieve the other ValidationAttributes while a possible ApplyToItems is validated.

Alternatively I could imagine something like:

[Apply(Range(1, 10)]
public List<int> MyConfigValues { get; set; }

but is that even valid syntax? How would I write an Attribute like Apply that takes other Attributes as parameter without falling back on something like

[Apply(new RangeAttribute(1, 10)]

which does not look nice.

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Panke
  • 156
  • 9

1 Answers1

3

To create a custom data annotation validator follow these gudelines:

  1. Your class has to inherit from System.ComponentModel.DataAnnotations.ValidationAttribute class.
  2. Override bool IsValid(object value) method and implement validation logic inside it.

That's it.

(from How to create Custom Data Annotation Validators)

So in your case it could be something like this:

public class ApplyRangeAttribute : ValidationAttribute
{
    public int Minimum { get; set; }
    public int Maximum { get; set; }

    public ApplyRangeAttribute()
    {
        this.Minimum = 0;
        this.Maximum = int.MaxValue;
    }

    public override bool IsValid(object value)
    {
        if (value is IList<int> list)
        {
            if (list.Any(i => i < Minimum || i > Maximum))
            {
                return false;
            }
            return true;
        }

        return false;
    }
}

Edit

Here's how you would use it:

class MyConfiguration
{
    [ApplyRange(Minimum = 1, Maximum = 10)]
    public IList<int> MyConfigValues { get; set; }
}
Stefan
  • 652
  • 5
  • 10