ASP.NET Core의 양식 및 관련 태그 도우미

작성자: Rick Anderson, N. Taylor Mullen, Dave PaquetteJerrie Pelser

이 문서는 양식 및 양식에서 흔히 사용되는 HTML 요소를 사용하여 작업하는 방법을 보여줍니다. HTML 양식 요소는 웹앱이 서버에 데이터를 다시 게시하는 데 사용되는 기본 메커니즘을 제공합니다. 이 문서의 대부분은 태그 도우미 및 태그 도우미를 사용하여 강력한 HTML 양식을 생산적으로 만들 수 있는 방법을 설명합니다. 이 문서를 읽기 전에 태그 도우미 소개를 읽어보는 것을 권장합니다.

많은 경우 HTML 도우미는 특정 태그 도우미에 대한 대체 방법을 제공하지만, 태그 도우미는 HTML 도우미를 대체하지 않으며 각각의 HTML 도우미에 대한 태그 도우미가 존재하는 것은 아니라는 점을 인지하는 것이 중요합니다. HTML 도우미 대안이 있을 경우 그 내용도 언급합니다.

양식 태그 도우미

양식 태그 도우미:

  • MVC 컨트롤러 작업 또는 명명된 경로에 대한 HTML <양식>action 특성 값을 생성합니다.

  • 사이트 간 요청 위조를 방지하기 위해 숨겨진 요청 확인 토큰을 생성합니다(HTTP Post 작업 메서드에서 [ValidateAntiForgeryToken] 특성을 함께 사용할 경우).

  • asp-route-<Parameter Name> 특성을 제공하며, 여기서 <Parameter Name>은 경로 값에 추가됩니다. Html.BeginFormHtml.BeginRouteForm에 대한 routeValues 매개 변수는 유사한 기능을 제공합니다.

  • HTML 도우미 대안 Html.BeginFormHtml.BeginRouteForm가 있습니다.

샘플:

<form asp-controller="Demo" asp-action="Register" method="post">
    <!-- Input and Submit elements -->
</form>

위의 형식 태그 도우미에서는 다음 HTML을 생성합니다.

<form method="post" action="/Demo/Register">
    <!-- Input and Submit elements -->
    <input name="__RequestVerificationToken" type="hidden" value="<removed for brevity>">
</form>

MVC 런타임은 양식 태그 도우미의 특성 asp-controllerasp-action으로부터 action 특성 값을 생성합니다. 또한 양식 태그 도우미는 사이트 간 요청 위조를 방지하기 위해 숨겨진 요청 확인 토큰을 생성합니다(HTTP Post 작업 메서드에서 [ValidateAntiForgeryToken] 특성을 함께 사용할 경우). 사이트 간 요청 위조로부터 순수한 HTML 양식을 보호하기는 어렵습니다. 양식 태그 도우미는 이러한 서비스를 제공합니다.

명명된 경로 사용

asp-route 태그 도우미 특성도 HTML action 특성에 대한 태그를 생성할 수 있습니다. register라는 이름의 경로를 사용하는 앱은 등록 페이지에 다음 표시를 사용할 수 있습니다.

<form asp-route="register" method="post">
    <!-- Input and Submit elements -->
</form>

Views/Account 폴더의 많은 보기는(개별 사용자 계정을 사용하여 새로운 웹앱을 만들 때 생성됨) asp-route-returnurl 특성을 포함하고 있습니다.

<form asp-controller="Account" asp-action="Login"
     asp-route-returnurl="@ViewData["ReturnUrl"]"
     method="post" class="form-horizontal" role="form">

참고 항목

기본 제공 템플릿에서는 권한이 부여된 리소스에 액세스하려고 하지만 인증되지 읺거나 권한이 없는 경우에만 returnUrl이 자동으로 채워집니다. 권한이 없는 액세스를 시도하는 경우 보안 미들웨어는 사용자를 returnUrl 설정이 포함된 로그인 페이지에 리디렉션합니다.

양식 작업 태그 도우미

양식 작업 태그 도우미는 생성되는 <button ...> 또는 <input type="image" ...> 태그의 formaction 특성을 생성합니다. formaction 특성은 양식이 해당 데이터를 제출하는 위치를 제어합니다. image 형식의<입력> 요소와 <버튼> 요소에 바인딩됩니다. 양식 작업 태그 도우미를 통해 여러 개의 AnchorTagHelperasp- 특성을 사용하여 해당 요소에 대해 생성되는 formaction 링크를 제어할 수 있습니다.

formaction의 값을 제어하기 위해 지원되는 AnchorTagHelper 특성:

attribute 설명
asp-controller 컨트롤러의 이름입니다.
asp-action 작업 메서드의 이름입니다.
asp-area 영역의 이름입니다.
asp-page Razor 페이지의 이름입니다.
asp-page-handler Razor 페이지 처리기의 이름입니다.
asp-route 경로의 이름입니다.
asp-route-{value} 단일 URL 경로 값입니다. 예: asp-route-id="1234".
asp-all-route-data 모든 경로 값입니다.
asp-fragment URL 조각입니다.

