다음을 통해 공유


IDataErrorInfo 인터페이스를 사용한 유효성 검사(VB)

작성 자: Stephen Walther

Stephen Walther는 모델 클래스에서 IDataErrorInfo 인터페이스를 구현하여 사용자 지정 유효성 검사 오류 메시지를 표시하는 방법을 보여줍니다.

이 자습서의 목표는 ASP.NET MVC 애플리케이션에서 유효성 검사를 수행하는 한 가지 방법을 설명하는 것입니다. 필요한 양식 필드에 대한 값을 제공하지 않고 다른 사용자가 HTML 양식을 제출하지 못하도록 방지하는 방법을 알아봅니다. 이 자습서에서는 IErrorDataInfo 인터페이스를 사용하여 유효성 검사를 수행하는 방법을 알아봅니다.

가정

이 자습서에서는 MoviesDB 데이터베이스 및 Movies 데이터베이스 테이블을 사용합니다. 이 테이블에는 다음 열이 있습니다.

열 이름 데이터 형식 Null 허용
Id Int 거짓
제목 Nvarchar (100) 거짓
감독 Nvarchar (100) 거짓
DateReleased DateTime 거짓

이 자습서에서는 Microsoft Entity Framework를 사용하여 데이터베이스 모델 클래스를 생성합니다. Entity Framework에서 생성된 Movie 클래스는 그림 1에 표시됩니다.

무비 엔터티

그림 01: 동영상 엔터티(전체 크기 이미지를 보려면 클릭)

참고

Entity Framework를 사용하여 데이터베이스 모델 클래스를 생성하는 방법에 대한 자세한 내용은 Entity Framework를 사용하여 모델 클래스 만들기 자습서를 참조하세요.

컨트롤러 클래스

홈 컨트롤러를 사용하여 영화를 나열하고 새 영화를 만듭니다. 이 클래스의 코드는 목록 1에 포함되어 있습니다.

목록 1 - Controllers\HomeController.vb

Public Class HomeController
Inherits Controller

Private _db As New MoviesDBEntities()

Public Function Index() As ActionResult
    Return View(_db.MovieSet.ToList())
End Function

Public Function Create() As ActionResult
    Return View()
End Function

<AcceptVerbs(HttpVerbs.Post)> _
Public Function Create(<Bind(Exclude := "Id")> ByVal movieToCreate As Movie) As ActionResult
        ' Validate
        If (Not ModelState.IsValid) Then
        Return View()
        End If

    ' Add to database
    Try
        _db.AddToMovieSet(movieToCreate)
        _db.SaveChanges()

        Return RedirectToAction("Index")
    Catch
        Return View()
    End Try
End Function

End Class

목록 1의 홈 컨트롤러 클래스에는 두 개의 Create() 작업이 포함됩니다. 첫 번째 작업은 새 동영상을 만들기 위한 HTML 양식을 표시합니다. 두 번째 만들기() 작업은 데이터베이스에 새 동영상의 실제 삽입을 수행합니다. 두 번째 Create() 작업은 첫 번째 Create() 작업으로 표시되는 양식이 서버에 제출될 때 호출됩니다.

두 번째 Create() 작업에는 다음 코드 줄이 포함되어 있습니다.

' Validate
If (Not ModelState.IsValid) Then
Return View()
End If

유효성 검사 오류가 있는 경우 IsValid 속성은 false를 반환합니다. 이 경우 동영상을 만들기 위한 HTML 양식이 포함된 만들기 보기가 다시 표시됩니다.

Partial 클래스 만들기

Movie 클래스는 Entity Framework에서 생성됩니다. 솔루션 탐색기 창에서 MoviesDBModel.edmx 파일을 확장하고 MoviesDBModel.Designer 열면 Movie 클래스의 코드를 볼 수 있습니다. 코드 편집기에서 vb 파일(그림 2 참조).

Movie 엔터티에 대한 코드

그림 02: 무비 엔터티의 코드(전체 크기 이미지를 보려면 클릭)

Movie 클래스는 partial 클래스입니다. 즉, 이름이 같은 다른 partial 클래스를 추가하여 Movie 클래스의 기능을 확장할 수 있습니다. 유효성 검사 논리를 새 partial 클래스에 추가합니다.

