.net 数组必须包含1个元素

gk7wooem  于 2023-01-10  发布在  .NET
关注(0)|答案(8)|浏览(222)

我有下面的类:

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

我想在TaskDescriptions上面加上一个数据注解,这样数组就必须包含至少一个元素,就像[Required]一样。这可能吗?

dfuffjeb

dfuffjeb1#

它可以使用标准的Required和MinLength验证属性来完成,但仅适用于数组:

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

goqiplq22#

我以前见过用于此目的的自定义验证属性,如下所示:
(我给出了一个带有列表的示例,但可以适用于数组,也可以使用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};
    }
}

归功于Antonio Falcão Jr.的优雅

yptwkmov

yptwkmov3#

请允许我在.NET核心中使用MinLengthAttribute的附带说明。
微软建议使用.NET Core 2.0以上版本的Razor Pages。
当前,使用MinLengthAttribute对PageModel中的属性进行验证不起作用:

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

当SelectedStores.Count()== 0时,ModelState.IsValid返回True。
使用.NET Core 2.1预览版2进行测试。

yrdbyhpb

yrdbyhpb4#

下面是@dove解决方案的一个改进版本,它可以处理不同类型的集合,如HashSet、List等...

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

vjrehmav5#

必须使用2个标准注记属性

public class CreateJob
{
    [MaxLength(1), MinLength(1)]
    public JobTask[] TaskDescriptions { get; set; }
}
8ftvxx2r

8ftvxx2r6#

除了mynkow的回答之外,我还添加了向属性传递最小计数值并生成有意义的失败消息的功能:

public class MinimumElementsRequiredAttribute : ValidationAttribute
{
  private readonly int _requiredElements;

  public MinimumElementsRequiredAttribute(int requiredElements)
  {
    if (requiredElements < 1)
    {
      throw new ArgumentOutOfRangeException(nameof(requiredElements), "Minimum element count of 1 is required.");
    }

    _requiredElements = requiredElements;
  }

  protected override ValidationResult IsValid(object value, ValidationContext validationContext)
  {
    if (!(value is IEnumerable enumerable))
    {
      return new ValidationResult($"The {validationContext.DisplayName} field is required.");
    }

    int elementCount = 0;
    IEnumerator enumerator = enumerable.GetEnumerator();
    while (enumerator.MoveNext())
    {
      if (enumerator.Current != null && ++elementCount >= _requiredElements)
      {
        return ValidationResult.Success;
      }
    }

    return new ValidationResult($"At least {_requiredElements} elements are required for the {validationContext.DisplayName} field.");
  }
}

像这样使用它:

public class Dto
{
  [MinimumElementsRequired(2)]
  public IEnumerable<string> Values { get; set; }
}
ztmd8pv5

ztmd8pv57#

只是将Dove的(@dove)响应更新为C# 9语法:

public class MustHaveOneElementAttribute : ValidationAttribute
    {
        public override bool IsValid(object value)
            => value is IList {Count: > 0};
    }
sbdsn5lh

sbdsn5lh8#

MinLength属性认为如果值为null则有效。因此,只需将模型中的属性初始化为一个空数组,它就可以工作。

MinLength(1, ErrorMessageResourceName = nameof(ValidationErrors.AtLeastOneSelected), ErrorMessageResourceType = typeof(ValidationErrors))]
int[] SelectedLanguages { get; set; } = new int[0];

相关问题