컨트롤러에 제출 예제

다음 태그는 입력 또는 단추가 선택될 때 HomeControllerIndex 작업에 양식을 제출합니다.

<form method="post">
    <button asp-controller="Home" asp-action="Index">Click Me</button>
    <input type="image" src="..." alt="Or Click Me" asp-controller="Home" 
                                asp-action="Index">
</form>

위의 태그는 다음 HTML을 생성합니다.

<form method="post">
    <button formaction="/Home">Click Me</button>
    <input type="image" src="..." alt="Or Click Me" formaction="/Home">
</form>

페이지에 제출 예제

다음 표시는 AboutRazor 페이지에 양식을 제출합니다.

<form method="post">
    <button asp-page="About">Click Me</button>
    <input type="image" src="..." alt="Or Click Me" asp-page="About">
</form>

위의 태그는 다음 HTML을 생성합니다.

<form method="post">
    <button formaction="/About">Click Me</button>
    <input type="image" src="..." alt="Or Click Me" formaction="/About">
</form>

경로에 제출 예제

/Home/Test 엔드포인트를 살펴보겠습니다.

public class HomeController : Controller
{
    [Route("/Home/Test", Name = "Custom")]
    public string Test()
    {
        return "This is the test page";
    }
}

다음 태그는 /Home/Test 엔드포인트에 양식을 제출합니다.

<form method="post">
    <button asp-route="Custom">Click Me</button>
    <input type="image" src="..." alt="Or Click Me" asp-route="Custom">
</form>

위의 태그는 다음 HTML을 생성합니다.

<form method="post">
    <button formaction="/Home/Test">Click Me</button>
    <input type="image" src="..." alt="Or Click Me" formaction="/Home/Test">
</form>

입력 태그 도우미

입력 태그 도우미는 HTML <입력> 요소를 Razor 보기의 모델 식에 바인딩합니다.

구문:

<input asp-for="<Expression Name>">

입력 태그 도우미:

  • asp-for 특성에 지정된 식 이름에 대해 idname HTML 특성을 생성합니다. asp-for="Property1.Property2"m => m.Property1.Property2와 같습니다. 식의 이름은 asp-for 특성 값에 사용됩니다. 추가 정보는 식 이름 섹션을 참조하세요.

  • 모델 속성에 적용된 데이터 주석 특성 및 모델 형식에 따라 HTML type 특성 값을 설정합니다.

  • HTML type 특성 값이 지정된 경우 덮어쓰지 않습니다.

  • 모델 속성에 적용된 데이터 주석 특성에서 HTML5 유효성 검사 특성을 생성합니다.

  • Html.TextBoxForHtml.EditorFor와 HTML 도우미 기능이 겹칩니다. 자세한 내용은 입력 태그 도우미에 대한 HTML 도우미 대안 섹션을 참조하세요.

  • 강력한 형식 지정을 제공합니다. 속성의 이름이 변경되고 태그 도우미를 업데이트하지 않은 경우 다음과 비슷한 오류가 표시됩니다.

    An error occurred during the compilation of a resource required to process
    this request. Please review the following specific error details and modify
    your source code appropriately.
    
    Type expected
    'RegisterViewModel' does not contain a definition for 'Email' and no
    extension method 'Email' accepting a first argument of type 'RegisterViewModel'
    could be found (are you missing a using directive or an assembly reference?)
    

Input 태그 도우미는 .NET 형식을 기반으로 HTML type 특성을 설정합니다. 다음 표에서는 몇 가지 일반적인 .NET 형식 및 생성된 HTML 형식을 나열합니다(.NET 형식의 일부만 나열됨).

.NET 형식 입력 유형
Bool type="checkbox"
문자열 type="text"
DateTime type="datetime-local"
Byte type="number"
정수 type="number"
Single, Double type="number"

다음 표는 입력 태그 도우미가 특정 입력 형식에 매핑하는 몇 가지 일반적인 데이터 주석 특성을 보여줍니다(유효성 검사 특성의 일부만 나열됨).

Attribute 입력 유형
[EmailAddress] type="email"
[Url] type="url"
[HiddenInput] type="hidden"
[Phone] type="tel"
[DataType(DataType.Password)] type="password"
[DataType(DataType.Date)] type="date"
[DataType(DataType.Time)] type="time"

샘플:

using System.ComponentModel.DataAnnotations;

namespace FormsTagHelper.ViewModels
{
    public class RegisterViewModel
    {
        [Required]
        [EmailAddress]
        [Display(Name = "Email Address")]
        public string Email { get; set; }

        [Required]
        [DataType(DataType.Password)]
        public string Password { get; set; }
    }
}
@model RegisterViewModel

