Array must contain 1 element

24,754

Solution 1

I've seen a custom validation attribute used for this before, like this:

(I've given sample with a list but could be adapted for array or you could use list)

public class MustHaveOneElementAttribute : ValidationAttribute
{
    public override bool IsValid(object value)
    {
        var list = value as IList;
        if (list != null)
        {
            return list.Count > 0;
        }
        return false;
    }
}

[MustHaveOneElementAttribute (ErrorMessage = "At least a task is required")]
public List<Person> TaskDescriptions { get; private set; }

// as of C# 8/9 this could be more elegantly done with     
public class MustHaveOneElementAttribute : ValidationAttribute
{
    public override bool IsValid(object value)
    {
        return value is IList {Count: > 0};
    }
}

Credit to Antonio Falcão Jr. for elegance

Solution 2

It can be done using standard Required and MinLength validation attributes, but works ONLY for arrays:

public class CreateJob
{
    [Required]
    public int JobTypeId { get; set; }
    public string RequestedBy { get; set; }
    [Required, MinLength(1)]
    public JobTask[] TaskDescriptions { get; set; }
}

Solution 3

Please allow me a side note on using MinLengthAttribute with .NET Core.

Microsoft recommends using Razor Pages starting with .NET Core 2.0.

Currently, The validation with MinLengthAttribute on a property within the PageModel does not work:

[BindProperty]
[Required]
[MinLength(1)]
public IEnumerable<int> SelectedStores { get; set; }

ModelState.IsValid returns true when SelectedStores.Count() == 0.

Tested with .NET Core 2.1 Preview 2.

Solution 4

Here is a bit improved version of @dove solution which handles different types of collections such as HashSet, List etc...

public class MustHaveOneElementAttribute : ValidationAttribute
{
    public override bool IsValid(object value)
    {
        var collection = value as IEnumerable;
        if (collection != null && collection.GetEnumerator().MoveNext())
        {
            return true;
        }
        return false;
    }
}

Solution 5

You have to use 2 standard annotation attribute

public class CreateJob
{
    [MaxLength(1), MinLength(1)]
    public JobTask[] TaskDescriptions { get; set; }
}
Share:
24,754

Related videos on Youtube

CallumVass
Author by

CallumVass

Updated on May 28, 2021

Comments

  • CallumVass
    CallumVass almost 3 years

    I have the following class:

    public class CreateJob
    {
        [Required]
        public int JobTypeId { get; set; }
        public string RequestedBy { get; set; }
        public JobTask[] TaskDescriptions { get; set; }
    }
    

    I'd like to have a data annotation above TaskDescriptions so that the array must contain at least one element? Much like [Required]. Is this possible?

  • John MacIntyre
    John MacIntyre over 9 years
    Apparently it's only available in .net 4.5+ as well. :-(
  • Pluc
    Pluc about 9 years
    A little more info about this attribute: You should use [Required] in conjunction with [MinLength(1)] because MinLength will not trigger if the array is null (not empty, null). Also important to note, this is not supported (correct me if I'm wrong) with default client side validators. It will only trigger the ModelState.IsValid.
  • Cat_Clan
    Cat_Clan about 8 years
    That attribute also works for objects that implements the ICollection interface and strings.
  • Mike Devenney
    Mike Devenney about 8 years
    You should add @Pluc's comment to your answer. Having the [Required] attribute makes your answer better than the accepted answer above.
  • Lostaunaum
    Lostaunaum about 7 years
    Thank you this is exactly what I was looking for.
  • whyleee
    whyleee over 6 years
    [MinLength(1)] works with IEnumerable<T> in ASP.NET Core
  • monty
    monty almost 5 years
    MinLength seems not to work correctly in .NET Core 2.2 (nor with arrays, IEnumerables, ICollections, IList....)
  • Antonio Falcão Jr.
    Antonio Falcão Jr. almost 3 years
    As of C # 8/9, all of this code can be replaced by this: return value is IList {Count: > 0};
  • tiennen07
    tiennen07 almost 3 years
    yeah, it appears to be broken on .NET 5, as well.
  • Daniël J.M. Hoffman
    Daniël J.M. Hoffman about 2 years
    [MinLength(1)] attribute is working for my requirement to have a least 1 element in my List<T>, with .NET 6 Blazor.