ASP.NET MVC 조건부 유효성 검사 검사를 수행하는 방법은 무엇입니까? 예를 들어 다음과 같은

데이터 주석을 사용하여 모델에서 조건부 유효성 검사를 수행하는 방법은 무엇입니까?

예를 들어 다음과 같은 모델 (개인 및 시니어)이 있다고 가정 해 보겠습니다.

public class Person
{
    [Required(ErrorMessage = "*")]
    public string Name
    {
        get;
        set;
    }

    public bool IsSenior
    {
        get;
        set;
    }

    public Senior Senior
    {
        get;
        set;
    }
}

public class Senior
{
    [Required(ErrorMessage = "*")]//this should be conditional validation, based on the "IsSenior" value
    public string Description
    {
        get;
        set;
    }
}

그리고 다음과 같은 견해 :

<%= Html.EditorFor(m => m.Name)%>
<%= Html.ValidationMessageFor(m => m.Name)%>

<%= Html.CheckBoxFor(m => m.IsSenior)%>
<%= Html.ValidationMessageFor(m => m.IsSenior)%>

<%= Html.CheckBoxFor(m => m.Senior.Description)%>
<%= Html.ValidationMessageFor(m => m.Senior.Description)%>

“IsSenior”속성 선택 (true-> 필수)에 따라 “Senior.Description”속성 조건부 필수 필드가되고 싶습니다. 데이터 주석을 사용하여 ASP.NET MVC 2에서 조건부 유효성 검사를 구현하는 방법은 무엇입니까?



답변

MVC3에 조건부 유효성 검사 규칙을 추가하는 훨씬 좋은 방법이 있습니다. 모델 IValidatableObjectValidate메소드를 상속 하고 구현하게하십시오 .

public class Person : IValidatableObject
{
    public string Name { get; set; }
    public bool IsSenior { get; set; }
    public Senior Senior { get; set; }

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        if (IsSenior && string.IsNullOrEmpty(Senior.Description))
            yield return new ValidationResult("Description must be supplied.");
    }
}

ASP.NET MVC 3 소개 (미리보기 1) 에서 자세히 알아보십시오 .


답변

컨트롤러에 포함 된 “ModelState” 사전 을 처리하여이 문제를 해결했습니다 . ModelState 사전에는 유효성을 검사해야하는 모든 멤버가 포함됩니다.

해결책은 다음과 같습니다.

속성 수준 오류 메시지를 유지하면서 일부 필드 (예 : A = true이면 B가 필요함)를 기반으로 조건부 유효성 검사 를 구현해야하는 경우 (객체 수준에있는 사용자 지정 유효성 검사기에는 해당되지 않음) “ModelState”를 처리하여 원치 않는 유효성 검사를 제거하면됩니다.

… 일부 수업에서 …

public bool PropertyThatRequiredAnotherFieldToBeFilled
{
  get;
  set;
}

[Required(ErrorMessage = "*")]
public string DepentedProperty
{
  get;
  set;
}

… 수업은 계속됩니다 …

… 일부 컨트롤러 작업에서 …

if (!PropertyThatRequiredAnotherFieldToBeFilled)
{
   this.ModelState.Remove("DepentedProperty");
}

이를 통해 조건부 유효성 검사를 수행하면서 다른 모든 항목은 동일하게 유지합니다.


최신 정보:

이것이 나의 최종 구현이다 : 나는 모델의 인터페이스와 상기 인터페이스를 구현하는 모델을 검증하는 action 속성을 사용했다. 인터페이스는 Validate (ModelStateDictionary modelState) 메소드를 규정합니다. action 속성은 IValidatorSomething에서 Validate (modelState)를 호출합니다.

이 답변을 복잡하게 만들고 싶지 않았으므로 최종 구현 세부 사항 (결국 생산 코드의 문제)에 대해서는 언급하지 않았습니다.


답변

어제 같은 문제가 있었지만 클라이언트 측과 서버 측 유효성 검사 모두에서 작동하는 매우 깨끗한 방식으로 문제를 해결했습니다.

조건 : 모델의 다른 속성 값을 기준으로 다른 속성을 필요로합니다. 여기 코드가 있습니다

public class RequiredIfAttribute : RequiredAttribute
{
    private String PropertyName { get; set; }
    private Object DesiredValue { get; set; }

    public RequiredIfAttribute(String propertyName, Object desiredvalue)
    {
        PropertyName = propertyName;
        DesiredValue = desiredvalue;
    }

    protected override ValidationResult IsValid(object value, ValidationContext context)
    {
        Object instance = context.ObjectInstance;
        Type type = instance.GetType();
        Object proprtyvalue = type.GetProperty(PropertyName).GetValue(instance, null);
        if (proprtyvalue.ToString() == DesiredValue.ToString())
        {
            ValidationResult result = base.IsValid(value, context);
            return result;
        }
        return ValidationResult.Success;
    }
}

여기서 PropertyName은 조건을 지정하려는 특성입니다. DesiredValue는 다른 특성을 필수로 검증해야하는 PropertyName (속성)의 특정 값입니다.

다음이 있다고 가정하십시오.

public class User
{
    public UserType UserType { get; set; }

    [RequiredIf("UserType", UserType.Admin, ErrorMessageResourceName = "PasswordRequired", ErrorMessageResourceType = typeof(ResourceString))]
    public string Password
    {
        get;
        set;
    }
}

마지막으로 최소한 클라이언트 속성을 검사하여 클라이언트 측 유효성 검사를 수행 할 수 있도록 속성에 대한 어댑터를 등록하십시오 (global.asax, Application_Start에 넣습니다)

 DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(RequiredIfAttribute),typeof(RequiredAttributeAdapter));


답변

나는 동적 주석의 수행이 놀라운 nuget 사용하고 ExpressiveAnnotations을

당신이 꿈꿀 수있는 논리를 검증 할 수 있습니다 :

public string Email { get; set; }
public string Phone { get; set; }
[RequiredIf("Email != null")]
[RequiredIf("Phone != null")]
[AssertThat("AgreeToContact == true")]
public bool? AgreeToContact { get; set; }


답변

ModelState에서 오류를 제거하여 조건부 검사기를 조건부로 비활성화 할 수 있습니다.

ModelState["DependentProperty"].Errors.Clear();


답변

감사합니다 메리트 🙂

누구나 유용하다고 생각되는 경우 MVC 3으로 업데이트했습니다 .ASP.NET MVC 3의 조건부 유효성 검사 .


답변

이제 다른 편리한 데이터 주석 유효성 검사와 같은 조건부 유효성 검사를 수행하는 프레임 워크가 있습니다.
http://foolproof.codeplex.com/

특히 [RequiredIfTrue ( “IsSenior”)] 유효성 검사기를 살펴보십시오. 유효성을 검사하려는 속성에 직접 입력하면 “Senior”속성과 관련된 유효성 검사 오류의 원하는 동작이 나타납니다.

NuGet 패키지로 제공됩니다.