<form asp-controller="Demo" asp-action="RegisterInput" method="post">
    Email:  <input asp-for="Email" /> <br />
    Password: <input asp-for="Password" /><br />
    <button type="submit">Register</button>
</form>

위의 코드는 다음과 같은 HTML을 생성합니다.

<form method="post" action="/Demo/RegisterInput">
    Email:
    <input type="email" data-val="true"
            data-val-email="The Email Address field is not a valid email address."
            data-val-required="The Email Address field is required."
            id="Email" name="Email" value=""><br>
    Password:
    <input type="password" data-val="true"
            data-val-required="The Password field is required."
            id="Password" name="Password"><br>
    <button type="submit">Register</button>
    <input name="__RequestVerificationToken" type="hidden" value="<removed for brevity>">
</form>

EmailPassword 속성에 적용된 데이터 주석은 모델에서 메타데이터를 생성합니다. 입력 태그 도우미는 모델 메타데이터를 사용하고 HTML5data-val-* 특성을 생성합니다(모델 유효성 검사 참조). 이러한 특성은 입력 필드에 연결할 유효성 검사기를 설명합니다. 이 기능은 비간섭 HTML5 및 jQuery 유효성 검사를 제공합니다. 비간섭 특성은 data-val-rule="Error Message" 형식을 사용합니다. 여기서 rule은 유효성 검사 규칙의 이름(예: data-val-required, data-val-email, data-val-maxlength 등)입니다. 오류 메시지가 특성에서 제공되는 경우 data-val-rule 특성에 대한 값으로 표시됩니다. 또한 규칙에 대한 추가 세부 정보를 제공하는 data-val-ruleName-argumentName="argumentValue" 형식의 특성이 있습니다(예: data-val-maxlength-max="1024").

여러 input 컨트롤을 동일한 속성에 바인딩할 때, 생성된 컨트롤은 동일한 id를 공유하기 때문에 생성된 표시가 유효하지 않게 됩니다. 중복을 방지하려면 각 컨트롤의 id 특성을 명시적으로 지정하세요.

확인란 숨겨진 입력 렌더링

HTML5의 확인란은 선택하지 않은 경우 값을 제출하지 않습니다. 선택하지 않은 확인란에 대해 기본값을 보내도록 설정하려면 입력 태그 도우미는 확인란에 대해 추가적인 숨겨진 입력을 생성합니다.

예를 들어 부울 모델 속성 IsChecked에 대해 입력 태그 도우미를 사용하는 다음 Razor 태그를 고려해 보세요.

<form method="post">
    <input asp-for="@Model.IsChecked" />
    <button type="submit">Submit</button>
</form>

위의 Razor 태그는 다음과 유사한 HTML 태그를 생성합니다.

<form method="post">
    <input name="IsChecked" type="checkbox" value="true" />
    <button type="submit">Submit</button>

    <input name="IsChecked" type="hidden" value="false" /> 
</form>

위의 HTML 태그는 이름이 IsChecked이고, 값이 false인 추가적인 숨겨진 입력을 보여 줍니다. 기본적으로 이 숨겨진 입력은 양식의 끝에 렌더링됩니다. 양식이 제출되는 경우:

  • IsChecked 확인란 입력을 선택하면 truefalse 모두 값으로 전송됩니다.
  • IsChecked 확인란 입력을 선택하지 않으면 숨겨진 입력 값 false만 전송됩니다.

ASP.NET Core 모델 바인딩 프로세스는 bool 값에 바인딩할 때 첫 번째 값만 읽으므로 선택된 확인란에 대해 true 및 선택하지 않은 확인란에 대해 false로 나타납니다.

숨겨진 입력 렌더링의 동작을 구성하려면 MvcViewOptions.HtmlHelperOptions에서 CheckBoxHiddenInputRenderMode 속성을 설정합니다. 예시:

services.Configure<MvcViewOptions>(options =>
    options.HtmlHelperOptions.CheckBoxHiddenInputRenderMode =
        CheckBoxHiddenInputRenderMode.None);

위의 코드는 CheckBoxHiddenInputRenderModeCheckBoxHiddenInputRenderMode.None으로 설정하여 확인란에 대한 숨겨진 입력 렌더링을 사용하지 않도록 설정합니다. 사용 가능한 모든 렌더링 모드는 CheckBoxHiddenInputRenderMode 열거형을 참조하세요.

입력 태그 도우미에 대한 HTML 도우미 대안

Html.TextBox, Html.TextBoxFor, Html.EditorHtml.EditorFor는 입력 태그 도우미와 겹치는 기능을 갖고 있습니다. 입력 태그 도우미는 type 특성을 자동으로 설정하는 반면 Html.TextBoxHtml.TextBoxFor는 설정하지 않습니다. Html.EditorHtml.EditorFor는 컬렉션, 복잡한 개체 및 템플릿을 처리하는 반면 입력 태그 도우미는 처리하지 않습니다. 입력 태그 도우미, Html.EditorForHtml.TextBoxFor은 강력한 형식이 지정(람다 식 사용)되는 반면 Html.TextBoxHtml.Editor는 그렇지 않습니다.(식 이름 사용)

