Search

'ModelState'에 해당되는 글 1건

  1. 2010.05.31 M, V 그리고 C의 각방생활(4) - 유효성 검사 8

M, V 그리고 C의 각방생활(4) - 유효성 검사

ASP.NET MVC 2010. 5. 31. 09:00 Posted by 네버덜레스
안녕하세요. 지난 포스팅에 이어서(넘흐 오랜만이죠^^;) 시작하겠습니다. 아마 다들 잊으셨을 겁니다. 여기까지 했었죠?


_db.SaveChanges() 를 하려 했더니, 에러가 발생했습니다. 자세히 들여다 보니


ID 에 NULL 값을 넣을 수가 없다네요. 이래서 에러가 발생했죠.
아~ 이래서 사용자가 빈 값을 넣으려 하면 막아야하겠구나~ 라는 생각이 번뜩 드셨을겁니다.

유효성 검사!

유효성검사라 하면 필수입력값에는 꼭 데이터를 입력해야하고, 데이터의 타입이나 길이에 맞게 들어오게 체크하는 것을 말하겠죠?

ASP.NET MVC 프레임워크에서는 모델 스테이트(Model State)를 제공합니다. 정확히 말하면 model state dictionary 라고 해서 유효성 에러들을 표시하기 위해 사용됩니다. 유효성 검사중에 해당 프로퍼티에서 fail 이 발생하면 모델 스테이트에 이를 추가합니다. 모델 스테이트에 에러가 있으면 ModelState.IsVaild 는 false를 반환합니다.
여기까지 설명을 드리고, 예제와 함께 보시겠습니다.

예제 만들기

아주 간단한 전화번호를 담는 TelDir 클래스를 만들겠습니다.


DirectoryController 도 추가하겠습니다. 이 컨트롤러에 두개의 Create 액션메쏘드를 만들겠습니다. 하나는 /Directory/Create url 요청시(GET) 호출되는 메쏘드이고, 다른 하나는 POST로 호출되는 메쏘드 입니다. 아시죠?^^
ASP.NET MVC 프레임워크에서는 자동적으로 폼 필드에 값을 해당 모델 속성들과 매핑을 시킵니다. 모델 바인더가 이런 일을 하게되죠. 예제에서 처럼 HTML 폼 필드의 값을 TelDir 객체에 매핑을 시키는데, 에러가 없이 바인딩이 되면 즉, ModelState.IsValid가 true 이면 데이터베이스에 저장을 하는 것이고, 그렇지 않다면, 다시 폼을 그리며 에러를 표시하게됩니다.


뷰도 같이 만들겠습니다. 액션메쏘드에서 오른쪽버튼을 클릭하여 Add View 를 선택하고, 강하게 생성하겠습니다.


추가하기 전에 빌드하는 것 잊지 않으셨죠? 모델 생성 후 빌드를 하지 않으면 View data class 항목에 표시가 되지 않습니다. Add 해서 완료를 하시면 /Views/Directory/Create.aspx 가 생성되었습니다.

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<MvcTest.Models.TelDir>" %>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
 Create
</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
    <h2>Create</h2>
    <% using (Html.BeginForm()) {%>
        <%: Html.ValidationSummary(true) %>
        <fieldset>
            <legend>Fields</legend>
           
            <div class="editor-label">
                <%: Html.LabelFor(model => model.Name) %>
            </div>
            <div class="editor-field">
                <%: Html.TextBoxFor(model => model.Name) %>
                <%: Html.ValidationMessageFor(model => model.Name) %>
            </div>
           
            <div class="editor-label">
                <%: Html.LabelFor(model => model.Phone) %>
            </div>
            <div class="editor-field">
                <%: Html.TextBoxFor(model => model.Phone) %>
                <%: Html.ValidationMessageFor(model => model.Phone) %>
            </div>
           
            <div class="editor-label">
                <%: Html.LabelFor(model => model.SpeedDial) %>
            </div>
            <div class="editor-field">
                <%: Html.TextBoxFor(model => model.SpeedDial) %>
                <%: Html.ValidationMessageFor(model => model.SpeedDial) %>
            </div>
           
            <div class="editor-label">
                <%: Html.LabelFor(model => model.Email) %>
            </div>
            <div class="editor-field">
                <%: Html.TextBoxFor(model => model.Email) %>
                <%: Html.ValidationMessageFor(model => model.Email) %>
            </div>
           
            <p>
                <input type="submit" value="Create" />
            </p>
        </fieldset>
    <% } %>
</asp:Content>

휴. 여기까지 했으니 이제 유효성검사를 해보실까요?
다음과 같이 컨트롤러에서 유효성 검사를 할수 있습니다.


물론, 클라이언트단인 aspx 에서도 할 수 있겠죠. 제가 프로젝트에서 경험해본 유효성검사는 클라이언트단에서 먼저 검사를 하고 혹시나 몰라서, 클라이언트에서의 유효성검사를 신뢰할수 없어서 서버단에서도 한번 더 유효성검사를 했었습니다. 코드가 중복되고 또한 비슷한 UI 에서도 같은 검사를 해야했었죠.
ASP.NET MVC 에서는 이러한 부분을 모두 없애고 모델클래스에서 이를 담당하게 합니다. 심플해지고 개발속도도 향상되죠.

DataAnnotation을 이용한 유효성 검사


위와같이 컨트롤러와 뷰가아닌 모델에 유효성 검사로직을 두게되면, 다른 UI(Edit와 같은) 에서도 따로 유효성 검사를 하지 않고도 동일한 유효성 검사를 할 수 있습니다. 이렇게 함으로써 중복되는 코드를 피할 수 있게되는 거죠. DRY관점에서도 올바른 방향으로 나가는 거겠죠?ㅡ.ㅡ

위 소스를 보시면 유효성 검사를 위한 몇개의 속성들이 눈에 띄실겁니다.  using 문에 System.ComponentModel.DataAnnotations를 추가하면 유효성 검사 속성들을 사용할 수가 있습니다. 
각 필드에 속성들을 추가할 수 있는데요. [Required], [Ragng], [ReqularExpression], [StringLength] 등이 있고 커스텀한 속성도 만들 수가 있습니다.
만약 Name 에 길이제한을 5자로 하고 싶다면 [StringLength(5, ErrorMessage="5자까지만!")] 을 추가만 하시면 됩니다. 모델의 유효성 검사를 추가함으로(컨트롤러와 뷰 수정없이), 이 모델을 사용하는 부분에는 모두 적용이 되는거죠. 참 쉽죠잉?

일단 에러를 내볼까요?


위 에러메시지가 표시되는 것은 Create.aspx 소스를 보시면

<div class="editor-field">
    <%: Html.TextBoxFor(model => model.Name) %>
    <%: Html.ValidationMessageFor(model => model.Name) %>
</div>

<%: Html.ValidationMessageFor() %> 를 보실 수 있습니다. 바로 이것이 ModelState.IsValid 가 false 여서 뷰를 다시 그릴때, 각각의 해당 필드 옆에 붙어서 에러메시지를 보여주는 유효성 검사 헬퍼 메쏘드 입니다.

여기서 마무리

바로 지난번에 이어 계속 진행하고 싶지만, 유효성 검사에 대해 설명하다보니 이것만으로 너무 길어져서 오늘도 여기서 마무리 하겠습니다(__). 곧 찾아뵙도록 하겠습니다. ^^

참고 : http://weblogs.asp.net/scottgu/archive/2010/01/15/asp-net-mvc-2-model-validation.aspx