모델에 유효성 검사 추가(C#)Adding Validation to the Model (C#)

Rick Andersonby Rick Anderson

Note

ASP.NET MVC 5와 Visual Studio 2013를 사용 하는이 자습서의 업데이트 된 버전 을 사용할 수 있습니다.An updated version of this tutorial is available here that uses ASP.NET MVC 5 and Visual Studio 2013. 더 안전 하 고 더 간단 하 고 더 많은 기능을 보여 줍니다.It's more secure, much simpler to follow and demonstrates more features.

이 자습서에서는 Microsoft Visual Studio의 무료 버전인 Microsoft Visual Web Developer 2010 Express 서비스 팩 1을 사용 하 여 ASP.NET MVC 웹 응용 프로그램을 빌드하는 기본 사항을 학습 합니다.This tutorial will teach you the basics of building an ASP.NET MVC Web application using Microsoft Visual Web Developer 2010 Express Service Pack 1, which is a free version of Microsoft Visual Studio. 시작 하기 전에 아래 나열 된 필수 구성 요소를 설치 했는지 확인 합니다.Before you start, make sure you've installed the prerequisites listed below. 웹 플랫폼 설치 관리자링크를 클릭 하 여 모든 항목을 설치할 수 있습니다.You can install all of them by clicking the following link: Web Platform Installer. 또는 다음 링크를 사용 하 여 필수 구성 요소를 개별적으로 설치할 수 있습니다.Alternatively, you can individually install the prerequisites using the following links:

Visual Web Developer 2010 대신 Visual Studio 2010을 사용 하는 경우 Visual studio 2010 필수 조건링크를 클릭 하 여 필수 구성 요소를 설치 합니다.If you're using Visual Studio 2010 instead of Visual Web Developer 2010, install the prerequisites by clicking the following link: Visual Studio 2010 prerequisites.

이 항목과 함께 사용할 수 있는 C# 소스 코드가 포함 된 Visual Web Developer 프로젝트를 사용할 수 있습니다.A Visual Web Developer project with C# source code is available to accompany this topic. 버전을 C# 다운로드합니다.Download the C# version. Visual Basic 선호 하는 경우이 자습서의 Visual Basic 버전 으로 전환 합니다.If you prefer Visual Basic, switch to the Visual Basic version of this tutorial.

이 섹션에서는 Movie 모델에 유효성 검사 논리를 추가 하 고, 사용자가 응용 프로그램을 사용 하 여 동영상을 만들거나 편집 하려고 할 때마다 유효성 검사 규칙이 적용 되도록 합니다.In this section you'll add validation logic to the Movie model, and you'll ensure that the validation rules are enforced any time a user attempts to create or edit a movie using the application.

작업 건조 유지Keeping Things DRY

ASP.NET MVC의 핵심 디자인 개념 중 하나는 마른 ("반복 금지")입니다.One of the core design tenets of ASP.NET MVC is DRY ("Don't Repeat Yourself"). ASP.NET MVC는 기능이 나 동작을 한 번만 지정한 다음 응용 프로그램의 모든 위치에 반영 되도록 권장 합니다.ASP.NET MVC encourages you to specify functionality or behavior only once, and then have it be reflected everywhere in an application. 이렇게 하면 작성 해야 하는 코드의 양이 줄어들고 작성 하는 코드를 훨씬 쉽게 유지 관리할 수 있습니다.This reduces the amount of code you need to write and makes the code you do write much easier to maintain.

ASP.NET MVC 및 Entity Framework Code First에서 제공 하는 유효성 검사 지원은 작동 중인 마른 원칙의 좋은 예입니다.The validation support provided by ASP.NET MVC and Entity Framework Code First is a great example of the DRY principle in action. 모델 클래스의 한 위치에서 유효성 검사 규칙을 선언적으로 지정할 수 있으며, 이러한 규칙은 응용 프로그램의 모든 위치에서 적용 됩니다.You can declaratively specify validation rules in one place (in the model class) and then those rules are enforced everywhere in the application.

영화 응용 프로그램에서이 유효성 검사 지원을 활용할 수 있는 방법을 살펴보겠습니다.Let's look at how you can take advantage of this validation support in the movie application.

무비 모델에 유효성 검사 규칙 추가Adding Validation Rules to the Movie Model

먼저 Movie 클래스에 유효성 검사 논리를 추가 합니다.You'll begin by adding some validation logic to the Movie class.

Movie.cs 파일을 엽니다.Open the Movie.cs file. System.ComponentModel.DataAnnotations 네임 스페이스를 참조 하는 파일의 맨 위에 using 문을 추가 합니다.Add a using statement at the top of the file that references the System.ComponentModel.DataAnnotations namespace:

using System.ComponentModel.DataAnnotations;

네임 스페이스는 .NET Framework의 일부입니다.The namespace is part of the .NET Framework. 클래스 또는 속성에 선언적으로 적용할 수 있는 유효성 검사 특성의 기본 제공 집합을 제공 합니다.It provides a built-in set of validation attributes that you can apply declaratively to any class or property.

이제 Movie 클래스를 업데이트 하 여 기본 제공 Required, StringLengthRange 유효성 검사 특성을 활용 합니다.Now update the Movie class to take advantage of the built-in Required, StringLength, and Range validation attributes. 특성을 적용할 위치의 예로 다음 코드를 사용 합니다.Use the following code as an example of where to apply the attributes.

public class Movie
{
    public int ID { get; set; }

    [Required(ErrorMessage = "Title is required")]
    public string Title { get; set; }

    [Required(ErrorMessage = "Date is required")]
    public DateTime ReleaseDate { get; set; }

    [Required(ErrorMessage = "Genre must be specified")]
    public string Genre { get; set; }

    [Range(1, 100, ErrorMessage = "Price must be between $1 and $100")]
    public decimal Price { get; set; }

    [StringLength(5)]
    public string Rating { get; set; }
}

이 유효성 검사 특성은 적용되는 모델 속성에 시행하려는 동작을 지정합니다.The validation attributes specify behavior that you want to enforce on the model properties they are applied to. Required 특성은 속성에 값이 있어야 함을 나타냅니다. 이 샘플에서 동영상은 유효 하려면 Title, ReleaseDate, GenrePrice 속성에 대 한 값이 있어야 합니다.The Required attribute indicates that a property must have a value; in this sample, a movie has to have values for the Title, ReleaseDate, Genre, and Price properties in order to be valid. Range 특성은 지정한 범위 내로 값을 제한합니다.The Range attribute constrains a value to within a specified range. StringLength 특성을 사용하면 문자열 속성의 최대 길이와, 그리고 필요에 따라 최소 길이를 설정할 수 있습니다.The StringLength attribute lets you set the maximum length of a string property, and optionally its minimum length.

Code First를 사용 하면 응용 프로그램에서 데이터베이스의 변경 내용을 저장 하기 전에 모델 클래스에서 지정 하는 유효성 검사 규칙이 적용 됩니다.Code First ensures that the validation rules you specify on a model class are enforced before the application saves changes in the database. 예를 들어, 몇 가지 필수 Movie 속성 값이 누락 되 고 가격이 0 (유효한 범위를 벗어남) 이기 때문에 아래 코드는 SaveChanges 메서드가 호출 될 때 예외를 throw 합니다.For example, the code below will throw an exception when the SaveChanges method is called, because several required Movie property values are missing and the price is zero (which is out of the valid range).

MovieDBContext db = new MovieDBContext();

Movie movie = new Movie();
movie.Title = "Gone with the Wind";
movie.Price = 0.0M;

db.Movies.Add(movie);
db.SaveChanges();        // <= Will throw validation exception

.NET Framework에 의해 자동으로 적용 되는 유효성 검사 규칙이 있으면 응용 프로그램을 더욱 강력 하 게 만들 수 있습니다.Having validation rules automatically enforced by the .NET Framework helps make your application more robust. 또한 무언가의 유효성 검사를 잊거나, 실수로 데이터베이스에 불량 데이터가 들어가지 않도록 할 수 있습니다.It also ensures that you can't forget to validate something and inadvertently let bad data into the database.

다음은 업데이트 된 Movie.cs 파일에 대 한 전체 코드 목록입니다.Here's a complete code listing for the updated Movie.cs file:

using System;
using System.Data.Entity;
using System.ComponentModel.DataAnnotations;

namespace MvcMovie.Models
{
    public class Movie
    {
        public int ID { get; set; }

        [Required(ErrorMessage = "Title is required")]
        public string Title { get; set; }

        public DateTime ReleaseDate { get; set; }

        [Required(ErrorMessage = "Genre must be specified")]
        public string Genre { get; set; }

        [Range(1, 100, ErrorMessage = "Price must be between $1 and $100")]
        public decimal Price { get; set; }

        [StringLength(5)]
        public string Rating { get; set; }
    }

    public class MovieDBContext : DbContext
    {
        public DbSet<Movie> Movies { get; set; }
    }
}

ASP.NET MVC의 유효성 검사 오류 UIValidation Error UI in ASP.NET MVC

응용 프로그램을 다시 실행 하 고/또는 비디오 URL로 이동 합니다.Re-run the application and navigate to the /Movies URL.

동영상 만들기 링크를 클릭 하 여 새 동영상을 추가 합니다.Click the Create Movie link to add a new movie. 양식에서 잘못 된 값을 입력 한 다음 만들기 단추를 클릭 합니다.Fill out the form with some invalid values and then click the Create button.

8_validationErrors8_validationErrors

양식에서 자동으로 배경색을 사용 하 여 잘못 된 데이터를 포함 하 고 각 텍스트 상자 옆에 적절 한 유효성 검사 오류 메시지를 내보낸 텍스트 상자를 강조 표시 하는 방법을 확인 합니다.Notice how the form has automatically used a background color to highlight the text boxes that contain invalid data and has emitted an appropriate validation error message next to each one. 오류 메시지는 Movie 클래스에 주석을 달 때 지정한 오류 문자열과 일치 합니다.The error messages match the error strings you specified when you annotated the Movie class. 오류는 클라이언트 쪽 (JavaScript 사용) 및 서버 쪽 (사용자가 JavaScript를 사용 하지 않도록 설정한 경우) 모두에 적용 됩니다.The errors are enforced both client-side (using JavaScript) and server-side (in case a user has JavaScript disabled).

실제 혜택은이 유효성 검사 UI를 사용 하도록 설정 하기 위해 MoviesController 클래스 또는 Create. cshtml 뷰에서 코드 한 줄을 변경할 필요가 없다는 것입니다.A real benefit is that you didn't need to change a single line of code in the MoviesController class or in the Create.cshtml view in order to enable this validation UI. 이 자습서의 앞부분에서 만든 컨트롤러 및 뷰는 Movie 모델 클래스에서 특성을 사용 하 여 지정한 유효성 검사 규칙을 자동으로 선택 합니다.The controller and views you created earlier in this tutorial automatically picked up the validation rules that you specified using attributes on the Movie model class.

Create View 및 Create Action 메서드에서 유효성 검사를 수행 하는 방법How Validation Occurs in the Create View and Create Action Method

컨트롤러나 보기의 코드를 전혀 수정하지 않고도 어떻게 유효성 검사 UI가 생성되는지 궁금할 것입니다.You might wonder how the validation UI was generated without any updates to the code in the controller or views. 다음 목록에서는 MovieController 클래스의 Create 메서드를 보여 줍니다.The next listing shows what the Create methods in the MovieController class look like. 이 자습서의 앞부분에서 만든 방법에서 변경 되지 않았습니다.They're unchanged from how you created them earlier in this tutorial.

//
// GET: /Movies/Create

public ActionResult Create()
{
    return View();
}

//
// POST: /Movies/Create

[HttpPost]
public ActionResult Create(Movie movie)
{
    if (ModelState.IsValid)
    {
        db.Movies.Add(movie);
        db.SaveChanges();
        return RedirectToAction("Index");
    }

    return View(movie);
}

첫 번째 작업 메서드는 초기 만들기 폼을 표시 합니다.The first action method displays the initial Create form. 두 번째는 폼 게시를 처리 합니다.The second handles the form post. 두 번째 Create 메서드 ModelState.IsValid를 호출 하 여 영화에 유효성 검사 오류가 있는지 여부를 확인 합니다.The second Create method calls ModelState.IsValid to check whether the movie has any validation errors. 이 메서드를 호출하면 개체에 적용된 모든 유효성 검사 특성이 평가됩니다.Calling this method evaluates any validation attributes that have been applied to the object. 개체에 유효성 검사 오류가 있는 경우 Create 메서드는 폼을 보다 합니다.If the object has validation errors, the Create method redisplays the form. 오류가 없으면 메서드가 데이터베이스에 새 영화를 저장합니다.If there are no errors, the method saves the new movie in the database.

다음은이 자습서의 앞부분에서 스 캐 폴드 하는 Create. cshtml 보기 템플릿입니다.Below is the Create.cshtml view template that you scaffolded earlier in the tutorial. 이 항목은 위 두 작업 메서드에서 최초 양식을 표시하고 오류 시 다시 표시하기 위해 사용됩니다.It's used by the action methods shown above both to display the initial form and to redisplay it in the event of an error.

@model MvcMovie.Models.Movie
@{
    ViewBag.Title = "Create";
}
<h2>
    Create</h2>
<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
@using (Html.BeginForm())
{
    @Html.ValidationSummary(true)
    <fieldset>
        <legend>Movie</legend>
        <div class="editor-label">
            @Html.LabelFor(model => model.Title)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Title)
            @Html.ValidationMessageFor(model => model.Title)
        </div>
        <div class="editor-label">
            @Html.LabelFor(model => model.ReleaseDate)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.ReleaseDate)
            @Html.ValidationMessageFor(model => model.ReleaseDate)
        </div>
        <div class="editor-label">
            @Html.LabelFor(model => model.Genre)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Genre)
            @Html.ValidationMessageFor(model => model.Genre)
        </div>
        <div class="editor-label">
            @Html.LabelFor(model => model.Price)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Price)
            @Html.ValidationMessageFor(model => model.Price)
        </div>
        <div class="editor-label">
            @Html.LabelFor(model => model.Rating)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Rating)
            @Html.ValidationMessageFor(model => model.Rating)
        </div>
        <p>
            <input type="submit" value="Create" />
        </p>
    </fieldset>
}
<div>
    @Html.ActionLink("Back to List", "Index")