목록 2의 클래스를 Models 폴더에 추가합니다.

목록 2 - Models\Movie.vb

Public Partial Class Movie

End Class

목록 2의 클래스에는 부분 한정자가 포함됩니다. 이 클래스에 추가하는 모든 메서드 또는 속성은 Entity Framework에서 생성된 Movie 클래스의 일부가 됩니다.

OnChanging 및 OnChanged Partial 메서드 추가

Entity Framework에서 엔터티 클래스를 생성하면 Entity Framework는 부분 메서드를 클래스에 자동으로 추가합니다. Entity Framework는 클래스의 각 속성에 해당하는 OnChanging 및 OnChanged 부분 메서드를 생성합니다.

Movie 클래스의 경우 Entity Framework는 다음 메서드를 만듭니다.

  • OnIdChanging
  • OnIdChanged
  • OnTitleChanging
  • OnTitleChanged
  • OnDirectorChanging
  • OnDirectorChanged
  • OnDateReleasedChanging
  • OnDateReleasedChanged

OnChanging 메서드는 해당 속성이 변경되기 바로 전에 호출됩니다. OnChanged 메서드는 속성이 변경된 직후에 호출됩니다.

이러한 부분 메서드를 활용하여 Movie 클래스에 유효성 검사 논리를 추가할 수 있습니다. 목록 3의 Update Movie 클래스는 타이틀 및 디렉터 속성에 흠 없는 값이 할당되어 있는지 확인합니다.

참고

partial 메서드는 구현할 필요가 없는 클래스에 정의된 메서드입니다. partial 메서드를 구현하지 않으면 컴파일러는 메서드 서명 및 메서드에 대한 모든 호출을 제거하므로 partial 메서드와 관련된 런타임 비용이 발생하지 않습니다. Visual Studio Code 편집기에서 키워드(keyword) 부분과 구현할 부분 목록을 볼 수 있는 공백을 입력하여 partial 메서드를 추가할 수 있습니다.

목록 3 - Models\Movie.vb

Imports System.ComponentModel

Partial Public Class Movie
    Implements IDataErrorInfo

    Private _errors As New Dictionary(Of String, String)()

    Private Sub OnTitleChanging(ByVal value As String)
        If value.Trim().Length = 0 Then
            _errors.Add("Title", "Title is required.")
        End If
    End Sub

    Private Sub OnDirectorChanging(ByVal value As String)
        If value.Trim().Length = 0 Then
            _errors.Add("Director", "Director is required.")
        End If
    End Sub

End Class

예를 들어 빈 문자열을 Title 속성에 할당하려고 하면 오류 메시지가 _errors 라는 사전에 할당됩니다.

이 시점에서 타이틀 속성에 빈 문자열을 할당하고 프라이빗 _errors 필드에 오류가 추가되면 실제로 아무 작업도 수행되지 않습니다. 이러한 유효성 검사 오류를 ASP.NET MVC 프레임워크에 노출하려면 IDataErrorInfo 인터페이스를 구현해야 합니다.

IDataErrorInfo 인터페이스 구현

IDataErrorInfo 인터페이스는 첫 번째 버전부터 .NET 프레임워크의 일부였습니다. 이 인터페이스는 매우 간단한 인터페이스입니다.

Public Interface IDataErrorInfo
  Default ReadOnly Property Item(ByVal columnName As String) As String
  ReadOnly Property [Error]() As String
End Interface

클래스가 IDataErrorInfo 인터페이스를 구현하는 경우 ASP.NET MVC 프레임워크는 클래스의 instance 만들 때 이 인터페이스를 사용합니다. 예를 들어 홈 컨트롤러 만들기() 작업은 Movie 클래스의 instance 허용합니다.

<AcceptVerbs(HttpVerbs.Post)> _
Public Function Create(<Bind(Exclude := "Id")> ByVal movieToCreate As Movie) As ActionResult
    ' Validate
    If (Not ModelState.IsValid) Then
        Return View()
    End If

    ' Add to database
    Try
        _db.AddToMovieSet(movieToCreate)
        _db.SaveChanges()

        Return RedirectToAction("Index")
    Catch
        Return View()
    End Try
