programing

목록에 대한 모델 유효성 검사 보기

lastmoon 2023. 6. 11. 11:12
반응형

목록에 대한 모델 유효성 검사 보기

다음 뷰 모델 정의가 있습니다.

public class AccessRequestViewModel
{
    public Request Request { get; private set; }
    public SelectList Buildings { get; private set; }
    public List<Person> Persons { get; private set; }
}

그래서 제 애플리케이션에는 적어도 한 명의 사람이 접근 요청을 해야 합니다.어떤 접근 방식을 사용하여 검증할 수 있습니까?컨트롤러에서 이 확인 작업이 수행되지 않았으면 합니다. 쉽게 수행할 수 있습니다.사용자 지정 유효성 검사 특성만 선택할 수 있습니까?

편집: 현재 FluentValidation(Nice 라이브러리!)으로 이 검증을 수행하고 있습니다.

RuleFor(vm => vm.Persons)
                .Must((vm, person) => person.Count > 0)
                .WithMessage("At least one person is required");

데이터 주석을 사용하여 유효성 검사를 수행하는 경우 사용자 지정 특성이 필요할 수 있습니다.

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

다음과 같은 경우:

[EnsureOneElement(ErrorMessage = "At least a person is required")]
public List<Person> Persons { get; private set; }

또는 보다 일반적으로 사용할 수 있습니다.

public class EnsureMinimumElementsAttribute : ValidationAttribute
{
    private readonly int _minElements;
    public EnsureMinimumElementsAttribute(int minElements)
    {
        _minElements = minElements;
    }

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

다음과 같은 경우:

[EnsureMinimumElements(1, ErrorMessage = "At least a person is required")]
public List<Person> Persons { get; private set; }

개인적으로 Fluent Validation을 사용합니다.는 선언문 대신 명령 유효성 검사 논리를 선호하기 때문에 유효성 검사를 수행하는 데이터 주석 대신 NET.저는 그것이 더 강력하다고 생각합니다.따라서 제 검증 규칙은 다음과 같습니다.

RuleFor(x => x.Persons)
    .Must(x => x.Count > 0)
    .WithMessage("At least a person is required");

다음 코드는 asp.net core 1.1에서 작동합니다.

[Required, MinLength(1, ErrorMessage = "At least one item required in work order")]
public ICollection<WorkOrderItem> Items { get; set; }

뷰 모델 개체의 컬렉션 멤버에 대한 카운트 유효성 검사를 처리하는 또 다른 방법은 계산된 속성이 컬렉션 또는 목록 카운트를 반환하는 것입니다.그런 다음 아래 코드와 같이 RangeAttribute를 적용하여 카운트 유효성 검사를 시행할 수 있습니다.

[Range(minimum: 1, maximum: Int32.MaxValue, ErrorMessage = "At least one item needs to be selected")]
public int ItemCount
{
    get
    {
        return Items != null ? Items.Length : 0;
    }
}

위의 코드에서 ItemCount는 유효성 검사 중인 뷰 모델에서 계산된 예제 속성이고 Items는 카운트를 검사 중인 예제 멤버 컬렉션 속성입니다.이 예에서는 하나 이상의 항목이 컬렉션 멤버에 적용되며 최대 제한은 정수가 취할 수 있는 최대 값이며, 이는 대부분의 실질적인 목적을 위해 제한되지 않습니다.유효성 검사 실패 시 오류 메시지는 위의 예에서 RangeAttribute의 ErrorMessage 멤버를 통해 설정할 수도 있습니다.

다린의 답변은 좋지만 아래 버전은 자동으로 유용한 오류 메시지를 줄 것입니다.

public class MinimumElementsAttribute : ValidationAttribute
{
    private readonly int minElements;

    public MinimumElementsAttribute(int minElements)
    {
        this.minElements = minElements;
    }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        var list = value as IList;

        var result = list?.Count >= minElements;

        return result
            ? ValidationResult.Success
            : new ValidationResult($"{validationContext.DisplayName} requires at least {minElements} element" + (minElements > 1 ? "s" : string.Empty));
    }
}

용도:

[MinimumElements(1)]
public List<Customer> Customers {get;set}

[MinimumElements(2)]
public List<Address> Addresses {get;set}

오류 메시지:

  • 고객에게는 하나 이상의 요소가 필요합니다.
  • 주소에 2개 이상의 요소가 필요합니다.

사용자 지정 유효성 검사 특성을 생성하고 속성을 장식하거나 View Model이 다음을 구현하도록 할 수 있습니다.IValidatableObject인터페이스(정의하는Validate방법)

이것이 도움이 되길 바랍니다 :)

커스텀 검증을 받는 것은 매우 깨끗하고 우아할 것입니다.이와 같은 것:

public class AccessRequestViewModel
{
    public Request Request { get; private set; }
    public SelectList Buildings { get; private set; }
    [AtLeastOneItem]
    public List<Person> Persons { get; private set; }
}

또는[MinimumItems(1)].

한 가지 접근 방식은 개체의 인스턴스를 반환하기 위해 전용 생성자와 정적 메서드를 사용하는 것일 수 있습니다.

public class AccessRequestViewModel
{
    private AccessRequesetViewModel() { };

    public static GetAccessRequestViewModel (List<Person> persons)
    {
            return new AccessRequestViewModel()
            {
                Persons = persons,
            };
    }

    public Request Request { get; private set; }
    public SelectList Buildings { get; private set; }
    public List<Person> Persons { get; private set; }
}

항상 공장을 사용하여 View 모델을 인스턴스화함으로써 항상 사람이 존재하도록 할 수 있습니다.

이것은 아마도 당신이 원하는 것에 이상적이지는 않지만, 효과가 있을 것입니다.

언급URL : https://stackoverflow.com/questions/5146732/viewmodel-validation-for-a-list

반응형