HtmlAttributes

@Html.Editor()@Html.EditorFor()는 기본 템플릿을 실행할 때 htmlAttributes라는 특수한 ViewDataDictionary 항목을 사용합니다. 이 동작은 필요에 따라 additionalViewData 매개 변수를 사용하여 확대됩니다. "htmlAttributes" 키는 대/소문자를 구분합니다. "htmlAttributes" 키는 @Html.TextBox()와 같은 입력 도우미에 전달된 htmlAttributes 개체와 유사하게 처리됩니다.

@Html.EditorFor(model => model.YourProperty, 
  new { htmlAttributes = new { @class="myCssClass", style="Width:100px" } })

식 이름

asp-for 특성 값은 ModelExpression이며 람다 식의 우변입니다. 따라서 asp-for="Property1"은 생성된 코드에서 m => m.Property1이 됩니다. 따라서 Model과 함께 접두사로 사용할 필요가 없습니다. "@" 문자를 사용하여 인라인 식을 시작하고 m. 앞으로 이동할 수 있습니다.

@{
  var joe = "Joe";
}

<input asp-for="@joe">

다음을 생성합니다.

<input type="text" id="joe" name="joe" value="Joe">

컬렉션 속성을 사용할 경우, asp-for="CollectionProperty[23].Member"i23 값을 가졌을 때의 asp-for="CollectionProperty[i].Member"와 동일한 이름을 생성합니다.

ASP.NET Core MVC가 ModelExpression의 값을 계산하는 경우 ModelState를 비롯한 여러 원본을 검사합니다. <input type="text" asp-for="Name">을 가정해보세요. 계산되는 value 특성은 다음 중 null이 아닌 첫 번째 값입니다.

  • "Name" 키를 가진 ModelState 항목
  • Model.Name 식의 결과

보기 모델의 속성 경로를 사용하여 자식 속성을 탐색할 수 있습니다. 자식 Address 속성을 포함하는 보다 복잡한 모델 클래스를 고려해보세요.

public class AddressViewModel
{
    public string AddressLine1 { get; set; }
}
public class RegisterAddressViewModel
{
    public string Email { get; set; }

    [DataType(DataType.Password)]
    public string Password { get; set; }

    public AddressViewModel Address { get; set; }
}

보기에서 Address.AddressLine1에 바인딩합니다.

@model RegisterAddressViewModel

<form asp-controller="Demo" asp-action="RegisterAddress" method="post">
    Email:  <input asp-for="Email" /> <br />
    Password: <input asp-for="Password" /><br />
    Address: <input asp-for="Address.AddressLine1" /><br />
    <button type="submit">Register</button>
</form>

Address.AddressLine1에 대해 다음 HTML이 생성됩니다.

<input type="text" id="Address_AddressLine1" name="Address.AddressLine1" value="">

식 이름 및 컬렉션

이번 예제에서 모델은 Colors의 목록을 담고 있습니다.

public class Person
{
    public List<string> Colors { get; set; }

    public int Age { get; set; }
}

작업 메서드:

public IActionResult Edit(int id, int colorIndex)
{
    ViewData["Index"] = colorIndex;
    return View(GetPerson(id));
}

다음 Razor는 특정 Color 요소에 액세스하는 방법을 보여 줍니다.

@model Person
@{
    var index = (int)ViewData["index"];
}

<form asp-controller="ToDo" asp-action="Edit" method="post">
    @Html.EditorFor(m => m.Colors[index])
    <label asp-for="Age"></label>
    <input asp-for="Age" /><br />
    <button type="submit">Post</button>
</form>

Views/Shared/EditorTemplates/String.cshtml 템플릿:

@model string

<label asp-for="@Model"></label>
<input asp-for="@Model" /> <br />

List<T>를 사용하는 예제:

public class ToDoItem
{
    public string Name { get; set; }

    public bool IsDone { get; set; }
}

다음 Razor는 컬렉션을 반복하는 방법을 보여 줍니다.

@model List<ToDoItem>

<form asp-controller="ToDo" asp-action="Edit" method="post">
    <table>
        <tr> <th>Name</th> <th>Is Done</th> </tr>

        @for (int i = 0; i < Model.Count; i++)
        {
            <tr>
                @Html.EditorFor(model => model[i])
            </tr>
        }

    </table>
    <button type="submit">Save</button>
</form>

Views/Shared/EditorTemplates/ToDoItem.cshtml 템플릿:

@model ToDoItem

<td>
    <label asp-for="@Model.Name"></label>
    @Html.DisplayFor(model => model.Name)
</td>
<td>
    <input asp-for="@Model.IsDone" />
</td>

