Pomocnicy tagów w formularzach w programie ASP.NET Core

Przez Rick Anderson, N. Taylor Mullen, Dave Paquette i Jerrie Pelser

Ten dokument przedstawia pracę z formularzami i elementami HTML często używanymi w formularzu. Element Formularz HTML udostępnia podstawowy mechanizm aplikacji internetowych używany do publikowania danych z powrotem na serwerze. W większości tego dokumentu opisano pomocników tagów i sposób, w jaki mogą one pomóc w wydajnym tworzeniu niezawodnych formularzy HTML. Przed przeczytaniem tego dokumentu zalecamy przeczytanie tematu Introduction to Tag Helpers (Wprowadzenie do pomocników tagów ).

W wielu przypadkach pomocnicy HTML zapewniają alternatywne podejście do określonego pomocnika tagów, ale ważne jest, aby rozpoznać, że pomocnicy tagów nie zastępują pomocników HTML i nie ma pomocnika tagów dla każdego pomocnika HTML. Jeśli istnieje alternatywa pomocnika HTML, jest ona wymieniona.

Pomocnik tagu formularza

Pomocnik tagu formularza:

  • Generuje wartość atrybutu FORMULARZ>action HTML <dla akcji kontrolera MVC lub nazwanej trasy

  • Generuje ukryty token weryfikacji żądania, aby zapobiec fałszerzowaniu żądania między witrynami (w przypadku użycia z atrybutem [ValidateAntiForgeryToken] w metodzie akcji Post HTTP)

  • asp-route-<Parameter Name> Udostępnia atrybut , w którym <Parameter Name> jest dodawany do wartości trasy. Parametry routeValues do Html.BeginForm i Html.BeginRouteForm zapewniają podobne funkcje.

  • Ma alternatywę Html.BeginForm pomocnika HTML i Html.BeginRouteForm

Przykład:

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

Powyższy pomocnik tagu formularza generuje następujący kod HTML:

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

Środowisko uruchomieniowe MVC generuje wartość atrybutu action z atrybutów Pomocnika tagów formularzy asp-controller i asp-action. Pomocnik tagu formularza generuje również ukryty token weryfikacji żądania, aby zapobiec fałszerzowaniu żądań między witrynami (w przypadku użycia z atrybutem [ValidateAntiForgeryToken] w metodzie akcji Post HTTP). Ochrona czystego formularza HTML przed fałszertwem żądania obejmującego wiele witryn jest trudna. Pomocnik tagów formularzy udostępnia tę usługę.

Używanie nazwanej trasy

Atrybut asp-route Pomocnika tagów może również generować znaczniki dla atrybutu HTML action . Aplikacja z trasą o nazwie register może używać następującego znacznika dla strony rejestracji:

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

Wiele widoków w folderze Views/Account (generowanych podczas tworzenia nowej aplikacji internetowej z indywidualnymi kontami użytkowników) zawiera atrybut asp-route-returnurl :

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

Uwaga

Wbudowane szablony są wypełniane automatycznie tylko podczas próby uzyskania dostępu do autoryzowanego zasobu, returnUrl ale nie są uwierzytelniane ani autoryzowane. Podczas próby nieautoryzowanego dostępu oprogramowanie pośredniczące zabezpieczeń przekierowuje Cię do strony logowania z zestawem returnUrl .

Pomocnik tagu akcji formularza

Pomocnik tagu formaction akcji formularza generuje atrybut wygenerowany <button ...> lub <input type="image" ...> tag. Atrybut formaction określa, gdzie formularz przesyła dane. Wiąże się z elementami wejściowymi> elementów typu image i< przycisków>.< Pomocnik tagu akcji formularza umożliwia użycie kilku atrybutów AnchorTagHelperasp- w celu kontrolowania, jaki formaction link jest generowany dla odpowiedniego elementu.

Obsługiwane atrybuty AnchorTagHelper do kontrolowania wartości :formaction

Atrybut opis
asp-controller Nazwa kontrolera.
asp-action Nazwa metody akcji.
asp-area Nazwa obszaru.
asp-page Nazwa Razor strony.
program obsługi asp-page-handler Nazwa Razor programu obsługi strony.
asp-route Nazwa trasy.
asp-route-{value} Pojedyncza wartość trasy adresu URL. Na przykład asp-route-id="1234".
asp-all-route-data Wszystkie wartości tras.
asp-fragment Fragment adresu URL.

Przykład przesyłania do kontrolera