End Function

ASP.NET MVC 프레임워크는 모델 바인더(DefaultModelBinder)를 사용하여 Create() 작업에 전달된 Movie의 instance 만듭니다. 모델 바인더는 HTML 양식 필드를 Movie 개체의 instance 바인딩하여 Movie 개체의 instance 만듭니다.

DefaultModelBinder는 클래스가 IDataErrorInfo 인터페이스를 구현하는지 여부를 검색합니다. 클래스가 이 인터페이스를 구현하는 경우 모델 바인더는 클래스의 각 속성에 대해 IDataErrorInfo.this 인덱서 를 호출합니다. 인덱서가 오류 메시지를 반환하는 경우 모델 바인더는 이 오류 메시지를 모델 상태에 자동으로 추가합니다.

DefaultModelBinder는 IDataErrorInfo.Error 속성도 확인합니다. 이 속성은 클래스와 연결된 속성이 아닌 특정 유효성 검사 오류를 나타내기 위한 것입니다. 예를 들어 Movie 클래스의 여러 속성 값에 따라 유효성 검사 규칙을 적용할 수 있습니다. 이 경우 Error 속성에서 유효성 검사 오류를 반환합니다.

목록 4의 업데이트된 Movie 클래스는 IDataErrorInfo 인터페이스를 구현합니다.

목록 4 - Models\Movie.vb(IDataErrorInfo 구현)

Imports System.ComponentModel

Partial Public Class Movie
    Implements IDataErrorInfo

    Private _errors As New Dictionary(Of String, String)()

    Private Sub OnTitleChanging(ByVal value As String)
        If value.Trim().Length = 0 Then
            _errors.Add("Title", "Title is required.")
        End If
    End Sub

    Private Sub OnDirectorChanging(ByVal value As String)
        If value.Trim().Length = 0 Then
            _errors.Add("Director", "Director is required.")
        End If
    End Sub

#Region "IDataErrorInfo Members"

    Public ReadOnly Property [Error]() As String Implements IDataErrorInfo.Error
        Get
            Return String.Empty
        End Get
    End Property

    Default Public ReadOnly Property Item(ByVal columnName As String) As String Implements IDataErrorInfo.Item
        Get
            If _errors.ContainsKey(columnName) Then
                Return _errors(columnName)
            End If
            Return String.Empty
        End Get
    End Property

#End Region

End Class

목록 4에서 인덱서 속성은 _errors 컬렉션을 확인하여 인덱서에 전달된 속성 이름에 해당하는 키가 포함되어 있는지 확인합니다. 속성과 연결된 유효성 검사 오류가 없으면 빈 문자열이 반환됩니다.

수정된 Movie 클래스를 사용하기 위해 홈 컨트롤러를 수정할 필요가 없습니다. 그림 3에 표시된 페이지는 제목 또는 디렉터 양식 필드에 값을 입력하지 않을 때 발생하는 일을 보여 줍니다.

자동으로 작업 메서드 만들기

그림 03: 값이 누락된 양식(전체 크기 이미지를 보려면 클릭)

DateReleased 값의 유효성이 자동으로 검사됩니다. DateReleased 속성은 NULL 값을 허용하지 않으므로 DefaultModelBinder는 값이 없는 경우 이 속성에 대한 유효성 검사 오류를 자동으로 생성합니다. DateReleased 속성에 대한 오류 메시지를 수정하려면 사용자 지정 모델 바인더를 만들어야 합니다.

요약

이 자습서에서는 IDataErrorInfo 인터페이스를 사용하여 유효성 검사 오류 메시지를 생성하는 방법을 알아보았습니다. 먼저 Entity Framework에서 생성된 Partial Movie 클래스의 기능을 확장하는 Partial Movie 클래스를 만들었습니다. 다음으로, Movie 클래스 OnTitleChanging() 및 OnDirectorChanging() 부분 메서드에 유효성 검사 논리를 추가했습니다. 마지막으로 이러한 유효성 검사 메시지를 ASP.NET MVC 프레임워크에 노출하기 위해 IDataErrorInfo 인터페이스를 구현했습니다.