@*
    This template replaces the following Razor which evaluates the indexer three times.
    <td>
         <label asp-for="@Model[i].Name"></label>
         @Html.DisplayFor(model => model[i].Name)
     </td>
     <td>
         <input asp-for="@Model[i].IsDone" />
     </td>
*@

값이 asp-for 또는 Html.DisplayFor 해당 컨텍스트에서 사용될 때 가능한 경우 foreach를 사용해야 합니다. 일반적으로 for는 열거자를 할당할 필요가 없으므로 foreach보다 좋습니다(시나리오에서 허용하는 경우). 그러나 LINQ 식에서 인덱서를 평가하는 작업은 비용이 많이 들기 때문에 최소화해야 합니다.

 

참고 항목

위의 주석 처리된 코드 예제는 람다 식을 @ 연산자로 바꿔서 목록에 있는 각 ToDoItem에 액세스하는 방법을 보여줍니다.

텍스트 영역 태그 도우미

Textarea Tag Helper 태그 도우미는 입력 태그 도우미와 비슷합니다.

  • < textarea >요소에 대한 모델에서idname 특성 및 데이터 유효성 검사 특성을 생성합니다.

  • 강력한 형식 지정을 제공합니다.

  • HTML 도우미 대안: Html.TextAreaFor

샘플:

using System.ComponentModel.DataAnnotations;

namespace FormsTagHelper.ViewModels
{
    public class DescriptionViewModel
    {
        [MinLength(5)]
        [MaxLength(1024)]
        public string Description { get; set; }
    }
}
@model DescriptionViewModel

<form asp-controller="Demo" asp-action="RegisterTextArea" method="post">
    <textarea asp-for="Description"></textarea>
    <button type="submit">Test</button>
</form>

다음 HTML이 생성됩니다.

<form method="post" action="/Demo/RegisterTextArea">
  <textarea data-val="true"
   data-val-maxlength="The field Description must be a string or array type with a maximum length of &#x27;1024&#x27;."
   data-val-maxlength-max="1024"
   data-val-minlength="The field Description must be a string or array type with a minimum length of &#x27;5&#x27;."
   data-val-minlength-min="5"
   id="Description" name="Description">
  </textarea>
  <button type="submit">Test</button>
  <input name="__RequestVerificationToken" type="hidden" value="<removed for brevity>">
</form>

레이블 태그 도우미

  • 식 이름의 <레이블>요소에 레이블 캡션 및 for 특성을 생성합니다.

  • HTML 도우미 대안: Html.LabelFor

Label Tag Helper는 순수 HTML 레이블 요소에 비해 다음과 같은 이점을 제공합니다.

  • Display 특성으로부터 설명 레이블 값을 자동으로 가져옵니다. 의도한 표시 이름은 시간이 지나면 변경될 수 있고, Display 특성 및 레이블 태그 도우미의 조합은 사용되는 모든 곳에 Display를 적용합니다.

  • 소스 코드의 간단한 태그

  • 모델 속성을 사용하는 강력한 형식화.

샘플:

using System.ComponentModel.DataAnnotations;

namespace FormsTagHelper.ViewModels
{
    public class SimpleViewModel
    {
        [Required]
        [EmailAddress]
        [Display(Name = "Email Address")]
        public string Email { get; set; }
    }
}

@model SimpleViewModel

<form asp-controller="Demo" asp-action="RegisterLabel" method="post">
    <label asp-for="Email"></label>
    <input asp-for="Email" /> <br />
</form>

다음 HTML이 <label> 요소에 생성됩니다.

<label for="Email">Email Address</label>

레이블 태그 도우미는 "Email"이라는 for 특성 값을 생성했습니다. 이 값은 <input> 요소와 연결된 ID입니다. 태그 도우미는 일관된 idfor 요소를 제대로 연결할 수 있도록 생성합니다. 이 예제의 캡션은 Display 특성으로부터 제공됩니다. 모델에 Display 특성이 포함되지 않는 경우 캡션은 식의 속성 이름입니다. 기본 캡션을 재정의하려면 레이블 태그 내에 캡션을 추가하세요.

유효성 검사 태그 도우미

두 개의 유효성 검사 태그 도우미가 있습니다. Validation Message Tag Helper(모델의 단일 속성에 대한 유효성 검사 메시지 표시) 및 Validation Summary Tag Helper(유효성 검사 오류의 요약 표시)입니다. Input Tag Helper는 모델 클래스의 데이터 주석 특성에 따라 입력 요소에 HTML5 클라이언트 쪽 유효성 검사 특성을 추가합니다. 유효성 검사는 서버에서도 수행됩니다. 유효성 검사 태그 도우미는 유효성 검사 오류가 발생하는 경우 이러한 오류 메시지를 표시합니다.

