私は次のクラスを持っています:
public class CreateJob
{
[Required]
public int JobTypeId { get; set; }
public string RequestedBy { get; set; }
public JobTask[] TaskDescriptions { get; set; }
}
TaskDescriptions
の上にデータ注釈を付けて、配列に少なくとも1つの要素を含める必要がありますか? [Required]
によく似ています。これは可能ですか?
このために、次のように使用されるカスタム検証属性を見たことがあります。
(私はリスト付きのサンプルを提供しましたが、配列に適合させることも、リストを使用することもできます)
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; }
標準のMinLengthAttribute検証属性を使用して実行できますが、配列に対してのみ機能します。
public class CreateJob
{
[Required]
public int JobTypeId { get; set; }
public string RequestedBy { get; set; }
[MinLength(1)]
public JobTask[] TaskDescriptions { get; set; }
}
.NET CoreでのMinLengthAttributeの使用についての補足説明をさせてください。
マイクロソフトでは、.NET Core 2.0以降のRazorページの使用を推奨しています。
現在、PageModel内のプロパティでMinLengthAttributeを使用した検証は機能しません。
[BindProperty]
[Required]
[MinLength(1)]
public IEnumerable<int> SelectedStores { get; set; }
SelectedStates.Count()== 0の場合、ModelState.IsValidはtrueを返します。
.NET Core 2.1 Preview 2でテスト済み。
これは、HashSet、Listなどのさまざまなタイプのコレクションを処理する@doveソリューションの少し改良されたバージョンです...
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;
}
}
MinLength属性は、値がnullの場合、値を有効と見なします。したがって、モデルのプロパティを空の配列として初期化するだけで機能します。
MinLength(1, ErrorMessageResourceName = nameof(ValidationErrors.AtLeastOneSelected), ErrorMessageResourceType = typeof(ValidationErrors))]
int[] SelectedLanguages { get; set; } = new int[0];
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; }
}