Poniższy znacznik przesyła formularz do Index akcji HomeController po wybraniu danych wejściowych lub przycisków:

<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>

Poprzedni znacznik generuje następujący kod HTML:

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

Przykład przesyłania do strony

Następujący znacznik przesyła formularz do AboutRazor strony:

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

Poprzedni znacznik generuje następujący kod HTML:

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

Przykład przesyłania do trasy

Rozważmy /Home/Test punkt końcowy:

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

Poniższy znacznik przesyła formularz do punktu końcowego /Home/Test .

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

Poprzedni znacznik generuje następujący kod HTML:

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

Pomocnik tagu wejściowego

Pomocnik tagów wejściowych wiąże element wejściowy> HTML <z wyrażeniem modelu w widoku razor.

Składnia:

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

Pomocnik tagów wejściowych:

  • id Generuje atrybuty i name HTML dla nazwy wyrażenia określonego w atrybucieasp-for. asp-for="Property1.Property2" jest równoważne z m => m.Property1.Property2. Nazwa wyrażenia jest używana dla wartości atrybutu asp-for . Aby uzyskać dodatkowe informacje, zobacz sekcję Nazwy wyrażeń.

  • Ustawia wartość atrybutu HTML type na podstawie typu modelu i atrybutów adnotacji danych zastosowanych do właściwości modelu

  • Nie zastąpi wartości atrybutu HTML type po określeniu

  • Generuje atrybuty weryfikacji HTML5 na podstawie atrybutów adnotacji danych zastosowanych do właściwości modelu

  • Ma funkcję pomocnika HTML nakładających się na jednostki Html.TextBoxFor i Html.EditorFor. Aby uzyskać szczegółowe informacje, zobacz sekcję Pomocnik języka HTML dla pomocnika tagów wejściowych.

  • Zapewnia silne wpisywanie. Jeśli nazwa właściwości ulegnie zmianie i nie zaktualizujesz pomocnika tagów, zostanie wyświetlony błąd podobny do następującego:

    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?)
    

Pomocnik Input tagów ustawia atrybut HTML type na podstawie typu .NET. W poniższej tabeli wymieniono niektóre typowe typy platformy .NET i wygenerowany typ HTML (nie każdy typ platformy .NET jest wymieniony).

Typ platformy .NET Typ danych wejściowych
Bool type="pole wyboru"
Ciąg type="text"
Data/godzina type="datetime-local"
Byte type="number"
Int type="number"
Pojedynczy, podwójny type="number"

W poniższej tabeli przedstawiono niektóre typowe atrybuty adnotacji danych, które pomocnik tagów wejściowych mapuje na określone typy danych wejściowych (nie każdy atrybut weryfikacji jest wymieniony):

Atrybut Typ danych wejściowych
[Adres e-mail] type="email"
[Adres URL] type="url"
[HiddenInput] type="hidden"
[Telefon] type="tel"
[DataType(DataType.Password)] type="password"
[DataType(DataType.Date)] type="date"
[DataType(DataType.Time)] type="time"

Przykład:

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>

Powyższy kod generuje następujący kod 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>

Adnotacje danych zastosowane do Email właściwości i Password generują metadane w modelu. Pomocnik tagów wejściowych używa metadanych modelu i generuje atrybuty HTML5data-val-* (zobacz Walidacja modelu). Te atrybuty opisują moduły sprawdzania poprawności do dołączania do pól wejściowych. Zapewnia to nieprawdziwą walidację kodu HTML5 i jQuery . Atrybuty niestrudne mają format data-val-rule="Error Message", gdzie reguła jest nazwą reguły walidacji (np data-val-required. , data-val-email, data-val-maxlengthitp.) Jeśli w atrybucie zostanie podany komunikat o błędzie, zostanie wyświetlony jako wartość atrybutu data-val-rule . Istnieją również atrybuty formularza data-val-ruleName-argumentName="argumentValue" , które zawierają dodatkowe szczegóły dotyczące reguły, na przykład data-val-maxlength-max="1024" .

W przypadku powiązania wielu input kontrolek z tą samą właściwością wygenerowane kontrolki współdzielą ten sam idelement , co sprawia, że wygenerowany znacznik jest nieprawidłowy. Aby zapobiec duplikatom, określ id atrybut dla każdej kontrolki jawnie.

Pole wyboru ukrytego renderowania danych wejściowych