유효성 검사 메시지 태그 도우미

  • HTML5data-valmsg-for="property" 특성을 범위 요소에 추가합니다. 그러면 지정된 모델 속성의 입력 필드에서 유효성 검사 오류 메시지를 표시합니다. 클라이언트 쪽 유효성 검사 오류가 발생하면 jQuery<span> 요소에서 오류 메시지를 표시합니다.

  • 유효성 검사도 서버에서 수행됩니다. 클라이언트는 JavaScript를 사용하지 않도록 설정할 수 있고 일부 유효성 검사는 서버 쪽에서만 수행될 수 있습니다.

  • HTML 도우미 대안: Html.ValidationMessageFor

HTML Validation Message Tag Helper범위 요소의 asp-validation-for 특성과 함께 사용됩니다.

<span asp-validation-for="Email"></span>

유효성 검사 메시지 태그 도우미는 다음 HTML을 생성합니다.

<span class="field-validation-valid"
  data-valmsg-for="Email"
  data-valmsg-replace="true"></span>

일반적으로 동일한 속성에서 Input 태그 도우미 이후에 Validation Message Tag Helper를 사용합니다. 이렇게 하면 오류가 발생하는 입력 주변에서 유효성 검사 오류 메시지가 표시됩니다.

참고 항목

클라이언트 쪽 유효성 검사 대신 올바른 JavaScript 및 jQuery 스크립트 참조를 사용하는 보기가 있어야 합니다. 자세한 내용은 모델 유효성 검사를 참조하세요.

서버 쪽 유효성 검사 오류가 발생하는 경우(예: 사용자 지정 서버 쪽 유효성 검사 또는 클라이언트 쪽 유효성 검사를 사용하지 않는 경우) MVC는 해당 오류 메시지를 <span> 요소의 본문으로 배치합니다.

<span class="field-validation-error" data-valmsg-for="Email"
            data-valmsg-replace="true">
   The Email Address field is required.
</span>

유효성 검사 요약 태그 도우미

  • asp-validation-summary 특성이 있는 <div> 요소를 대상으로 지정합니다.

  • HTML 도우미 대안: @Html.ValidationSummary

Validation Summary Tag Helper는 유효성 검사 메시지의 요약 정보를 표시하는 데 사용됩니다. asp-validation-summary 특성 값은 다음 중 하나일 수 있습니다.

asp-validation-summary 표시되는 유효성 검사 메시지
All 속성 및 모델 수준
ModelOnly 모델
None 없음

예제

다음 예제에서 데이터 모델에는 DataAnnotation 특성이 있습니다. 이 특성은 <input> 요소에 대한 유효성 검사 오류 메시지를 생성합니다. 유효성 검사 오류가 발생하는 경우 유효성 검사 태그 도우미는 다음 오류 메시지를 표시합니다.

using System.ComponentModel.DataAnnotations;

namespace FormsTagHelper.ViewModels
{
    public class RegisterViewModel
    {
        [Required]
        [EmailAddress]
        [Display(Name = "Email Address")]
        public string Email { get; set; }

        [Required]
        [DataType(DataType.Password)]
        public string Password { get; set; }
    }
}
@model RegisterViewModel

<form asp-controller="Demo" asp-action="RegisterValidation" method="post">
    <div asp-validation-summary="ModelOnly"></div>
    Email:  <input asp-for="Email" /> <br />
    <span asp-validation-for="Email"></span><br />
    Password: <input asp-for="Password" /><br />
    <span asp-validation-for="Password"></span><br />
    <button type="submit">Register</button>
</form>

생성된 HTML(모델은 유효한 경우):

<form action="/DemoReg/Register" method="post">
  Email:  <input name="Email" id="Email" type="email" value=""
   data-val-required="The Email field is required."
   data-val-email="The Email field is not a valid email address."
   data-val="true"><br>
  <span class="field-validation-valid" data-valmsg-replace="true"
   data-valmsg-for="Email"></span><br>
  Password: <input name="Password" id="Password" type="password"
   data-val-required="The Password field is required." data-val="true"><br>
  <span class="field-validation-valid" data-valmsg-replace="true"
   data-valmsg-for="Password"></span><br>
  <button type="submit">Register</button>
  <input name="__RequestVerificationToken" type="hidden" value="<removed for brevity>">
</form>

선택 태그 도우미

  • 모델의 속성에 대한 선택 및 관련된 옵션 요소를 생성합니다.

  • HTML 도우미 대안 Html.DropDownListForHtml.ListBoxFor가 있습니다.

Select Tag Helperasp-forselect 요소의 모델 속성 이름을 지정하고 asp-items옵션 요소를 지정합니다. 예시:

<select asp-for="Country" asp-items="Model.Countries"></select> 

샘플:

using Microsoft.AspNetCore.Mvc.Rendering;
using System.Collections.Generic;

namespace FormsTagHelper.ViewModels
{
    public class CountryViewModel
    {
        public string Country { get; set; }

