ASP.NET MVC3 – 유효성 검사

종류

  • Client Validation : javascript로 client쪽에서, 보통 jQuery사용
  • Data Annotation : 모델차원에서
  • Remote Validation : ajax처럼 client에서 server측 유효성 검사 로직 호출
  • Self Validation : ViewModel 자체가 유효성 검사코드 가짐
  • plug-in : Castle, Enterprise Library

 

Data Annotation (모델 기반)

using System.ComponentModel.DataAnnotations;
using System.Web.Mvc;

[Required(ErrorMessage="이름을 반드시 입력하세욧!")] // 필수
[StringLength(25)] // 문자열 길이제한
public string Username { get; set; }

[Range(1, 120)] // 범위제한
public int Hours { get; set; }

[Compare("Hours")] // Hours와 값이 같아야 한다.
public int ConfirmHours { get; set; }

 

Custom Validation Attributes (사용자 정의)

  • IsValid 를 override하여 정의
  • Validation 폴더를 만들고, ValidationAttribute를 상속받아 만들자
  • 팁 : “override “까지 입력후 목록이 나오면 선택후에 탭키를 누른다.
  • Custom Validation Attributes 생성
using System;
using System.ComponentModel.DataAnnotations;

namespace MvcValidation.Validation
{
    public class GreaterThanDateAttribute : ValidationAttribute
    {
        public string OtherPropertyName { get; set; } // 대상 속성명

        public GreaterThanDateAttribute(string otherPropertyName) : base("{0}는 반드시 {1}보다 커야합니다.")
        {
            this.OtherPropertyName = otherPropertyName;
        }

        public override string FormatErrorMessage(string name)
        {
            return string.Format(ErrorMessageString, name, OtherPropertyName);
        }

        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            // 현재개체
            var thisDate = (DateTime)value; // EndDate

            // 대상개체 가져오기
            var otherPropertyInfo = validationContext.ObjectType.GetProperty(OtherPropertyName);
            var otherDate = (DateTime)otherPropertyInfo.GetValue(validationContext.ObjectInstance, null);

            // 유효성 검사 : StartDate < EndDate
            if (otherDate >= thisDate)
            {
                var message = FormatErrorMessage(validationContext.DisplayName);
                return new ValidationResult(message);
            }

            return null;
        }
    }
}
  • Model에서
[GreaterThanDate]
public DateTime EndDate { get; set; }

 

Self Validation

  • IvaliatableObject 인터페이스 구현 (Model 개체에 Validate() 메서드 구현)
  • Model차원에서 검사하기 때문에 Custom Validation 와 에러문구 위치가 틀려진다.
public class TimeCard : IValidatableObject
{
    ...

    public DateTime StartDate { get; set; }
    public DateTime EndDate { get; set; }

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        if (EndDate <= StartDate)
        {
            yield return new ValidationResult("EndDate는 반드시 StartDate보다 커야 합니다.");
        }
    }
}

 

Client Validation

  • Unobtrusive(튀지않는) javascript 사용 : jQuery Validation만 사용하면 됨
  • jQuery validate plug-in : 서버사이드 유효성 검사도 필수
  • web.config 설정
<appSettings>
<add key="ClientValidationEnabled" value="true"/>           // 서버까지 안가고..
<add key="UnobtrusiveJavaScriptEnabled" value="true"/>      // 튀지않는..
</appSettings>
  • 특정 View에서만 설정 바꾸기
@{ Html.EnableClientValidation(false); }
@{ Html.EnableUnobtrusiveJavaScript(false); }

 

Custom Client Validation

  • jQuery.validate에 대한 이해가 필요. 어렵다. 힘들면 하지말자
  • 보통 기본제공하는 validate가 아닌 경우 서버에 갔다와야 한다. 이걸 Client에서 유효성 검사해보자.
  • 아까만든 GreaterThanDateAttribute에 IClientValidatable 상속받게 하여 메소드 구현
// 사용자 정의 클라이언트측 유효성 검사
public System.Collections.Generic.IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
    var rule = new ModelClientValidationRule();
    rule.ErrorMessage = FormatErrorMessage(metadata.GetDisplayName()); // EndDate
    rule.ValidationType = "greater"; // 내가 원하는 이름을 만들어준다.
    rule.ValidationParameters.Add("other", OtherPropertyName);
    yield return rule; // IEnumerable 로 여러개 리턴할 수 있으니까 yield return 하자.
}
  • jQuery validation 메서드를 javascript로 구현
    • Script 폴더에 CustomValidation.js 파일 추가
    • View에 js를 적용 (솔류션 탐색기에서 js파일을 던진다)
    • CustomValidation.js 에 reference 추가 (jquery-1.5.1-vsdoc.js, jquery.validate-vsdoc.js, jquery.validate.unobtrusive.js 파일을 던진다)
/// <reference path="jquery-1.5.1-vsdoc.js" />
/// <reference path="jquery.validate.unobtrusive.js" />
/// <reference path="jquery.validate-vsdoc.js" />

// value : StartDate, param : EndDate
// greater는 GreaterThanDateAttribute 에서 만든 이름
jQuery.validator.addMethod("greater", function (value, element, param) {
    return Date.parse(value) > Date.parse($(param).val());
});

jQuery.validator.unobtrusive.adapters.add("greater", ["other"], function (options) {
    options.rules["greater"] = "#" + options.params.other;
    options.messages["greater"] = options.message;
});

 

Remote Validation

  • ajax와 비슷, 서버측 메서드를 읽어서 실행 (DB를 검사하는 등의 시나리오)
  • 모델에 메소드 이름 추가
[Remote("CheckUsername", "Work", ErrorMessage="해당 이름이 없습니다.")]
public string Username { get; set; }
  • Work 컨트롤러의 CheckUsername 메소드 실행 (아래의 코드에서 AllowGe t의 공백 없어야함.)
public JsonResult CheckUsername(string username)
{
    var result = false;
    // 실제 DB값을 뒤져야 한다.
    if (username == "kimstar") result = true;
    return Json(result, JsonRequestBehavior.AllowGe t);
}

Notice

  • 이 저작물은 크리에이티브 커먼즈 저작자표시-비영리-변경금지 2.0 대한민국 라이선스에 따라 이용할 수 있습니다. 크리에이티브 커먼즈 라이선스
  • 저작권과 관련된 파일요청 및 작업요청을 받지 않습니다.
  • 댓글에 대한 답변은 늦을 수도 있습니다.
  • 답글 남기기

    이메일 주소를 발행하지 않을 것입니다. 필수 항목은 *(으)로 표시합니다