Pola wyboru w kodzie HTML5 nie przesyłają wartości, gdy nie są zaznaczone. Aby włączyć wysyłanie wartości domyślnej dla niezaznaczonego pola wyboru, pomocnik tagu wejściowego generuje dodatkowe ukryte dane wejściowe dla pól wyboru.

Rozważmy na przykład następujący Razor znacznik, który używa pomocnika tagów wejściowych dla właściwości IsCheckedmodelu logicznego:

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

Razor Powyższy znacznik generuje znaczniki HTML podobne do następujących:

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

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

Powyższy znacznik HTML przedstawia dodatkowe ukryte dane wejściowe o nazwie IsChecked i wartości false. Domyślnie ukryte dane wejściowe są renderowane na końcu formularza. Po przesłaniu formularza:

  • IsChecked Jeśli pole wyboru jest zaznaczone, zarówno, jak true i false są przesyłane jako wartości.
  • IsChecked Jeśli dane wejściowe pola wyboru są niezaznaczone, zostanie przesłana tylko ukryta wartość false wejściowa.

Proces powiązania modelu ASP.NET Core odczytuje tylko pierwszą wartość podczas tworzenia powiązania z wartością bool , co powoduje true zaznaczenie pól wyboru zaznaczonego i false niezaznaczonego pola wyboru.

Aby skonfigurować zachowanie ukrytego renderowania danych wejściowych, ustaw CheckBoxHiddenInputRenderMode właściwość na .MvcViewOptions.HtmlHelperOptions Przykład:

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

Powyższy kod wyłącza ukryte renderowanie danych wejściowych dla pól wyboru, ustawiając wartość CheckBoxHiddenInputRenderMode .CheckBoxHiddenInputRenderMode.None Aby zapoznać się ze wszystkimi dostępnymi trybami renderowania, zobacz wyliczenie CheckBoxHiddenInputRenderMode .

Pomocnik HTML alternatywy dla pomocnika tagów wejściowych

Html.TextBoxHtml.Editor, Html.TextBoxFori Html.EditorFor mają nakładające się funkcje za pomocą pomocnika tagów wejściowych. Pomocnik tagów wejściowych type automatycznie ustawi atrybut i Html.TextBoxHtml.TextBoxFor nie. Html.Editor i Html.EditorFor obsługują kolekcje, złożone obiekty i szablony; pomocnik tagów wejściowych nie. Pomocnik Html.EditorFor tagów wejściowych i Html.TextBoxFor są silnie typizowane (używają wyrażeń lambda) Html.TextBox i Html.Editor nie są (używają nazw wyrażeń).

Atrybuty HtmlAttributes

@Html.Editor() i @Html.EditorFor() użyj specjalnego ViewDataDictionary wpisu o nazwie htmlAttributes podczas wykonywania szablonów domyślnych. To zachowanie jest opcjonalnie rozszerzone przy użyciu additionalViewData parametrów. Klucz "htmlAttributes" jest bez uwzględniania wielkości liter. Klucz "htmlAttributes" jest obsługiwany podobnie do obiektu przekazanego htmlAttributes do pomocników wejściowych, takich jak @Html.TextBox().

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

Nazwy wyrażeń

Wartość asp-for atrybutu to i ModelExpression prawa strona wyrażenia lambda. W związku z tym staje m => m.Property1 się w wygenerowanym kodzie, asp-for="Property1" dlatego nie trzeba prefiksować za pomocą Modelpolecenia . Możesz użyć znaku "@", aby uruchomić wyrażenie wbudowane i przenieść przed znakiem m.:

@{
  var joe = "Joe";
}

<input asp-for="@joe">

Generuje następujące elementy:

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

W przypadku właściwości asp-for="CollectionProperty[23].Member" kolekcji generuje taką samą nazwę, jak asp-for="CollectionProperty[i].Member" w przypadku, gdy i ma wartość 23.

Gdy ASP.NET Core MVC oblicza wartość ModelExpression, sprawdza kilka źródeł, w tym ModelState. Rozważmy .<input type="text" asp-for="Name"> Atrybut obliczeniowy value jest pierwszą wartością inną niż null:

  • ModelState wpis z kluczem "Name".
  • Wynik wyrażenia Model.Name.

Możesz również przejść do właściwości podrzędnych przy użyciu ścieżki właściwości modelu widoku. Rozważ bardziej złożoną klasę modelu zawierającą właściwość podrzędną 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; }
}

W widoku wiążemy się z elementem 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>

Następujący kod HTML jest generowany dla elementu Address.AddressLine1:

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