</div>

코드에서 Html.EditorFor 도우미를 사용 하 여 각 Movie 속성의 <input> 요소를 출력 하는 방법을 확인 합니다.Notice how the code uses an Html.EditorFor helper to output the <input> element for each Movie property. 이 도우미 옆은 Html.ValidationMessageFor 도우미 메서드에 대 한 호출입니다.Next to this helper is a call to the Html.ValidationMessageFor helper method. 이러한 두 도우미 메서드는 컨트롤러에서 뷰에 전달 되는 모델 개체 (이 경우에는 Movie 개체)를 사용 합니다.These two helper methods work with the model object that's passed by the controller to the view (in this case, a Movie object). 모델에 지정 된 유효성 검사 특성을 자동으로 검색 하 고 오류 메시지를 적절 하 게 표시 합니다.They automatically look for validation attributes specified on the model and display error messages as appropriate.

이 방법에 대 한 유용한 정보는 컨트롤러와 Create view 템플릿에서 적용 되는 실제 유효성 검사 규칙이 나 표시 되는 특정 오류 메시지에 대 한 정보를 인식 하지 못하는 것입니다.What's really nice about this approach is that neither the controller nor the Create view template knows anything about the actual validation rules being enforced or about the specific error messages displayed. 유효성 검사 규칙 및 오류 문자열은 Movie 클래스에서만 지정됩니다.The validation rules and the error strings are specified only in the Movie class.