        public List<SelectListItem> Countries { get; } = new List<SelectListItem>
        {
            new SelectListItem { Value = "MX", Text = "Mexico" },
            new SelectListItem { Value = "CA", Text = "Canada" },
            new SelectListItem { Value = "US", Text = "USA"  },
        };
    }
}

Index 메서드는 CountryViewModel를 초기화하고, 선택한 국가를 설정하고, Index 보기에 전달합니다.

public IActionResult Index()
{
    var model = new CountryViewModel();
    model.Country = "CA";
    return View(model);
}

HTTP POST Index 메서드는 선택 항목을 표시합니다.

[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Index(CountryViewModel model)
{
    if (ModelState.IsValid)
    {
        var msg = model.Country + " selected";
        return RedirectToAction("IndexSuccess", new { message = msg });
    }

    // If we got this far, something failed; redisplay form.
    return View(model);
}

Index 보기:

@model CountryViewModel

<form asp-controller="Home" asp-action="Index" method="post">
    <select asp-for="Country" asp-items="Model.Countries"></select> 
    <br /><button type="submit">Register</button>
</form>

다음 HTML을 생성합니다("CA"를 선택함).

<form method="post" action="/">
     <select id="Country" name="Country">
       <option value="MX">Mexico</option>
       <option selected="selected" value="CA">Canada</option>
       <option value="US">USA</option>
     </select>
       <br /><button type="submit">Register</button>
     <input name="__RequestVerificationToken" type="hidden" value="<removed for brevity>">
   </form>

참고 항목

선택 태그 도우미와 ViewBag 또는 ViewData를 함께 사용하지 않는 것이 좋습니다. 보기 모델은 일반적으로 더 강력하고 문제가 적은 방식으로 MVC 메타데이터를 제공합니다.

asp-for 특성 값은 특별한 경우이며 다른 태그 도우미 특성(예: asp-items)과 달리 Model 접두사를 필요로 하지 않습니다.

<select asp-for="Country" asp-items="Model.Countries"></select> 

열거형 바인딩

enum 속성과 함께 <select>를 사용하고 enum 값에서 SelectListItem 요소를 생성하는 것이 편리합니다.

샘플:

public class CountryEnumViewModel
{
    public CountryEnum EnumCountry { get; set; }
}
using System.ComponentModel.DataAnnotations;

namespace FormsTagHelper.ViewModels
{
    public enum CountryEnum
    {
        [Display(Name = "United Mexican States")]
        Mexico,
        [Display(Name = "United States of America")]
        USA,
        Canada,
        France,
        Germany,
        Spain
    }
}

GetEnumSelectList 메서드는 열거형에 대해 SelectList 개체를 생성합니다.

@model CountryEnumViewModel

<form asp-controller="Home" asp-action="IndexEnum" method="post">
    <select asp-for="EnumCountry" 
            asp-items="Html.GetEnumSelectList<CountryEnum>()">
    </select> 
    <br /><button type="submit">Register</button>
</form>

Display 특성으로 열거자 목록을 표시하여 보다 풍부한 UI를 사용할 수 있습니다.

using System.ComponentModel.DataAnnotations;

namespace FormsTagHelper.ViewModels
{
    public enum CountryEnum
    {
        [Display(Name = "United Mexican States")]
        Mexico,
        [Display(Name = "United States of America")]
        USA,
        Canada,
        France,
        Germany,
        Spain
    }
}

다음 HTML이 생성됩니다.

<form method="post" action="/Home/IndexEnum">
    <select data-val="true" data-val-required="The EnumCountry field is required."
            id="EnumCountry" name="EnumCountry">
        <option value="0">United Mexican States</option>
        <option value="1">United States of America</option>
        <option value="2">Canada</option>
        <option value="3">France</option>
        <option value="4">Germany</option>
        <option selected="selected" value="5">Spain</option>
    </select>
    <br /><button type="submit">Register</button>
    <input name="__RequestVerificationToken" type="hidden" value="<removed for brevity>">
</form>

옵션 그룹

보기 모델에 하나 이상의 SelectListGroup 개체가 포함되는 경우 HTML <optgroup> 요소가 생성됩니다.

CountryViewModelGroupSelectListItem 요소를 "북아메리카" 및 "유럽" 그룹으로 그룹화합니다.

public class CountryViewModelGroup
{
    public CountryViewModelGroup()
    {
        var NorthAmericaGroup = new SelectListGroup { Name = "North America" };
        var EuropeGroup = new SelectListGroup { Name = "Europe" };

        Countries = new List<SelectListItem>
        {
            new SelectListItem
            {
                Value = "MEX",
                Text = "Mexico",
                Group = NorthAmericaGroup
            },
            new SelectListItem
            {
                Value = "CAN",
                Text = "Canada",
                Group = NorthAmericaGroup
            },
            new SelectListItem
            {
                Value = "US",
                Text = "USA",
                Group = NorthAmericaGroup
            },
            new SelectListItem
            {
                Value = "FR",
                Text = "France",
                Group = EuropeGroup
            },
            new SelectListItem
            {
                Value = "ES",
                Text = "Spain",
                Group = EuropeGroup
            },
            new SelectListItem
            {
                Value = "DE",
                Text = "Germany",
                Group = EuropeGroup
            }
      };
    }

    public string Country { get; set; }

    public List<SelectListItem> Countries { get; }

두 그룹은 다음과 같이 보여집니다.

option group example

생성되는 HTML은 다음과 같습니다.

 <form method="post" action="/Home/IndexGroup">
      <select id="Country" name="Country">
          <optgroup label="North America">
              <option value="MEX">Mexico</option>
              <option value="CAN">Canada</option>
              <option value="US">USA</option>
          </optgroup>
          <optgroup label="Europe">
              <option value="FR">France</option>
              <option value="ES">Spain</option>
              <option value="DE">Germany</option>
          </optgroup>
      </select>
      <br /><button type="submit">Register</button>
      <input name="__RequestVerificationToken" type="hidden" value="<removed for brevity>">
 </form>

다중 선택

asp-for 특성에 지정된 속성이 IEnumerable인 경우 태그 선택 도우미는 multiple = "multiple" 특성을 자동으로 생성합니다. 예를 들어, 다음과 같은 모델을 고려해보세요.

using Microsoft.AspNetCore.Mvc.Rendering;
using System.Collections.Generic;

namespace FormsTagHelper.ViewModels
{
    public class CountryViewModelIEnumerable
    {
        public IEnumerable<string> CountryCodes { get; set; }

        public List<SelectListItem> Countries { get; } = new List<SelectListItem>
        {
            new SelectListItem { Value = "MX", Text = "Mexico" },
            new SelectListItem { Value = "CA", Text = "Canada" },
            new SelectListItem { Value = "US", Text = "USA"    },
            new SelectListItem { Value = "FR", Text = "France" },
            new SelectListItem { Value = "ES", Text = "Spain"  },
            new SelectListItem { Value = "DE", Text = "Germany"}
         };
    }
}

다음 보기를 사용할 경우:

@model CountryViewModelIEnumerable

<form asp-controller="Home" asp-action="IndexMultiSelect" method="post">
    <select asp-for="CountryCodes" asp-items="Model.Countries"></select> 
    <br /><button type="submit">Register</button>
</form>

다음과 같은 HTML을 생성합니다.

<form method="post" action="/Home/IndexMultiSelect">
    <select id="CountryCodes"
    multiple="multiple"
    name="CountryCodes"><option value="MX">Mexico</option>
<option value="CA">Canada</option>
<option value="US">USA</option>
<option value="FR">France</option>
<option value="ES">Spain</option>
<option value="DE">Germany</option>
</select>
    <br /><button type="submit">Register</button>
  <input name="__RequestVerificationToken" type="hidden" value="<removed for brevity>">
</form>

선택 영역 없음

여러 페이지에서 "지정 안 됨" 옵션을 사용하는 경우 템플릿을 만들어서 HTML의 반복을 제거할 수 있습니다.

@model CountryViewModel

<form asp-controller="Home" asp-action="IndexEmpty" method="post">
    @Html.EditorForModel()
    <br /><button type="submit">Register</button>
</form>

Views/Shared/EditorTemplates/CountryViewModel.cshtml 템플릿:

@model CountryViewModel

<select asp-for="Country" asp-items="Model.Countries">
    <option value="">--none--</option>
</select>

HTML <옵션> 요소를 추가하는 것은 선택 안 됨 사례로 제한되지 않습니다. 예를 들어 다음과 같은 보기 및 작업 메서드는 위의 코드와 유사한 HTML을 생성합니다.

public IActionResult IndexNone()
{
    var model = new CountryViewModel();
    model.Countries.Insert(0, new SelectListItem("<none>", ""));
    return View(model);
}
@model CountryViewModel

<form asp-controller="Home" asp-action="IndexEmpty" method="post">
    <select asp-for="Country">
        <option value="">&lt;none&gt;</option>
        <option value="MX">Mexico</option>
        <option value="CA">Canada</option>
        <option value="US">USA</option>
    </select> 
    <br /><button type="submit">Register</button>
</form>

현재 Country 값에 따라 올바른 <option> 요소가 선택됩니다(selected="selected" 특성 포함).

public IActionResult IndexOption(int id)
{
    var model = new CountryViewModel();
    model.Country = "CA";
    return View(model);
}
 <form method="post" action="/Home/IndexEmpty">
      <select id="Country" name="Country">
          <option value="">&lt;none&gt;</option>
          <option value="MX">Mexico</option>
          <option value="CA" selected="selected">Canada</option>
          <option value="US">USA</option>
      </select>
      <br /><button type="submit">Register</button>
   <input name="__RequestVerificationToken" type="hidden" value="<removed for brevity>">
 </form>

추가 리소스