Nazwy wyrażeń i kolekcje

Przykładowy model zawierający tablicę Colors:

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

    public int Age { get; set; }
}

Metoda akcji:

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

Razor Poniżej przedstawiono sposób uzyskiwania dostępu do określonego Color elementu:

@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>

Szablon Views/Shared/EditorTemplates/String.cshtml :

@model string

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

Przykład przy użyciu polecenia List<T>:

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

    public bool IsDone { get; set; }
}

Razor Poniżej przedstawiono sposób iteracji kolekcji:

@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>

Szablon 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>
*@

foreachnależy użyć, jeśli jest to możliwe, gdy wartość będzie używana w kontekście lub Html.DisplayFor równoważnymasp-for. Ogólnie rzecz biorąc, for jest lepszy niż foreach (jeśli scenariusz go umożliwia), ponieważ nie musi przydzielić modułu wyliczającego, jednak ocena indeksatora w wyrażeniu LINQ może być kosztowna i powinna być zminimalizowana.

 

Uwaga

W powyższym przykładowym kodzie z komentarzem pokazano, jak zastąpić wyrażenie lambda operatorem @ w celu uzyskania dostępu do każdego ToDoItem z nich na liście.

Pomocnik tagu obszaru tekstowego

Textarea Tag Helper Pomocnik tagu jest podobny do pomocnika tagów wejściowych.

  • id Generuje atrybuty i name oraz atrybuty weryfikacji danych z modelu dla elementu obszaru tekstowego<>.

  • Zapewnia silne wpisywanie.

  • Alternatywa pomocnika HTML: Html.TextAreaFor

Przykład:

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>

Generowany jest następujący kod 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>

Pomocnik tagów etykiet

  • Generuje etykietę podpis i for atrybut elementu <label> dla nazwy wyrażenia

  • Alternatywa pomocnika HTML: Html.LabelFor.

Zapewnia Label Tag Helper następujące korzyści wynikające z czystego elementu etykiety HTML:

  • Automatycznie uzyskujesz wartość etykiety opisowej z atrybutu Display . Docelowa nazwa wyświetlana może ulec zmianie w czasie, a kombinacja atrybutu i pomocnika tagów Display etykiet będzie stosować Display wszędzie tam, gdzie jest używana.

  • Mniej znaczników w kodzie źródłowym

  • Silne wpisywanie za pomocą właściwości modelu.

Przykład:

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>

Dla elementu jest generowany <label> następujący kod HTML:

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

Pomocnik tagu etykiety wygenerował for wartość atrybutu "Email", czyli identyfikator skojarzony z elementem <input> . Pomocnicy tagów generują spójne id i for elementy, aby można je było poprawnie skojarzyć. Podpis w tym przykładzie pochodzi z atrybutu Display . Jeśli model nie zawiera atrybutuDisplay, podpis będzie nazwą właściwości wyrażenia. Aby zastąpić podpis domyślną, dodaj podpis wewnątrz tagu etykiety.

Pomocnicy tagów walidacji

Istnieją dwie pomocniki tagów weryfikacji. Element Validation Message Tag Helper (który wyświetla komunikat weryfikacji dla pojedynczej właściwości modelu) i Validation Summary Tag Helper (który wyświetla podsumowanie błędów walidacji). Element Input Tag Helper dodaje atrybuty weryfikacji po stronie klienta HTML5 do elementów wejściowych na podstawie atrybutów adnotacji danych w klasach modelu. Walidacja jest również wykonywana na serwerze. Pomocnik tagu weryfikacji wyświetla te komunikaty o błędach po wystąpieniu błędu walidacji.

Pomocnik tagu komunikatu sprawdzania poprawności

  • Dodaje atrybut HTML5data-valmsg-for="property" do elementu span, który dołącza komunikaty o błędach walidacji w polu wejściowym określonej właściwości modelu. Po wystąpieniu błędu weryfikacji po stronie klienta zapytanie jQuery wyświetla komunikat o błędzie w elemecie <span> .

  • Walidacja odbywa się również na serwerze. Klienci mogą mieć wyłączony język JavaScript, a niektóre weryfikacje można wykonać tylko po stronie serwera.

  • Alternatywa pomocnika HTML: Html.ValidationMessageFor

Parametr Validation Message Tag Helper jest używany z atrybutem asp-validation-for w elemecie span HTML.

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

Pomocnik tagu komunikatu weryfikacji wygeneruje następujący kod HTML:

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