유효성 검사 논리를 나중에 변경 하려면 정확 하 게 한 곳에서 수행할 수 있습니다.If you want to change the validation logic later, you can do so in exactly one place. 모든 유효성 검사 논리가 한 곳에서 정의되어 모든 곳에서 사용되므로 애플리케이션의 서로 다른 부분이 규칙 적용 방법에 부합하는지 우려하지 않아도 됩니다.You won't have to worry about different parts of the application being inconsistent with how the rules are enforced — all validation logic will be defined in one place and used everywhere. 이렇게 하면 코드가 매우 깔끔해지고 유지 관리 및 확장이 간편합니다.This keeps the code very clean, and makes it easy to maintain and evolve. 또한 반복 금지 원칙에 완전히 부합하게 됩니다.And it means that you'll be fully honoring the DRY principle.

동영상 모델에 서식 추가Adding Formatting to the Movie Model

Movie.cs 파일을 엽니다.Open the Movie.cs file. System.ComponentModel.DataAnnotations 네임 스페이스는 기본 제공 유효성 검사 특성 집합 외에도 서식 특성을 제공 합니다.The System.ComponentModel.DataAnnotations namespace provides formatting attributes in addition to the built-in set of validation attributes. DisplayFormat 특성과 DataType 열거형 값을 릴리스 날짜 및 가격 필드에 적용 합니다.You'll apply the DisplayFormat attribute and a DataType enumeration value to the release date and to the price fields. 다음 코드에서는 적절 한 DisplayFormat 특성이 있는 ReleaseDatePrice 속성을 보여 줍니다.The following code shows the ReleaseDate and Price properties with the appropriate DisplayFormat attribute.

