2012-02-29 2 views
0

사용자 지정 특성을 사용하여 긴 양식의 유효성 검사를하고 있습니다. 들어오는 필드 중 하나는 사용자가 해당 데이터베이스 필드에 대해 여러 값을 설정할 수 있도록 허용하는 긴 일련의 확인란입니다 (MultiSelectList를 사용할 수 있지만 그 중 큰 팬이 아닙니다). 그런 다음 데이터베이스에로드하기 전에 ActionResult의 POST 메서드에서 다양한 체크 상자 값을 단일 문자열로 조합합니다. 그 부분은 잘 작동합니다.MVC 3 여러 확인란에 대한 사용자 지정 유효성 검사 속성

하지만 적어도 하나의 체크 박스를 선택했는지 확인해야합니다 (즉, 데이터베이스 값 자체가 null 일 수 없음). 그래서 각 확인란의 존재 여부를 찾는 사용자 지정 유효성 검사 특성을 작성하고 적어도 하나가 있으면 유효성 검사를 통과합니다.

public class ConfirmLAAttribute : ValidationAttribute 
{ 
    public ConfirmLAAttribute() 
    { 
    } 

    protected override ValidationResult IsValid(Object value, ValidationContext validationContext) 
    { 
     string lAppTest = String.Empty; 
     lAppTest += (validationContext.ObjectType.GetProperty("LAAccent") != null) ? "X" : String.Empty; 
     lAppTest += (validationContext.ObjectType.GetProperty("LAShade") != null) ? "X" : String.Empty; 
     lAppTest += (validationContext.ObjectType.GetProperty("LAArticulation") != null) ? "X" : String.Empty; 
     lAppTest += (validationContext.ObjectType.GetProperty("LAMassing") != null) ? "X" : String.Empty; 
     lAppTest += (validationContext.ObjectType.GetProperty("LAScreening") != null) ? "X" : String.Empty; 
     lAppTest += (validationContext.ObjectType.GetProperty("LARock") != null) ? "X" : String.Empty; 
     lAppTest += (validationContext.ObjectType.GetProperty("LAEdging") != null) ? "X" : String.Empty; 
     lAppTest += (validationContext.ObjectType.GetProperty("LAWindbreak") != null) ? "X" : String.Empty; 
     lAppTest += (validationContext.ObjectType.GetProperty("LAGroundcover") != null) ? "X" : String.Empty; 
     lAppTest += (validationContext.ObjectType.GetProperty("LANaturalizing") != null) ? "X" : String.Empty; 
     lAppTest += (validationContext.ObjectType.GetProperty("LAOrchard") != null) ? "X" : String.Empty; 
     lAppTest += (validationContext.ObjectType.GetProperty("LATopiary") != null) ? "X" : String.Empty; 
     lAppTest += (validationContext.ObjectType.GetProperty("LAHerb") != null) ? "X" : String.Empty; 
     lAppTest += (validationContext.ObjectType.GetProperty("LAContainer") != null) ? "X" : String.Empty; 
     lAppTest += (validationContext.ObjectType.GetProperty("LABog") != null) ? "X" : String.Empty; 

     if (String.IsNullOrEmpty(lAppTest)) { 
      return new ValidationResult(FormatErrorMessage(validationContext.DisplayName)); 
     } 
     return ValidationResult.Success; 
    } 
} 

내가보기 모델에 속성으로 검증을 호출하고 있습니다 :

[ConfirmLA(ErrorMessage = "You must select at least one Landscape Application!")] 
public string Landscape_Application { get; set; } 

뷰 모델의 HTML 코드를 단순히 반복되는 여기에 내가 검증 자체에 대한 쓴 코드는 :

<input type="checkbox" name="LAAccent" value="true" /> Accent/Feature<br /> 

테이블 내부 (즉, 각 체크 박스 당 15 번).

문제는 항상 오류가 발생한다는 것입니다. 유효성 검사 코드 자체에서 디버깅을했는데 속성 이름별로 확인란을 인식하지 못합니다. 즉, 각각 다음 중 하나입니다.

lAppTest += (validationContext.ObjectType.GetProperty("LAAccent") != null) ? "X" : String.Empty; 

은 체크 박스가 선택되어 있어도 null로 확인됩니다. 확인 된 값이 확실히 ActionResult의 FormCollection에 있음을 확인했습니다. 마치 GetProperty 메서드가 속성 이름으로이 확인란을 찾지 못하는 것처럼 구문을 잘못 입력 한 것처럼 보입니다. 여기서 내가 뭘 잘못하고 있니?

답변

4

변경하여보기 모델을 사용하면 선택한 모든 값이 속성 LandscapeServices에 추가됩니다 제출 쳤을 때

[Required(ErrorMessage = "You must select at least one Landscape Application!")] 
public ICollection<string> LandscapeServices { get; set; } 

<input type="checkbox" class="required-checkbox" name="LandscapeServices" value="LAAccent" /> Accent/Feature<br /> 
<input type="checkbox" class="required-checkbox" name="LandscapeServices" value="LAShade" /> Accent/Feature<br /> 
<input type="checkbox" class="required-checkbox" name="LandscapeServices" value="LAArticulation" /> Accent/Feature<br /> 
/*etc etc*/ 

로 당신의 HTML을 변경합니다.

서버 측 유효성 검사에만 적용됩니다. 클라이언트 측 유효성 검사를 원할 경우 자신의 javascript 유효성 검사 기능으로 필수 확장을 만들어야합니다.

편집 - SO answer

$(function(){ 
    $.validator.addMethod('required_group', function(value, element) { 
     var $module = $(element).parents('form'); 
     return $module.find('input.checkbox:checked').length; 
    }, 'Select at least one Service please'); 
    $.validator.addClassRules('required-checkbox', { 'required_group' : true }); 
+0

에서 클라이언트 측 유효성 검사에 대한 ScubaSteve의 코멘트 @ 해결하기 위해 내가 전달이 조금 (변경을 조정할 "문자열 []"있는지 뷰 모델을 만들기 위해 "ICollection에 을"했다 POST ActionResult의 인수로),하지만 당신은 나를 최적의 솔루션으로 데려 간다. 또한 처리 측을 "foreach"루프로 변환 할 수 있으므로 "수신자"코드를 줄일 수있었습니다. 고마워요. 훌륭했습니다! – Sylver

+0

이것은 서버 측 유효성 검사에 사용되지만 일반적으로 클라이언트 측 유효성 검사를 자동으로 추가하지는 않습니다. – ScubaSteve

+0

@ScubaSteve 질문은 질문자에게 맡겨야합니다. – heads5150

0

클라이언트 측 유효성 검사를 원한다면이 속성을 사용하지 않을 것입니다. 대신, 나는 당신의 모델을 IValidatableObject로부터 파생시키고 그것의 IsValid 메소드에서 검증을 수행한다. 훨씬 쉬우 며 늦은 구속력도 없습니다.

관련 문제