[C#] 특정 상황에서 필수 유효성 검사 속성 비활성화

특정 컨트롤러 작업에서 필수 유효성 검사 특성을 비활성화 할 수 있는지 궁금합니다. 편집 양식 중 하나에서 사용자가 이전에 이미 지정한 필드의 값을 입력하지 않아도되기 때문에 이것이 궁금합니다. 그러나 값을 입력 할 때 값을 해시하는 등의 특수 논리를 사용하여 모델을 업데이트하는 논리를 구현합니다.

이 문제를 해결하는 방법에 대한 의견이 있으십니까?

편집 :
네, 클라이언트 유효성 검사는 여기에 문제가 있습니다. 값을 입력하지 않고 양식을 제출할 수 없기 때문입니다.



답변

이 문제는 뷰 모델을 사용하여 쉽게 해결할 수 있습니다. 뷰 모델은 주어진 뷰의 요구에 맞게 특별히 설계된 클래스입니다. 예를 들어 귀하의 경우 다음과 같은 뷰 모델을 가질 수 있습니다.

public UpdateViewView
{
    [Required]
    public string Id { get; set; }

    ... some other properties
}

public class InsertViewModel
{
    public string Id { get; set; }

    ... some other properties
}

해당 컨트롤러 작업에 사용됩니다.

[HttpPost]
public ActionResult Update(UpdateViewView model)
{
    ...
}

[HttpPost]
public ActionResult Insert(InsertViewModel model)
{
    ...
}


답변

클라이언트 측에서 단일 필드에 대한 유효성 검증을 사용하지 않으려면 다음과 같이 유효성 검증 속성을 대체 할 수 있습니다.

@Html.TexBoxFor(model => model.SomeValue,
                new Dictionary<string, object> { { "data-val", false }})


답변

나는이 질문이 오래 전에 답변되어 왔으며 수락 된 답변이 실제로 작업을 수행한다는 것을 알고 있습니다. 그러나 나를 귀찮게하는 한 가지가 있습니다 : 유효성 검사를 비활성화하기 위해 2 개의 모델 만 복사하면됩니다.

내 제안은 다음과 같습니다.

public class InsertModel
{
    [Display(...)]
    public virtual string ID { get; set; }

    ...Other properties
}

public class UpdateModel : InsertModel
{
    [Required]
    public override string ID
    {
        get { return base.ID; }
        set { base.ID = value; }
    }
}

이런 식으로 클라이언트 / 서버 측 유효성 검사를 신경 쓸 필요가 없으며 프레임 워크는 예상대로 작동합니다. 또한 [Display]기본 클래스에서 속성 을 정의하는 경우에 속성을 다시 정의하지 않아도됩니다 UpdateModel.

그리고이 클래스들을 여전히 같은 방식으로 사용할 수 있습니다 :

[HttpPost]
public ActionResult Update(UpdateModel model)
{
    ...
}

[HttpPost]
public ActionResult Insert(InsertModel model)
{
    ...
}


답변

컨트롤러 작업에서 다음을 사용하여 속성에서 모든 유효성 검사를 제거 할 수 있습니다.

ModelState.Remove<ViewModel>(x => x.SomeProperty);

MVC5에 관한 @Ian 의견

다음은 여전히 ​​가능합니다

ModelState.Remove("PropertyNameInModel");

업데이트 된 API로 정적 타이핑을 잃어 버리는 것이 조금 귀찮습니다. HTML 헬퍼 인스턴스를 작성하고 NameExtensions Methods를 사용하여 이전 방식과 유사한 것을 달성 할 수 있습니다.


답변

고객 쪽
양식에 대한 유효성 검사를 비활성화하기 위해 내 연구에 기반한 여러 옵션이 아래에 나와 있습니다. 그들 중 하나가 희망적으로 당신을 위해 일할 것입니다.

옵션 1

나는 이것을 선호하며 이것은 완벽하게 작동합니다.

(function ($) {
    $.fn.turnOffValidation = function (form) {
        var settings = form.validate().settings;

        for (var ruleIndex in settings.rules) {
            delete settings.rules[ruleIndex];
        }
    };
})(jQuery); 

그리고 그것을 호출

$('#btn').click(function () {
    $(this).turnOffValidation(jQuery('#myForm'));
});

옵션 2

$('your selector here').data('val', false);
$("form").removeData("validator");
$("form").removeData("unobtrusiveValidation");
$.validator.unobtrusive.parse("form");

옵션 3

var settings = $.data($('#myForm').get(0), 'validator').settings;
settings.ignore = ".input";

옵션 4

 $("form").get(0).submit();
 jQuery('#createForm').unbind('submit').submit();

옵션 5

$('input selector').each(function () {
    $(this).rules('remove');
});

서버 측

속성을 작성하고 해당 속성으로 조치 메소드를 표시하십시오. 특정 요구에 맞게이를 사용자 정의하십시오.

[AttributeUsage(AttributeTargets.All)]
public class IgnoreValidationAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        var modelState = filterContext.Controller.ViewData.ModelState;

        foreach (var modelValue in modelState.Values)
        {
            modelValue.Errors.Clear();
        }
    }
}

더 나은 접근법은 여기에서 설명 합니다 .mvc 서버 측 유효성 검사를 동적으로 활성화 / 비활성화


답변

개인적으로 나는 Darin Dimitrov가 그의 해결책에서 보여준 접근법을 사용하는 경향이 있습니다. 이를 통해 데이터 주석 접근 방식을 유효성 검사와 함께 사용할 수 있고 각 작업에 해당하는 각 ViewModel에 대해 별도의 데이터 속성을 가질 수 있습니다. 모델과 뷰 모델 간의 복사 작업량을 최소화하려면 AutoMapper 또는 ValueInjecter를 살펴 보십시오 . 둘 다 각자의 장점이 있으므로 확인하십시오.

IValidatableObject에서 뷰 모델 또는 모델을 파생시키는 다른 방법이 있습니다. 이를 통해 Validate 함수를 구현할 수 있습니다. 유효성 검사에서 유효성 검사 결과 요소 목록을 반환하거나 유효성 검사에서 탐지 한 각 문제에 대해 수익률을 반환 할 수 있습니다.

ValidationResult는 오류 메시지와 필드 이름이 포함 된 문자열 목록으로 구성됩니다. 오류 메시지는 입력 필드 근처의 위치에 표시됩니다.

public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
  if( NumberField < 0 )
  {
    yield return new ValidationResult(
        "Don't input a negative number",
        new[] { "NumberField" } );
  }

  if( NumberField > 100 )
  {
    yield return new ValidationResult(
        "Don't input a number > 100",
        new[] { "NumberField" } );
  }

  yield break;
}


답변

내가 생각하는 가장 깨끗한 방법은 클라이언트 측 유효성 검사를 비활성화하고 서버 측에서 다음을 수행해야한다는 것입니다.

  1. ModelState [ “SomeField”]. Errors.Clear (컨트롤러에서 또는 컨트롤러 코드가 실행되기 전에 오류를 제거하기위한 작업 필터를 만듭니다)
  2. 감지 된 문제의 위반을 감지하면 컨트롤러 코드에서 ModelState.AddModelError를 추가하십시오.

여기에 사용자 정의보기 모델조차도 ‘사전 응답 된’필드의 수가 다양 할 수 있기 때문에 문제를 해결하지 못하는 것 같습니다. 그렇지 않으면 사용자 정의보기 모델이 가장 쉬운 방법 일 수 있지만 위의 기술을 사용하면 유효성 검사 문제를 해결할 수 있습니다.