[DataType(DataType.Date)] 
public DateTime ReleaseDate { get; set; }

[DataType(DataType.Currency)] 
public decimal Price { get; set; }

또는 DataFormatString 값을 명시적으로 설정할 수 있습니다.Alternatively, you could explicitly set a DataFormatString value. 다음 코드에서는 날짜 형식 문자열 (즉, "d")이 포함 된 릴리스 날짜 속성을 보여 줍니다.The following code shows the release date property with a date format string (namely, "d"). 이를 사용 하 여 릴리스 날짜의 일부로 시간을 원하지 않도록 지정 합니다.You'd use this to specify that you don't want to time as part of the release date.

[DisplayFormat(DataFormatString = "{0:d}")]
public DateTime ReleaseDate { get; set; }

다음 코드는 Price 속성의 형식을 통화로 지정 합니다.The following code formats the Price property as currency.

[DisplayFormat(DataFormatString = "{0:c}")]
public decimal Price { get; set; }

전체 Movie 클래스는 다음과 같습니다.The complete Movie class is shown below.

public class Movie
{
    public int ID { get; set; }

    [Required(ErrorMessage = "Title is required")]
    public string Title { get; set; }

    [DisplayFormat(DataFormatString = "{0:d}")]
    public DateTime ReleaseDate { get; set; }

    [Required(ErrorMessage = "Genre must be specified")]
    public string Genre { get; set; }

    [Range(1, 100, ErrorMessage = "Price must be between $1 and $100")]
    [DisplayFormat(DataFormatString = "{0:c}")]
    public decimal Price { get; set; }

    [StringLength(5)]
    public string Rating { get; set; }
}

응용 프로그램을 실행 하 고 Movies 컨트롤러로 이동 합니다.Run the application and browse to the Movies controller.

8_format_SM

이 시리즈의 다음 부분에서는 애플리케이션을 검토하고 자동 생성된 DetailsDelete 메서드를 몇 가지 개선합니다.In the next part of the series, we'll review the application and make some improvements to the automatically generated Details and Delete methods.