Dla tej samej właściwości zwykle używasz Validation Message Tag Helper pomocnika tagów Input . Spowoduje to wyświetlenie wszystkich komunikatów o błędach walidacji w pobliżu danych wejściowych, które spowodowały błąd.

Uwaga

Aby przeprowadzić walidację po stronie klienta, musisz mieć widok z poprawnymi odwołaniami do skryptów JavaScript i jQuery . Aby uzyskać więcej informacji, zobacz Walidacja modelu.

W przypadku wystąpienia błędu weryfikacji po stronie serwera (na przykład w przypadku wyłączenia niestandardowej weryfikacji po stronie serwera lub weryfikacji po stronie klienta) mvC umieszcza ten komunikat o błędzie jako treść <span> elementu.

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

Pomocnik tagu podsumowania walidacji

  • Elementy docelowe <div> z atrybutem asp-validation-summary

  • Alternatywa pomocnika HTML: @Html.ValidationSummary

Element Validation Summary Tag Helper służy do wyświetlania podsumowania komunikatów weryfikacji. Wartość atrybutu asp-validation-summary może być dowolna z następujących:

asp-validation-summary Wyświetlane komunikaty sprawdzania poprawności
All Poziom właściwości i modelu
ModelOnly Model
None None

Przykład

W poniższym przykładzie model danych ma DataAnnotation atrybuty, które generują komunikaty o błędach walidacji w elemecie <input> . Po wystąpieniu błędu sprawdzania poprawności pomocnik tagu weryfikacji wyświetla komunikat o błędzie:

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>

Wygenerowany kod HTML (gdy model jest prawidłowy):

<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>

Pomocnik wybierania tagów

Element Select Tag Helperasp-for określa nazwę właściwości modelu dla elementu select i asp-items określa elementy opcji . Przykład:

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

Przykład:

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"  },
        };
    }
}

Metoda Index inicjuje CountryViewModelelement , ustawia wybrany kraj i przekazuje go do Index widoku.

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

Metoda HTTP POST Index wyświetla wybór:

[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);
}

Widok 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>

Spowoduje to wygenerowanie następującego kodu HTML (przy użyciu wybranego przycisku "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>

Uwaga

Nie zalecamy używania lub ViewData używania ViewBag pomocnika Wybierz tag. Model widoku jest bardziej niezawodny w dostarczaniu metadanych MVC i ogólnie mniej problematycznych.

Wartość asp-for atrybutu jest specjalnym przypadkiem i nie wymaga prefiksu Model , inne atrybuty pomocnika tagu (takie jak asp-items)

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

Powiązanie wyliczenia

Często wygodne jest używanie <select> z właściwością enum i generowanie SelectListItem elementów na podstawie enum wartości.

Przykład:

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
    }
}

Metoda GetEnumSelectList generuje SelectList obiekt dla wyliczenia.

@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>

Możesz oznaczyć listę modułów wyliczania za pomocą atrybutu Display , aby uzyskać bogatszy interfejs użytkownika:

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
    }
}

Generowany jest następujący kod 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>

Grupa opcji

Element optgroup> HTML <jest generowany, gdy model widoku zawiera co najmniej jeden SelectListGroup obiekt.

Grupuje CountryViewModelGroupSelectListItem elementy w grupy "Ameryka Północna" i "Europa":

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; }

Poniżej przedstawiono dwie grupy:

option group example

Wygenerowany kod 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>

Wybór wielokrotny

Pomocnik wybierania tagów automatycznie wygeneruje wielokrotność = "wiele" atrybutów, jeśli właściwość określona w atrybucie asp-for to IEnumerable. Na przykład biorąc pod uwagę następujący model:

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"}
         };
    }
}

W następującym widoku:

@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>

Generuje następujący kod 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>

Brak zaznaczenia

Jeśli znajdziesz się przy użyciu opcji "nieokreślonej" na wielu stronach, możesz utworzyć szablon, aby wyeliminować powtarzanie kodu HTML:

@model CountryViewModel

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

Szablon Views/Shared/EditorTemplates/CountryViewModel.cshtml :

@model CountryViewModel

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

Dodawanie elementów opcji> HTML <nie jest ograniczone do bez wielkości liter zaznaczenia. Na przykład poniższy widok i metoda akcji wygenerują kod HTML podobny do powyższego:

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>

<option> Prawidłowy element zostanie wybrany ( zawiera selected="selected" atrybut) w zależności od bieżącej Country wartości.

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>

Dodatkowe zasoby