FluentValidation 라이브러리를 이용한 ASP.NET MVC 모델 유효성 검사
ASP.NET MVC 웹 애플리케이션에서 사용자 입력값의 유효성을 검사하는 방법은 여러가지가 있겠지만, 보통은 DataAnnodations 방법을 이용한다. 그러나, 여기 소개하는 FluentValidation 라이브러리를 이용하면 훨씬 더 편리하게 유효성 검사를 수행할 수 있다. 이 포스트에서는 이 FluentValidation 라이브러리를 소개하고, 이를 ASP.NET MVC 웹 애플리케이션과 Web API 애플리케이션에서 사용하는 방법, 유닛 테스트를 수행하는 방법, 그리고 IoC 콘트롤러에서 활용하는 방법에 대해 간단하게 논의해 보도록 하자. 여기에 쓰인 코드는 아래 리포지토리에서 확인할 수 있다.
- FluentValidation 라이브러리를 이용한 ASP.NET MVC 모델 유효성 검사
- FluentValidation 라이브러리 유닛 테스트
- FluentValidation IoC 설정
- FluentValidation 라이브러리를 이용한 ASP.NET Web API 모델 유효성 검사
전형적인 사용자 입력 유효성 검사
일반적으로 ASP.NET MVC 애플리케이션에서 사용자 입력에 대한 유효성 검사를 위해서는 바인딩 모델에 DataAnnotation 을 아래와 같은 식으로 추가한다.
public class RegisterViewModel
{
[Required]
[DataType(DataType.EmailAddress)]
[Display(Name = "Email")]
public string Email { get; set; }
[Required]
[StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
[DataType(DataType.Password)]
[Display(Name = "Confirm password")]
[Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
public string ConfirmPassword { get; set; }
}
위에서 확인할 수 있다 시피 Required와 StringLength 같은 속성클라스를 이용하여 해당 모델의 유효성 검사를 진행한다. 이를 이용하면 콘트롤러에서는 보통 이런 모양이 될 수 있다.
[HttpPost]
public virtual async Task<ActionResult> Register(RegisterViewModel form)
{
var vm = form;
if (ModelState.IsValid)
{
vm.Validated = true;
}
return View(vm);
}
이렇게 하면 ModelState.IsValid을 확인하는 시점에서 이미 유효성 검사는 끝났다고 볼 수 있다. 이렇게 해도 아무런 문제가 없긴 하다만, 모델 바인딩 클라스를 만들면서 굉장히 번거로운 작업이 필요하다. 이 과정을 획기적으로 줄여줄 수 있는 것이 바로 FluentValidation library이다.
FluentValidation 라이브러리로 변환
이제 FluentValidation 라이브러리를 설치해서 사용해 보도록 하자. NuGet 패키지를 다운로드 받아 설치한 후 아래와 같이 코드를 바꾸어 보자.
[Validator(typeof(RegisterViewModel))]
public class RegisterViewModel
{
[Display(Name = "Email")]
public string Email { get; set; }
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
[DataType(DataType.Password)]
[Display(Name = "Confirm password")]
public string ConfirmPassword { get; set; }
}
위에서 보는 바와 같이 바인딩 모델은 아주 간단하게 바뀌었다. 대신 Validator라는 속성 클라스를 추가한 것을 확인할 수 있는데, 이 속성 클라스의 정의는 아래와 같다.
public class RegisterViewModelValidator : AbstractValidator<RegisterViewModel>
{
public RegisterViewModelValidator()
{
RuleFor(x => x.Email).NotNull();
RuleFor(x => x.Password).NotNull().Length(6, 100);
RuleFor(x => x.ConfirmPassword).NotNull().Equal(x => x.Password);
}
}
이렇게 Validator 정의를 별도의 클라스에 한꺼번에 몰아서 선언하고 이를 Global.asax.cs의 Application_Start() 메소드에서 초기화한다.
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
...
FluentValidationModelValidatorProvider.Configure();
}
}
이렇게 한 후 다시 콘트롤러에서 평소와 같이 ModelState.IsValid 속성을 호출하면 된다. 그렇다면 이러한 유효성 검사에 대한 것들을 어떻게 테스트를 할 수 있을까? 다음 포스트에서 알아보도록 하자. 60초 후에 돌아오겠습니다