Delen via


Deel 9: validatie toevoegen aan een ASP.NET Core MVC-app

Opmerking

Dit is niet de nieuwste versie van dit artikel. Zie de .NET 10-versie van dit artikel voor de huidige release.

Waarschuwing

Deze versie van ASP.NET Core wordt niet meer ondersteund. Zie het .NET- en .NET Core-ondersteuningsbeleid voor meer informatie. Zie de .NET 9-versie van dit artikel voor de huidige release.

Door Rick Anderson

In deze sectie:

  • Validatielogica wordt toegevoegd aan het Movie model.
  • U zorgt ervoor dat de validatieregels worden afgedwongen wanneer een gebruiker een film maakt of bewerkt.

Alles droog houden

Een van de ontwerpprincipes van MVC is DRY ('Don't Repeat Yourself'). ASP.NET Core MVC moedigt u aan om slechts één keer functionaliteit of gedrag op te geven en deze vervolgens overal in een app te laten zien. Dit vermindert de hoeveelheid code die u moet schrijven en maakt de code die u doet minder foutgevoelig, gemakkelijker te testen en gemakkelijker te onderhouden.

De validatieondersteuning van MVC en Entity Framework Core is een goed voorbeeld van het DRY-principe in actie. U kunt declaratief validatieregels opgeven op één plaats (in de modelklasse) en de regels worden overal in de app afgedwongen.

Validatie in .NET 10

In .NET 10 zijn de geïntegreerde validatie-API's verplaatst naar het Microsoft.Extensions.Validation NuGet-pakket. Deze wijziging maakt de validatie-API's beschikbaar buiten ASP.NET Core HTTP-scenario's.

Om de API's te gebruiken Microsoft.Extensions.Validation :

  • Voeg de volgende pakketreferentie toe:

    <PackageReference Include="Microsoft.Extensions.Validation" Version="10.0.0" />
    

    De functionaliteit blijft hetzelfde, maar vereist nu een expliciete pakketreferentie.

  • Validatieservices registreren met afhankelijkheidsinjectie:

    builder.Services.AddValidation();
    

De eerder bewerkte gegevens verwijderen

In de volgende stap worden validatieregels toegevoegd die null-waarden niet toestaan. Voer de app uit, navigeer naar /Movies/Index, verwijder alle vermelde films en stop de app. De app gebruikt de seed-gegevens de volgende keer dat deze wordt uitgevoerd.

Validatieregels toevoegen aan het filmmodel

De naamruimte DataAnnotations biedt een set ingebouwde validatiekenmerken die declaratief worden toegepast op een klasse of eigenschap. DataAnnotations bevat ook opmaakkenmerken zoals DataType die helpen bij het opmaken en bieden geen validatie.

Werk de Movie klasse bij om te profiteren van de ingebouwde validatiekenmerkenRequired, StringLengthRegularExpressionRangeen het DataType opmaakkenmerk.

using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace MvcMovie.Models;

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

    [StringLength(60, MinimumLength = 3)]
    [Required]
    public string? Title { get; set; }

    [Display(Name = "Release Date")]
    [DataType(DataType.Date)]
    public DateTime ReleaseDate { get; set; }

    [Range(1, 100)]
    [DataType(DataType.Currency)]
    [Column(TypeName = "decimal(18, 2)")]
    public decimal Price { get; set; }    

    [RegularExpression(@"^[A-Z]+[a-zA-Z\s]*$")]
    [Required]
    [StringLength(30)]
    public string? Genre { get; set; }

    [RegularExpression(@"^[A-Z]+[a-zA-Z0-9""'\s-]*$")]
    [StringLength(5)]
    [Required]
    public string? Rating { get; set; }
}

De validatiekenmerken geven het gedrag op dat u wilt afdwingen voor de modeleigenschappen waarop ze worden toegepast:

  • De Required en MinimumLength kenmerken geven aan dat een eigenschap een waarde moet hebben, maar niets voorkomt dat een gebruiker witruimte invoert om aan deze validatie te voldoen.

  • Het kenmerk RegularExpression wordt gebruikt om te beperken welke tekens kunnen worden ingevoerd. In de voorgaande code, "Genre":

    • Mag alleen letters gebruiken.
    • De eerste letter moet een hoofdletter zijn. Spaties zijn toegestaan, maar getallen en speciale tekens zijn niet toegestaan.
  • De RegularExpression "Beoordeling":

    • Vereist dat het eerste teken een hoofdletter is.
    • Hiermee worden speciale tekens en nummers toegestaan in achtereenvolgende spaties. "PG-13" is geldig voor een beoordeling, maar is niet geschikt voor een genre.
  • Het Range kenmerk beperkt een waarde tot binnen een opgegeven bereik.

  • StringLength Met het kenmerk kunt u de maximale lengte van een tekenreekseigenschap en eventueel de minimale lengte instellen.

  • Waardetypen (zoals decimal, int, float, ) DateTimezijn inherent vereist en hebben het [Required] kenmerk niet nodig.

Door validatieregels automatisch af te dwingen door ASP.NET Core, kunt u uw app robuuster maken. Het zorgt er ook voor dat u niet kunt vergeten om iets te valideren en per ongeluk slechte gegevens in de database toe te staan.

Validatiefout Gebruikersinterface

Voer de app uit en navigeer naar de Films-controller.

Selecteer de koppeling Nieuwe maken om een nieuwe film toe te voegen. Vul het formulier in met een aantal ongeldige waarden. Zodra de jQuery-clientvalidatie de fout detecteert, wordt er een foutbericht weergegeven.

Formulier voor filmweergave met meerdere validatiefouten aan de clientzijde van jQuery

Opmerking

Mogelijk kunt u geen decimale komma's invoeren in decimale velden. Als u ondersteuning wilt bieden voor jQuery-validatie voor niet-Engelstalige landinstellingen die een komma (",") gebruiken voor een decimaalteken en niet-US-English datumnotaties, moet u stappen uitvoeren om uw app te globaliseren. Zie deze GitHub-opmerking 4076 voor instructies over het toevoegen van komma's.

U ziet hoe het formulier automatisch een geschikt validatiefoutbericht heeft weergegeven in elk veld met een ongeldige waarde. De fouten worden afgedwongen aan de clientzijde (met behulp van JavaScript en jQuery) en aan de serverzijde (voor het geval een gebruiker JavaScript heeft uitgeschakeld).

Een belangrijk voordeel is dat u geen enkele regel code in de MoviesController klasse of in de Create.cshtml weergave hoeft te wijzigen om deze validatiegebruikersinterface in te schakelen. De controller en weergaven die u eerder in deze zelfstudie hebt gemaakt, hebben automatisch de validatieregels opgehaald die u hebt opgegeven met behulp van validatiekenmerken voor de eigenschappen van de Movie modelklasse. Testvalidatie met behulp van de Edit actiemethode en dezelfde validatie wordt toegepast.

De formuliergegevens worden pas naar de server verzonden als er geen validatiefouten aan de clientzijde zijn. U kunt dit controleren door een onderbrekingspunt in de HTTP Post methode te plaatsen, met behulp van het hulpprogramma Fiddler of de hulpprogramma's voor F12-ontwikkelaars.

Hoe validatie werkt

Je vraagt je misschien af hoe de validatie-UI is gegenereerd zonder dat de code in de controller of views is bijgewerkt. De volgende code toont de twee Create methoden.

// GET: Movies/Create
public IActionResult Create()
{
    return View();
}

// POST: Movies/Create
// To protect from overposting attacks, enable the specific properties you want to bind to.
// For more details, see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("Id,Title,ReleaseDate,Genre,Price,Rating")] Movie movie)
{
    if (ModelState.IsValid)
    {
        _context.Add(movie);
        await _context.SaveChangesAsync();
        return RedirectToAction(nameof(Index));
    }
    return View(movie);
}

De eerste (HTTP GET) Create actiemethode toont het initiële Create-formulier. De tweede ([HttpPost]) versie verwerkt het formulierbericht. Met de tweede Create methode (de [HttpPost] versie) roept ModelState.IsValid op om te controleren of de film validatiefouten heeft. Als u deze methode aanroept, worden alle validatiekenmerken geëvalueerd die zijn toegepast op het object. Als het object validatiefouten bevat, wordt het formulier opnieuw weergegeven met de Create methode. Als er geen fouten zijn, slaat de methode de nieuwe film op in de database. In ons voorbeeld van de film wordt het formulier niet op de server geplaatst wanneer er validatiefouten aan de clientzijde zijn gedetecteerd; de tweede Create methode wordt nooit aangeroepen wanneer er validatiefouten aan de clientzijde zijn. Als u JavaScript uitschakelt in uw browser, wordt clientvalidatie uitgeschakeld en kunt u de HTTP POST-methode CreateModelState.IsValid testen om validatiefouten te detecteren.

U kunt een onderbrekingspunt instellen in de [HttpPost] Create methode en controleren of de methode nooit wordt aangeroepen. Validatie aan de clientzijde verzendt de formuliergegevens niet wanneer er validatiefouten worden gedetecteerd. Als u JavaScript uitschakelt in uw browser en het formulier met fouten indient, wordt het onderbrekingspunt bereikt. U krijgt nog steeds volledige validatie zonder JavaScript.

In de volgende afbeelding ziet u hoe u JavaScript uitschakelt in de Firefox-browser.

Firefox: Schakel op het tabblad Inhoud van Opties het selectievakje Javascript inschakelen uit.

In de volgende afbeelding ziet u hoe u JavaScript uitschakelt in de Chrome-browser.

Google Chrome: Selecteer in de sectie Javascript van inhoudsinstellingen de optie Geen site toestaan Om JavaScript uit te voeren.

Nadat u JavaScript hebt uitgeschakeld, plaatst u ongeldige gegevens en doorloopt u het foutopsporingsprogramma.

Tijdens foutopsporing in een bericht met ongeldige gegevens geeft Intellisense op ModelState.IsValid aan dat de waarde onwaar is.

Een gedeelte van de Create.cshtml weergavesjabloon wordt weergegeven in de volgende markeringen:

<h4>Movie</h4>
<hr />
<div class="row">
    <div class="col-md-4">
        <form asp-action="Create">
            <div asp-validation-summary="ModelOnly" class="text-danger"></div>
            <div class="form-group">
                <label asp-for="Title" class="control-label"></label>
                <input asp-for="Title" class="form-control" />
                <span asp-validation-for="Title" class="text-danger"></span>
            </div>

            @*Markup removed for brevity.*@

De voorgaande markeringen worden gebruikt door de actiemethoden om het oorspronkelijke formulier weer te geven en opnieuw weer te geven in het geval van een fout.

De Helper voor invoertags maakt gebruik van de kenmerken DataAnnotations en produceert HTML-kenmerken die nodig zijn voor jQuery-validatie aan de clientzijde. In de Helper voor validatietags worden validatiefouten weergegeven. Zie Validatie voor meer informatie.

Wat erg leuk is aan deze benadering is dat noch de controller noch de Create weergavesjabloon iets weet over de daadwerkelijke validatieregels die worden afgedwongen of over de specifieke foutberichten die worden weergegeven. De validatieregels en de foutreeksen worden alleen in de Movie klasse opgegeven. Dezelfde validatieregels worden automatisch toegepast op de Edit weergave en eventuele andere weergavesjablonen die u mogelijk maakt om uw model te bewerken.

Wanneer u validatielogica moet wijzigen, kunt u dit op precies één plaats doen door validatiekenmerken toe te voegen aan het model (in dit voorbeeld de Movie klasse). U hoeft zich geen zorgen te maken over verschillende onderdelen van de toepassing die inconsistent zijn met de manier waarop de regels worden afgedwongen. Alle validatielogica wordt op één plaats gedefinieerd en overal gebruikt. Hierdoor blijft de code zeer schoon en is het eenvoudig om de code te onderhouden en te ontwikkelen. En het betekent dat je het DRY-principe volledig respecteert.

DataType-kenmerken gebruiken

Open het Movie.cs bestand en bekijk de Movie klasse. De System.ComponentModel.DataAnnotations naamruimte biedt opmaakkenmerken naast de ingebouwde set validatiekenmerken. We hebben al een DataType opsommingswaarde toegepast op de releasedatum en op de prijsvelden. De volgende code toont de ReleaseDate en Price eigenschappen met het juiste DataType kenmerk.

[Display(Name = "Release Date")]
[DataType(DataType.Date)]
public DateTime ReleaseDate { get; set; }

[Range(1, 100)]
[DataType(DataType.Currency)]
[Column(TypeName = "decimal(18, 2)")]
public decimal Price { get; set; }    

De DataType kenmerken bieden alleen hints voor de weergave-engine om de gegevens op te maken en elementen/kenmerken te leveren, zoals <a> voor URL's en <a href="mailto:EmailAddress.com"> voor e-mail. U kunt het RegularExpression kenmerk gebruiken om de indeling van de gegevens te valideren. Het DataType kenmerk wordt gebruikt om een gegevenstype op te geven dat specifieker is dan het intrinsieke type database. Dit zijn geen validatiekenmerken. In dit geval willen we alleen de datum bijhouden, niet de tijd. De DataType opsomming biedt veel gegevenstypen, zoals Datum, Tijd, PhoneNumber, Valuta, EmailAddress en meer. Het DataType kenmerk kan de toepassing ook inschakelen om automatisch typespecifieke functies te bieden. Er kan bijvoorbeeld een mailto: koppeling worden gemaakt voor DataType.EmailAddress, en er kan een datumkiezer worden opgegeven in DataType.Date browsers die HTML5 ondersteunen. De DataType kenmerken verzenden HTML 5 data- -kenmerken (uitgesproken als gegevensstreepje) die HTML 5-browsers kunnen begrijpen. De DataType kenmerken bieden geen validatie.

DataType.Date specificeert niet het formaat van de datum die wordt weergegeven. Het gegevensveld wordt standaard weergegeven volgens de standaardformaten gebaseerd op de serverinstellingen CultureInfo.

Het DisplayFormat kenmerk wordt gebruikt om expliciet de datumnotatie op te geven:

[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime ReleaseDate { get; set; }

De ApplyFormatInEditMode instelling geeft aan dat de opmaak ook moet worden toegepast wanneer de waarde wordt weergegeven in een tekstvak voor bewerking. (Mogelijk wilt u dit niet voor sommige velden, bijvoorbeeld voor valutawaarden, wilt u waarschijnlijk niet dat het valutasymbool in het tekstvak wordt bewerkt.)

U kunt het DisplayFormat kenmerk zelf gebruiken, maar het is over het algemeen een goed idee om het DataType kenmerk te gebruiken. Het DataType kenmerk geeft de semantiek van de gegevens weer in plaats van hoe u deze op een scherm weergeeft en biedt de volgende voordelen die u niet krijgt met DisplayFormat:

  • De browser kan HTML5-functies inschakelen (bijvoorbeeld om een agendabesturingselement weer te geven, het valutasymbool dat geschikt is voor landinstellingen, e-mailkoppelingen, enzovoort)

  • Standaard worden in de browser gegevens weergegeven met de juiste indeling op basis van uw landinstelling.

  • Het DataType kenmerk kan MVC inschakelen om de juiste veldsjabloon te kiezen om de gegevens weer te geven (de DisplayFormat als deze door zichzelf wordt gebruikt, wordt de tekenreekssjabloon gebruikt).

Opmerking

jQuery-validatie werkt niet met het Range kenmerk en DateTime. Met de volgende code wordt bijvoorbeeld altijd een validatiefout aan de clientzijde weergegeven, zelfs wanneer de datum zich in het opgegeven bereik bevindt:

[Range(typeof(DateTime), "1/1/1966", "1/1/2020")]

Je moet jQuery-datumvalidatie deactiveren om het Range kenmerk te gebruiken met DateTime. Het is over het algemeen geen goede gewoonte om harde datums in uw modellen te compileren, dus het gebruik van het Range kenmerk en DateTime wordt afgeraden.

De volgende code toont het combineren van kenmerken op één regel:

using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace MvcMovie.Models;

public class Movie
{
    public int Id { get; set; }
    [StringLength(60, MinimumLength = 3)]
    public string? Title { get; set; }
    [Display(Name = "Release Date"), DataType(DataType.Date)]
    public DateTime ReleaseDate { get; set; }
    [RegularExpression(@"^[A-Z]+[a-zA-Z\s]*$"), Required, StringLength(30)]
    public string? Genre { get; set; }
    [Range(1, 100), DataType(DataType.Currency), Column(TypeName = "decimal(18, 2)")]
    public decimal Price { get; set; }
    [RegularExpression(@"^[A-Z]+[a-zA-Z0-9""'\s-]*$"), StringLength(5)]
    public string? Rating { get; set; }
}

In het volgende deel van de reeks bekijken we de app en brengen we enkele verbeteringen aan in de automatisch gegenereerde Details en Delete methoden.

Aanvullende bronnen

In deze sectie:

  • Validatielogica wordt toegevoegd aan het Movie model.
  • U zorgt ervoor dat de validatieregels worden afgedwongen wanneer een gebruiker een film maakt of bewerkt.

Alles droog houden

Een van de ontwerpprincipes van MVC is DRY ('Don't Repeat Yourself'). ASP.NET Core MVC moedigt u aan om slechts één keer functionaliteit of gedrag op te geven en deze vervolgens overal in een app te laten zien. Dit vermindert de hoeveelheid code die u moet schrijven en maakt de code die u doet minder foutgevoelig, gemakkelijker te testen en gemakkelijker te onderhouden.

De validatieondersteuning van MVC en Entity Framework Core Code First is een goed voorbeeld van het DRY-principe in actie. U kunt declaratief validatieregels opgeven op één plaats (in de modelklasse) en de regels worden overal in de app afgedwongen.

De eerder bewerkte gegevens verwijderen

In de volgende stap worden validatieregels toegevoegd die null-waarden niet toestaan. Voer de app uit, navigeer naar /Movies/Index, verwijder alle vermelde films en stop de app. De app gebruikt de seed-gegevens de volgende keer dat deze wordt uitgevoerd.

Validatieregels toevoegen aan het filmmodel

De naamruimte DataAnnotations biedt een set ingebouwde validatiekenmerken die declaratief worden toegepast op een klasse of eigenschap. DataAnnotations bevat ook opmaakkenmerken zoals DataType die helpen bij het opmaken en bieden geen validatie.

Werk de Movie klasse bij om te profiteren van de ingebouwde validatiekenmerkenRequired, StringLengthRegularExpressionRangeen het DataType opmaakkenmerk.

using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace MvcMovie.Models;

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

    [StringLength(60, MinimumLength = 3)]
    [Required]
    public string? Title { get; set; }

    [Display(Name = "Release Date")]
    [DataType(DataType.Date)]
    public DateTime ReleaseDate { get; set; }

    [Range(1, 100)]
    [DataType(DataType.Currency)]
    [Column(TypeName = "decimal(18, 2)")]
    public decimal Price { get; set; }    

    [RegularExpression(@"^[A-Z]+[a-zA-Z\s]*$")]
    [Required]
    [StringLength(30)]
    public string? Genre { get; set; }

    [RegularExpression(@"^[A-Z]+[a-zA-Z0-9""'\s-]*$")]
    [StringLength(5)]
    [Required]
    public string? Rating { get; set; }
}

De validatiekenmerken geven het gedrag op dat u wilt afdwingen voor de modeleigenschappen waarop ze worden toegepast:

  • De Required en MinimumLength kenmerken geven aan dat een eigenschap een waarde moet hebben, maar niets voorkomt dat een gebruiker witruimte invoert om aan deze validatie te voldoen.

  • Het kenmerk RegularExpression wordt gebruikt om te beperken welke tekens kunnen worden ingevoerd. In de voorgaande code, "Genre":

    • Mag alleen letters gebruiken.
    • De eerste letter moet een hoofdletter zijn. Spaties zijn toegestaan, maar getallen en speciale tekens zijn niet toegestaan.
  • De RegularExpression "Beoordeling":

    • Vereist dat het eerste teken een hoofdletter is.
    • Hiermee worden speciale tekens en nummers toegestaan in achtereenvolgende spaties. "PG-13" is geldig voor een beoordeling, maar is niet geschikt voor een genre.
  • Het Range kenmerk beperkt een waarde tot binnen een opgegeven bereik.

  • StringLength Met het kenmerk kunt u de maximale lengte van een tekenreekseigenschap en eventueel de minimale lengte instellen.

  • Waardetypen (zoals decimal, int, float, ) DateTimezijn inherent vereist en hebben het [Required] kenmerk niet nodig.

Door validatieregels automatisch af te dwingen door ASP.NET Core, kunt u uw app robuuster maken. Het zorgt er ook voor dat u niet kunt vergeten om iets te valideren en per ongeluk slechte gegevens in de database toe te staan.

Validatiefout Gebruikersinterface

Voer de app uit en navigeer naar de Films-controller.

Selecteer de koppeling Nieuwe maken om een nieuwe film toe te voegen. Vul het formulier in met een aantal ongeldige waarden. Zodra de jQuery-clientvalidatie de fout detecteert, wordt er een foutbericht weergegeven.

Formulier voor filmweergave met meerdere validatiefouten aan de clientzijde van jQuery

Opmerking

Mogelijk kunt u geen decimale komma's invoeren in decimale velden. Als u ondersteuning wilt bieden voor jQuery-validatie voor niet-Engelstalige landinstellingen die een komma (",") gebruiken voor een decimaalteken en niet-US-English datumnotaties, moet u stappen uitvoeren om uw app te globaliseren. Zie deze GitHub-opmerking 4076 voor instructies over het toevoegen van komma's.

U ziet hoe het formulier automatisch een geschikt validatiefoutbericht heeft weergegeven in elk veld met een ongeldige waarde. De fouten worden afgedwongen aan de clientzijde (met behulp van JavaScript en jQuery) en aan de serverzijde (voor het geval een gebruiker JavaScript heeft uitgeschakeld).

Een belangrijk voordeel is dat u geen enkele regel code in de MoviesController klasse of in de Create.cshtml weergave hoeft te wijzigen om deze validatiegebruikersinterface in te schakelen. De controller en weergaven die u eerder in deze zelfstudie hebt gemaakt, hebben automatisch de validatieregels opgehaald die u hebt opgegeven met behulp van validatiekenmerken voor de eigenschappen van de Movie modelklasse. Testvalidatie met behulp van de Edit actiemethode en dezelfde validatie wordt toegepast.

De formuliergegevens worden pas naar de server verzonden als er geen validatiefouten aan de clientzijde zijn. U kunt dit controleren door een onderbrekingspunt in de HTTP Post methode te plaatsen, met behulp van het hulpprogramma Fiddler of de hulpprogramma's voor F12-ontwikkelaars.

Hoe validatie werkt

Je vraagt je misschien af hoe de validatie-UI is gegenereerd zonder dat de code in de controller of views is bijgewerkt. De volgende code toont de twee Create methoden.

// GET: Movies/Create
public IActionResult Create()
{
    return View();
}

// POST: Movies/Create
// To protect from overposting attacks, enable the specific properties you want to bind to.
// For more details, see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("Id,Title,ReleaseDate,Genre,Price,Rating")] Movie movie)
{
    if (ModelState.IsValid)
    {
        _context.Add(movie);
        await _context.SaveChangesAsync();
        return RedirectToAction(nameof(Index));
    }
    return View(movie);
}

De eerste (HTTP GET) Create actiemethode toont het initiële Create-formulier. De tweede ([HttpPost]) versie verwerkt het formulierbericht. Met de tweede Create methode (de [HttpPost] versie) roept ModelState.IsValid op om te controleren of de film validatiefouten heeft. Als u deze methode aanroept, worden alle validatiekenmerken geëvalueerd die zijn toegepast op het object. Als het object validatiefouten bevat, wordt het formulier opnieuw weergegeven met de Create methode. Als er geen fouten zijn, slaat de methode de nieuwe film op in de database. In ons voorbeeld van de film wordt het formulier niet op de server geplaatst wanneer er validatiefouten aan de clientzijde zijn gedetecteerd; de tweede Create methode wordt nooit aangeroepen wanneer er validatiefouten aan de clientzijde zijn. Als u JavaScript uitschakelt in uw browser, wordt clientvalidatie uitgeschakeld en kunt u de HTTP POST-methode CreateModelState.IsValid testen om validatiefouten te detecteren.

U kunt een onderbrekingspunt instellen in de [HttpPost] Create methode en controleren of de methode nooit wordt aangeroepen. Validatie aan de clientzijde verzendt de formuliergegevens niet wanneer er validatiefouten worden gedetecteerd. Als u JavaScript uitschakelt in uw browser en het formulier met fouten indient, wordt het onderbrekingspunt bereikt. U krijgt nog steeds volledige validatie zonder JavaScript.

In de volgende afbeelding ziet u hoe u JavaScript uitschakelt in de Firefox-browser.

Firefox: Schakel op het tabblad Inhoud van Opties het selectievakje Javascript inschakelen uit.

In de volgende afbeelding ziet u hoe u JavaScript uitschakelt in de Chrome-browser.

Google Chrome: Selecteer in de sectie Javascript van inhoudsinstellingen de optie Geen site toestaan Om JavaScript uit te voeren.

Nadat u JavaScript hebt uitgeschakeld, plaatst u ongeldige gegevens en doorloopt u het foutopsporingsprogramma.

Tijdens foutopsporing in een bericht met ongeldige gegevens geeft Intellisense op ModelState.IsValid aan dat de waarde onwaar is.

Een gedeelte van de Create.cshtml weergavesjabloon wordt weergegeven in de volgende markeringen:

<h4>Movie</h4>
<hr />
<div class="row">
    <div class="col-md-4">
        <form asp-action="Create">
            <div asp-validation-summary="ModelOnly" class="text-danger"></div>
            <div class="form-group">
                <label asp-for="Title" class="control-label"></label>
                <input asp-for="Title" class="form-control" />
                <span asp-validation-for="Title" class="text-danger"></span>
            </div>

            @*Markup removed for brevity.*@

De voorgaande markeringen worden gebruikt door de actiemethoden om het oorspronkelijke formulier weer te geven en opnieuw weer te geven in het geval van een fout.

De Helper voor invoertags maakt gebruik van de kenmerken DataAnnotations en produceert HTML-kenmerken die nodig zijn voor jQuery-validatie aan de clientzijde. In de Helper voor validatietags worden validatiefouten weergegeven. Zie Validatie voor meer informatie.

Wat erg leuk is aan deze benadering is dat noch de controller noch de Create weergavesjabloon iets weet over de daadwerkelijke validatieregels die worden afgedwongen of over de specifieke foutberichten die worden weergegeven. De validatieregels en de foutreeksen worden alleen in de Movie klasse opgegeven. Dezelfde validatieregels worden automatisch toegepast op de Edit weergave en eventuele andere weergavesjablonen die u mogelijk maakt om uw model te bewerken.

Wanneer u validatielogica moet wijzigen, kunt u dit op precies één plaats doen door validatiekenmerken toe te voegen aan het model (in dit voorbeeld de Movie klasse). U hoeft zich geen zorgen te maken over verschillende onderdelen van de toepassing die inconsistent zijn met de manier waarop de regels worden afgedwongen. Alle validatielogica wordt op één plaats gedefinieerd en overal gebruikt. Hierdoor blijft de code zeer schoon en is het eenvoudig om de code te onderhouden en te ontwikkelen. En het betekent dat je het DRY-principe volledig respecteert.

DataType-kenmerken gebruiken

Open het Movie.cs bestand en bekijk de Movie klasse. De System.ComponentModel.DataAnnotations naamruimte biedt opmaakkenmerken naast de ingebouwde set validatiekenmerken. We hebben al een DataType opsommingswaarde toegepast op de releasedatum en op de prijsvelden. De volgende code toont de ReleaseDate en Price eigenschappen met het juiste DataType kenmerk.

[Display(Name = "Release Date")]
[DataType(DataType.Date)]
public DateTime ReleaseDate { get; set; }

[Range(1, 100)]
[DataType(DataType.Currency)]
[Column(TypeName = "decimal(18, 2)")]
public decimal Price { get; set; }    

De DataType kenmerken bieden alleen hints voor de weergave-engine om de gegevens op te maken en elementen/kenmerken te leveren, zoals <a> voor URL's en <a href="mailto:EmailAddress.com"> voor e-mail. U kunt het RegularExpression kenmerk gebruiken om de indeling van de gegevens te valideren. Het DataType kenmerk wordt gebruikt om een gegevenstype op te geven dat specifieker is dan het intrinsieke type database. Dit zijn geen validatiekenmerken. In dit geval willen we alleen de datum bijhouden, niet de tijd. De DataType opsomming biedt veel gegevenstypen, zoals Datum, Tijd, PhoneNumber, Valuta, EmailAddress en meer. Het DataType kenmerk kan de toepassing ook inschakelen om automatisch typespecifieke functies te bieden. Er kan bijvoorbeeld een mailto: koppeling worden gemaakt voor DataType.EmailAddress, en er kan een datumkiezer worden opgegeven in DataType.Date browsers die HTML5 ondersteunen. De DataType kenmerken verzenden HTML 5 data- -kenmerken (uitgesproken als gegevensstreepje) die HTML 5-browsers kunnen begrijpen. De DataType kenmerken bieden geen validatie.

DataType.Date specificeert niet het formaat van de datum die wordt weergegeven. Het gegevensveld wordt standaard weergegeven volgens de standaardformaten gebaseerd op de serverinstellingen CultureInfo.

Het DisplayFormat kenmerk wordt gebruikt om expliciet de datumnotatie op te geven:

[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime ReleaseDate { get; set; }

De ApplyFormatInEditMode instelling geeft aan dat de opmaak ook moet worden toegepast wanneer de waarde wordt weergegeven in een tekstvak voor bewerking. (Mogelijk wilt u dit niet voor sommige velden, bijvoorbeeld voor valutawaarden, wilt u waarschijnlijk niet dat het valutasymbool in het tekstvak wordt bewerkt.)

U kunt het DisplayFormat kenmerk zelf gebruiken, maar het is over het algemeen een goed idee om het DataType kenmerk te gebruiken. Het DataType kenmerk geeft de semantiek van de gegevens weer in plaats van hoe u deze op een scherm weergeeft en biedt de volgende voordelen die u niet krijgt met DisplayFormat:

  • De browser kan HTML5-functies inschakelen (bijvoorbeeld om een agendabesturingselement weer te geven, het valutasymbool dat geschikt is voor landinstellingen, e-mailkoppelingen, enzovoort)

  • Standaard worden in de browser gegevens weergegeven met de juiste indeling op basis van uw landinstelling.

  • Het DataType kenmerk kan MVC inschakelen om de juiste veldsjabloon te kiezen om de gegevens weer te geven (de DisplayFormat als deze door zichzelf wordt gebruikt, wordt de tekenreekssjabloon gebruikt).

Opmerking

jQuery-validatie werkt niet met het Range kenmerk en DateTime. Met de volgende code wordt bijvoorbeeld altijd een validatiefout aan de clientzijde weergegeven, zelfs wanneer de datum zich in het opgegeven bereik bevindt:

[Range(typeof(DateTime), "1/1/1966", "1/1/2020")]

Je moet jQuery-datumvalidatie deactiveren om het Range kenmerk te gebruiken met DateTime. Het is over het algemeen geen goede gewoonte om harde datums in uw modellen te compileren, dus het gebruik van het Range kenmerk en DateTime wordt afgeraden.

De volgende code toont het combineren van kenmerken op één regel:

using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace MvcMovie.Models;

public class Movie
{
    public int Id { get; set; }
    [StringLength(60, MinimumLength = 3)]
    public string Title { get; set; }
    [Display(Name = "Release Date"), DataType(DataType.Date)]
    public DateTime ReleaseDate { get; set; }
    [RegularExpression(@"^[A-Z]+[a-zA-Z\s]*$"), Required, StringLength(30)]
    public string Genre { get; set; }
    [Range(1, 100), DataType(DataType.Currency)]
    [Column(TypeName = "decimal(18, 2)")]
    public decimal Price { get; set; }
    [RegularExpression(@"^[A-Z]+[a-zA-Z0-9""'\s-]*$"), StringLength(5)]
    public string Rating { get; set; }
}

In het volgende deel van de reeks bekijken we de app en brengen we enkele verbeteringen aan in de automatisch gegenereerde Details en Delete methoden.

Aanvullende bronnen

In deze sectie:

  • Validatielogica wordt toegevoegd aan het Movie model.
  • U zorgt ervoor dat de validatieregels worden afgedwongen wanneer een gebruiker een film maakt of bewerkt.

Alles droog houden

Een van de ontwerpprincipes van MVC is DRY ('Don't Repeat Yourself'). ASP.NET Core MVC moedigt u aan om slechts één keer functionaliteit of gedrag op te geven en deze vervolgens overal in een app te laten zien. Dit vermindert de hoeveelheid code die u moet schrijven en maakt de code die u doet minder foutgevoelig, gemakkelijker te testen en gemakkelijker te onderhouden.

De validatieondersteuning van MVC en Entity Framework Core Code First is een goed voorbeeld van het DRY-principe in actie. U kunt declaratief validatieregels opgeven op één plaats (in de modelklasse) en de regels worden overal in de app afgedwongen.

Validatieregels toevoegen aan het filmmodel

De naamruimte DataAnnotations biedt een set ingebouwde validatiekenmerken die declaratief worden toegepast op een klasse of eigenschap. DataAnnotations bevat ook opmaakkenmerken zoals DataType die helpen bij het opmaken en bieden geen validatie.

Werk de Movie klasse bij om te profiteren van de ingebouwde validatiekenmerkenRequired, StringLengthRegularExpressionRangeen het DataType opmaakkenmerk.

using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace MvcMovie.Models;

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

    [StringLength(60, MinimumLength = 3)]
    [Required]
    public string? Title { get; set; }

    [Display(Name = "Release Date")]
    [DataType(DataType.Date)]
    public DateTime ReleaseDate { get; set; }

    [Range(1, 100)]
    [DataType(DataType.Currency)]
    [Column(TypeName = "decimal(18, 2)")]
    public decimal Price { get; set; }    

    [RegularExpression(@"^[A-Z]+[a-zA-Z\s]*$")]
    [Required]
    [StringLength(30)]
    public string? Genre { get; set; }
    
    [RegularExpression(@"^[A-Z]+[a-zA-Z0-9""'\s-]*$")]
    [StringLength(5)]
    [Required]
    public string? Rating { get; set; }
}

De validatiekenmerken geven het gedrag op dat u wilt afdwingen voor de modeleigenschappen waarop ze worden toegepast:

  • De Required en MinimumLength kenmerken geven aan dat een eigenschap een waarde moet hebben, maar niets voorkomt dat een gebruiker witruimte invoert om aan deze validatie te voldoen.

  • Het kenmerk RegularExpression wordt gebruikt om te beperken welke tekens kunnen worden ingevoerd. In de voorgaande code, "Genre":

    • Mag alleen letters gebruiken.
    • De eerste letter moet een hoofdletter zijn. Spaties zijn toegestaan, maar getallen en speciale tekens zijn niet toegestaan.
  • De RegularExpression "Beoordeling":

    • Vereist dat het eerste teken een hoofdletter is.
    • Hiermee worden speciale tekens en nummers toegestaan in achtereenvolgende spaties. "PG-13" is geldig voor een beoordeling, maar is niet geschikt voor een genre.
  • Het Range kenmerk beperkt een waarde tot binnen een opgegeven bereik.

  • StringLength Met het kenmerk kunt u de maximale lengte van een tekenreekseigenschap en eventueel de minimale lengte instellen.

  • Waardetypen (zoals decimal, int, float, ) DateTimezijn inherent vereist en hebben het [Required] kenmerk niet nodig.

Door validatieregels automatisch af te dwingen door ASP.NET Core, kunt u uw app robuuster maken. Het zorgt er ook voor dat u niet kunt vergeten om iets te valideren en per ongeluk slechte gegevens in de database toe te staan.

Validatiefout Gebruikersinterface

Voer de app uit en navigeer naar de Films-controller.

Selecteer de koppeling Nieuwe maken om een nieuwe film toe te voegen. Vul het formulier in met een aantal ongeldige waarden. Zodra de jQuery-clientvalidatie de fout detecteert, wordt er een foutbericht weergegeven.

Formulier voor filmweergave met meerdere validatiefouten aan de clientzijde van jQuery

Opmerking

Mogelijk kunt u geen decimale komma's invoeren in decimale velden. Als u ondersteuning wilt bieden voor jQuery-validatie voor niet-Engelstalige landinstellingen die een komma (",") gebruiken voor een decimaalteken en niet-US-English datumnotaties, moet u stappen uitvoeren om uw app te globaliseren. Zie deze GitHub-opmerking 4076 voor instructies over het toevoegen van komma's.

U ziet hoe het formulier automatisch een geschikt validatiefoutbericht heeft weergegeven in elk veld met een ongeldige waarde. De fouten worden afgedwongen aan de clientzijde (met behulp van JavaScript en jQuery) en aan de serverzijde (voor het geval een gebruiker JavaScript heeft uitgeschakeld).

Een belangrijk voordeel is dat u geen enkele regel code in de MoviesController klasse of in de Create.cshtml weergave hoeft te wijzigen om deze validatiegebruikersinterface in te schakelen. De controller en weergaven die u eerder in deze zelfstudie hebt gemaakt, hebben automatisch de validatieregels opgehaald die u hebt opgegeven met behulp van validatiekenmerken voor de eigenschappen van de Movie modelklasse. Testvalidatie met behulp van de Edit actiemethode en dezelfde validatie wordt toegepast.

De formuliergegevens worden pas naar de server verzonden als er geen validatiefouten aan de clientzijde zijn. U kunt dit controleren door een onderbrekingspunt in de HTTP Post methode te plaatsen, met behulp van het hulpprogramma Fiddler of de hulpprogramma's voor F12-ontwikkelaars.

Hoe validatie werkt

Je vraagt je misschien af hoe de validatie-UI is gegenereerd zonder dat de code in de controller of views is bijgewerkt. De volgende code toont de twee Create methoden.

// GET: Movies/Create
public IActionResult Create()
{
    return View();
}

// POST: Movies/Create
// To protect from overposting attacks, enable the specific properties you want to bind to.
// For more details, see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("Id,Title,ReleaseDate,Genre,Price,Rating")] Movie movie)
{
    if (ModelState.IsValid)
    {
        _context.Add(movie);
        await _context.SaveChangesAsync();
        return RedirectToAction(nameof(Index));
    }
    return View(movie);
}

De eerste (HTTP GET) Create actiemethode toont het initiële Create-formulier. De tweede ([HttpPost]) versie verwerkt het formulierbericht. Met de tweede Create methode (de [HttpPost] versie) roept ModelState.IsValid op om te controleren of de film validatiefouten heeft. Als u deze methode aanroept, worden alle validatiekenmerken geëvalueerd die zijn toegepast op het object. Als het object validatiefouten bevat, wordt het formulier opnieuw weergegeven met de Create methode. Als er geen fouten zijn, slaat de methode de nieuwe film op in de database. In ons voorbeeld van de film wordt het formulier niet op de server geplaatst wanneer er validatiefouten aan de clientzijde zijn gedetecteerd; de tweede Create methode wordt nooit aangeroepen wanneer er validatiefouten aan de clientzijde zijn. Als u JavaScript uitschakelt in uw browser, wordt clientvalidatie uitgeschakeld en kunt u de HTTP POST-methode CreateModelState.IsValid testen om validatiefouten te detecteren.

U kunt een onderbrekingspunt instellen in de [HttpPost] Create methode en controleren of de methode nooit wordt aangeroepen. Validatie aan de clientzijde verzendt de formuliergegevens niet wanneer er validatiefouten worden gedetecteerd. Als u JavaScript uitschakelt in uw browser en het formulier met fouten indient, wordt het onderbrekingspunt bereikt. U krijgt nog steeds volledige validatie zonder JavaScript.

In de volgende afbeelding ziet u hoe u JavaScript uitschakelt in de Firefox-browser.

Firefox: Schakel op het tabblad Inhoud van Opties het selectievakje Javascript inschakelen uit.

In de volgende afbeelding ziet u hoe u JavaScript uitschakelt in de Chrome-browser.

Google Chrome: Selecteer in de sectie Javascript van inhoudsinstellingen de optie Geen site toestaan Om JavaScript uit te voeren.

Nadat u JavaScript hebt uitgeschakeld, plaatst u ongeldige gegevens en doorloopt u het foutopsporingsprogramma.

Tijdens foutopsporing in een bericht met ongeldige gegevens geeft Intellisense op ModelState.IsValid aan dat de waarde onwaar is.

Een gedeelte van de Create.cshtml weergavesjabloon wordt weergegeven in de volgende markeringen:

<h4>Movie</h4>
<hr />
<div class="row">
    <div class="col-md-4">
        <form asp-action="Create">
            <div asp-validation-summary="ModelOnly" class="text-danger"></div>
            <div class="form-group">
                <label asp-for="Title" class="control-label"></label>
                <input asp-for="Title" class="form-control" />
                <span asp-validation-for="Title" class="text-danger"></span>
            </div>

            @*Markup removed for brevity.*@

De voorgaande markeringen worden gebruikt door de actiemethoden om het oorspronkelijke formulier weer te geven en opnieuw weer te geven in het geval van een fout.

De Helper voor invoertags maakt gebruik van de kenmerken DataAnnotations en produceert HTML-kenmerken die nodig zijn voor jQuery-validatie aan de clientzijde. In de Helper voor validatietags worden validatiefouten weergegeven. Zie Validatie voor meer informatie.

Wat erg leuk is aan deze benadering is dat noch de controller noch de Create weergavesjabloon iets weet over de daadwerkelijke validatieregels die worden afgedwongen of over de specifieke foutberichten die worden weergegeven. De validatieregels en de foutreeksen worden alleen in de Movie klasse opgegeven. Dezelfde validatieregels worden automatisch toegepast op de Edit weergave en eventuele andere weergavesjablonen die u mogelijk maakt om uw model te bewerken.

Wanneer u validatielogica moet wijzigen, kunt u dit op precies één plaats doen door validatiekenmerken toe te voegen aan het model (in dit voorbeeld de Movie klasse). U hoeft zich geen zorgen te maken over verschillende onderdelen van de toepassing die inconsistent zijn met de manier waarop de regels worden afgedwongen. Alle validatielogica wordt op één plaats gedefinieerd en overal gebruikt. Hierdoor blijft de code zeer schoon en is het eenvoudig om de code te onderhouden en te ontwikkelen. En het betekent dat je het DRY-principe volledig respecteert.

DataType-kenmerken gebruiken

Open het Movie.cs bestand en bekijk de Movie klasse. De System.ComponentModel.DataAnnotations naamruimte biedt opmaakkenmerken naast de ingebouwde set validatiekenmerken. We hebben al een DataType opsommingswaarde toegepast op de releasedatum en op de prijsvelden. De volgende code toont de ReleaseDate en Price eigenschappen met het juiste DataType kenmerk.

[Display(Name = "Release Date")]
[DataType(DataType.Date)]
public DateTime ReleaseDate { get; set; }

[Range(1, 100)]
[DataType(DataType.Currency)]
[Column(TypeName = "decimal(18, 2)")]
public decimal Price { get; set; }    

De DataType kenmerken bieden alleen hints voor de weergave-engine om de gegevens op te maken en elementen/kenmerken te leveren, zoals <a> voor URL's en <a href="mailto:EmailAddress.com"> voor e-mail. U kunt het RegularExpression kenmerk gebruiken om de indeling van de gegevens te valideren. Het DataType kenmerk wordt gebruikt om een gegevenstype op te geven dat specifieker is dan het intrinsieke type database. Dit zijn geen validatiekenmerken. In dit geval willen we alleen de datum bijhouden, niet de tijd. De DataType opsomming biedt veel gegevenstypen, zoals Datum, Tijd, PhoneNumber, Valuta, EmailAddress en meer. Het DataType kenmerk kan de toepassing ook inschakelen om automatisch typespecifieke functies te bieden. Er kan bijvoorbeeld een mailto: koppeling worden gemaakt voor DataType.EmailAddress, en er kan een datumkiezer worden opgegeven in DataType.Date browsers die HTML5 ondersteunen. De DataType kenmerken verzenden HTML 5 data- -kenmerken (uitgesproken als gegevensstreepje) die HTML 5-browsers kunnen begrijpen. De DataType kenmerken bieden geen validatie.

DataType.Date specificeert niet het formaat van de datum die wordt weergegeven. Het gegevensveld wordt standaard weergegeven volgens de standaardformaten gebaseerd op de serverinstellingen CultureInfo.

Het DisplayFormat kenmerk wordt gebruikt om expliciet de datumnotatie op te geven:

[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime ReleaseDate { get; set; }

De ApplyFormatInEditMode instelling geeft aan dat de opmaak ook moet worden toegepast wanneer de waarde wordt weergegeven in een tekstvak voor bewerking. (Mogelijk wilt u dit niet voor sommige velden, bijvoorbeeld voor valutawaarden, wilt u waarschijnlijk niet dat het valutasymbool in het tekstvak wordt bewerkt.)

U kunt het DisplayFormat kenmerk zelf gebruiken, maar het is over het algemeen een goed idee om het DataType kenmerk te gebruiken. Het DataType kenmerk geeft de semantiek van de gegevens weer in plaats van hoe u deze op een scherm weergeeft en biedt de volgende voordelen die u niet krijgt met DisplayFormat:

  • De browser kan HTML5-functies inschakelen (bijvoorbeeld om een agendabesturingselement weer te geven, het valutasymbool dat geschikt is voor landinstellingen, e-mailkoppelingen, enzovoort)

  • Standaard worden in de browser gegevens weergegeven met de juiste indeling op basis van uw landinstelling.

  • Het DataType kenmerk kan MVC inschakelen om de juiste veldsjabloon te kiezen om de gegevens weer te geven (de DisplayFormat als deze door zichzelf wordt gebruikt, wordt de tekenreekssjabloon gebruikt).

Opmerking

jQuery-validatie werkt niet met het Range kenmerk en DateTime. Met de volgende code wordt bijvoorbeeld altijd een validatiefout aan de clientzijde weergegeven, zelfs wanneer de datum zich in het opgegeven bereik bevindt:

[Range(typeof(DateTime), "1/1/1966", "1/1/2020")]

Je moet jQuery-datumvalidatie deactiveren om het Range kenmerk te gebruiken met DateTime. Het is over het algemeen geen goede gewoonte om harde datums in uw modellen te compileren, dus het gebruik van het Range kenmerk en DateTime wordt afgeraden.

De volgende code toont het combineren van kenmerken op één regel:

using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace MvcMovie.Models;

public class Movie
{
    public int Id { get; set; }
    [StringLength(60, MinimumLength = 3)]
    public string Title { get; set; }
    [Display(Name = "Release Date"), DataType(DataType.Date)]
    public DateTime ReleaseDate { get; set; }
    [RegularExpression(@"^[A-Z]+[a-zA-Z\s]*$"), Required, StringLength(30)]
    public string Genre { get; set; }
    [Range(1, 100), DataType(DataType.Currency)]
    [Column(TypeName = "decimal(18, 2)")]
    public decimal Price { get; set; }
    [RegularExpression(@"^[A-Z]+[a-zA-Z0-9""'\s-]*$"), StringLength(5)]
    public string Rating { get; set; }
}

In het volgende deel van de reeks bekijken we de app en brengen we enkele verbeteringen aan in de automatisch gegenereerde Details en Delete methoden.

Aanvullende bronnen

In deze sectie:

  • Validatielogica wordt toegevoegd aan het Movie model.
  • U zorgt ervoor dat de validatieregels worden afgedwongen wanneer een gebruiker een film maakt of bewerkt.

Alles droog houden

Een van de ontwerpprincipes van MVC is DRY ('Don't Repeat Yourself'). ASP.NET Core MVC moedigt u aan om slechts één keer functionaliteit of gedrag op te geven en deze vervolgens overal in een app te laten zien. Dit vermindert de hoeveelheid code die u moet schrijven en maakt de code die u doet minder foutgevoelig, gemakkelijker te testen en gemakkelijker te onderhouden.

De validatieondersteuning van MVC en Entity Framework Core Code First is een goed voorbeeld van het DRY-principe in actie. U kunt declaratief validatieregels opgeven op één plaats (in de modelklasse) en de regels worden overal in de app afgedwongen.

Validatieregels toevoegen aan het filmmodel

De naamruimte DataAnnotations biedt een set ingebouwde validatiekenmerken die declaratief worden toegepast op een klasse of eigenschap. DataAnnotations bevat ook opmaakkenmerken zoals DataType die helpen bij het opmaken en bieden geen validatie.

Werk de Movie klasse bij om te profiteren van de ingebouwde Required, StringLengthen RegularExpressionRange validatiekenmerken.

using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

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

        [StringLength(60, MinimumLength = 3)]
        [Required]
        public string? Title { get; set; }

        [Display(Name = "Release Date")]
        [DataType(DataType.Date)]
        public DateTime ReleaseDate { get; set; }

        [Range(1, 100)]
        [DataType(DataType.Currency)]
        [Column(TypeName = "decimal(18, 2)")]
        public decimal Price { get; set; }

        [RegularExpression(@"^[A-Z]+[a-zA-Z\s]*$")]
        [Required]
        [StringLength(30)]
        public string? Genre { get; set; }

        [RegularExpression(@"^[A-Z]+[a-zA-Z0-9""'\s-]*$")]
        [StringLength(5)]
        [Required]
        public string? Rating { get; set; }
    }
}

De validatiekenmerken geven het gedrag op dat u wilt afdwingen voor de modeleigenschappen waarop ze worden toegepast:

  • De Required en MinimumLength kenmerken geven aan dat een eigenschap een waarde moet hebben, maar niets voorkomt dat een gebruiker witruimte invoert om aan deze validatie te voldoen.

  • Het kenmerk RegularExpression wordt gebruikt om te beperken welke tekens kunnen worden ingevoerd. In de voorgaande code, "Genre":

    • Mag alleen letters gebruiken.
    • De eerste letter moet een hoofdletter zijn. Spaties zijn toegestaan, maar getallen en speciale tekens zijn niet toegestaan.
  • De RegularExpression "Beoordeling":

    • Vereist dat het eerste teken een hoofdletter is.
    • Hiermee worden speciale tekens en nummers toegestaan in achtereenvolgende spaties. "PG-13" is geldig voor een beoordeling, maar is niet geschikt voor een genre.
  • Het Range kenmerk beperkt een waarde tot binnen een opgegeven bereik.

  • StringLength Met het kenmerk kunt u de maximale lengte van een tekenreekseigenschap en eventueel de minimale lengte instellen.

  • Waardetypen (zoals decimal, int, float, ) DateTimezijn inherent vereist en hebben het [Required] kenmerk niet nodig.

Door validatieregels automatisch af te dwingen door ASP.NET Core, kunt u uw app robuuster maken. Het zorgt er ook voor dat u niet kunt vergeten om iets te valideren en per ongeluk slechte gegevens in de database toe te staan.

Validatiefout Gebruikersinterface

Voer de app uit en navigeer naar de Films-controller.

Selecteer de koppeling Nieuwe maken om een nieuwe film toe te voegen. Vul het formulier in met een aantal ongeldige waarden. Zodra de jQuery-clientvalidatie de fout detecteert, wordt er een foutbericht weergegeven.

Formulier voor filmweergave met meerdere validatiefouten aan de clientzijde van jQuery

Opmerking

Mogelijk kunt u geen decimale komma's invoeren in decimale velden. Als u ondersteuning wilt bieden voor jQuery-validatie voor niet-Engelstalige landinstellingen die een komma (",") gebruiken voor een decimaalteken en niet-US-English datumnotaties, moet u stappen uitvoeren om uw app te globaliseren. Zie deze GitHub-opmerking 4076 voor instructies over het toevoegen van komma's.

U ziet hoe het formulier automatisch een geschikt validatiefoutbericht heeft weergegeven in elk veld met een ongeldige waarde. De fouten worden afgedwongen aan de clientzijde (met behulp van JavaScript en jQuery) en aan de serverzijde (voor het geval een gebruiker JavaScript heeft uitgeschakeld).

Een belangrijk voordeel is dat u geen enkele regel code in de MoviesController klasse of in de Create.cshtml weergave hoeft te wijzigen om deze validatiegebruikersinterface in te schakelen. De controller en weergaven die u eerder in deze zelfstudie hebt gemaakt, hebben automatisch de validatieregels opgehaald die u hebt opgegeven met behulp van validatiekenmerken voor de eigenschappen van de Movie modelklasse. Testvalidatie met behulp van de Edit actiemethode en dezelfde validatie wordt toegepast.

De formuliergegevens worden pas naar de server verzonden als er geen validatiefouten aan de clientzijde zijn. U kunt dit controleren door een onderbrekingspunt in de HTTP Post methode te plaatsen, met behulp van het hulpprogramma Fiddler of de hulpprogramma's voor F12-ontwikkelaars.

Hoe validatie werkt

Je vraagt je misschien af hoe de validatie-UI is gegenereerd zonder dat de code in de controller of views is bijgewerkt. De volgende code toont de twee Create methoden.

// GET: Movies/Create
public IActionResult Create()
{
    return View();
}

// POST: Movies/Create
// To protect from overposting attacks, enable the specific properties you want to bind to.
// For more details, see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("Id,Title,ReleaseDate,Genre,Price,Rating")] Movie movie)
{
    if (ModelState.IsValid)
    {
        _context.Add(movie);
        await _context.SaveChangesAsync();
        return RedirectToAction(nameof(Index));
    }
    return View(movie);
}

De eerste (HTTP GET) Create actiemethode toont het initiële Create-formulier. De tweede ([HttpPost]) versie verwerkt het formulierbericht. Met de tweede Create methode (de [HttpPost] versie) roept ModelState.IsValid op om te controleren of de film validatiefouten heeft. Als u deze methode aanroept, worden alle validatiekenmerken geëvalueerd die zijn toegepast op het object. Als het object validatiefouten bevat, wordt het formulier opnieuw weergegeven met de Create methode. Als er geen fouten zijn, slaat de methode de nieuwe film op in de database. In ons voorbeeld van de film wordt het formulier niet op de server geplaatst wanneer er validatiefouten aan de clientzijde zijn gedetecteerd; de tweede Create methode wordt nooit aangeroepen wanneer er validatiefouten aan de clientzijde zijn. Als u JavaScript uitschakelt in uw browser, wordt clientvalidatie uitgeschakeld en kunt u de HTTP POST-methode CreateModelState.IsValid testen om validatiefouten te detecteren.

U kunt een onderbrekingspunt instellen in de [HttpPost] Create methode en controleren of de methode nooit wordt aangeroepen. Validatie aan de clientzijde verzendt de formuliergegevens niet wanneer er validatiefouten worden gedetecteerd. Als u JavaScript uitschakelt in uw browser en het formulier met fouten indient, wordt het onderbrekingspunt bereikt. U krijgt nog steeds volledige validatie zonder JavaScript.

In de volgende afbeelding ziet u hoe u JavaScript uitschakelt in de Firefox-browser.

Firefox: Schakel op het tabblad Inhoud van Opties het selectievakje Javascript inschakelen uit.

In de volgende afbeelding ziet u hoe u JavaScript uitschakelt in de Chrome-browser.

Google Chrome: Selecteer in de sectie Javascript van inhoudsinstellingen de optie Geen site toestaan Om JavaScript uit te voeren.

Nadat u JavaScript hebt uitgeschakeld, plaatst u ongeldige gegevens en doorloopt u het foutopsporingsprogramma.

Tijdens foutopsporing in een bericht met ongeldige gegevens geeft Intellisense op ModelState.IsValid aan dat de waarde onwaar is.

Een gedeelte van de Create.cshtml weergavesjabloon wordt weergegeven in de volgende markeringen:

<h4>Movie</h4>
<hr />
<div class="row">
    <div class="col-md-4">
        <form asp-action="Create">
            <div asp-validation-summary="ModelOnly" class="text-danger"></div>
            <div class="form-group">
                <label asp-for="Title" class="control-label"></label>
                <input asp-for="Title" class="form-control" />
                <span asp-validation-for="Title" class="text-danger"></span>
            </div>

            @*Markup removed for brevity.*@

De voorgaande markeringen worden gebruikt door de actiemethoden om het oorspronkelijke formulier weer te geven en opnieuw weer te geven in het geval van een fout.

De Helper voor invoertags maakt gebruik van de kenmerken DataAnnotations en produceert HTML-kenmerken die nodig zijn voor jQuery-validatie aan de clientzijde. In de Helper voor validatietags worden validatiefouten weergegeven. Zie Validatie voor meer informatie.

Wat erg leuk is aan deze benadering is dat noch de controller noch de Create weergavesjabloon iets weet over de daadwerkelijke validatieregels die worden afgedwongen of over de specifieke foutberichten die worden weergegeven. De validatieregels en de foutreeksen worden alleen in de Movie klasse opgegeven. Dezelfde validatieregels worden automatisch toegepast op de Edit weergave en eventuele andere weergavesjablonen die u mogelijk maakt om uw model te bewerken.

Wanneer u validatielogica moet wijzigen, kunt u dit op precies één plaats doen door validatiekenmerken toe te voegen aan het model (in dit voorbeeld de Movie klasse). U hoeft zich geen zorgen te maken over verschillende onderdelen van de toepassing die inconsistent zijn met de manier waarop de regels worden afgedwongen. Alle validatielogica wordt op één plaats gedefinieerd en overal gebruikt. Hierdoor blijft de code zeer schoon en is het eenvoudig om de code te onderhouden en te ontwikkelen. En het betekent dat je het DRY-principe volledig respecteert.

DataType-kenmerken gebruiken

Open het Movie.cs bestand en bekijk de Movie klasse. De System.ComponentModel.DataAnnotations naamruimte biedt opmaakkenmerken naast de ingebouwde set validatiekenmerken. We hebben al een DataType opsommingswaarde toegepast op de releasedatum en op de prijsvelden. De volgende code toont de ReleaseDate en Price eigenschappen met het juiste DataType kenmerk.

[Display(Name = "Release Date")]
[DataType(DataType.Date)]
public DateTime ReleaseDate { get; set; }

[Range(1, 100)]
[DataType(DataType.Currency)]
[Column(TypeName = "decimal(18, 2)")]
public decimal Price { get; set; }

De DataType kenmerken bieden alleen hints voor de weergave-engine om de gegevens op te maken en elementen/kenmerken te leveren, zoals <a> voor URL's en <a href="mailto:EmailAddress.com"> voor e-mail. U kunt het RegularExpression kenmerk gebruiken om de indeling van de gegevens te valideren. Het DataType kenmerk wordt gebruikt om een gegevenstype op te geven dat specifieker is dan het intrinsieke type database. Dit zijn geen validatiekenmerken. In dit geval willen we alleen de datum bijhouden, niet de tijd. De DataType opsomming biedt veel gegevenstypen, zoals Datum, Tijd, PhoneNumber, Valuta, EmailAddress en meer. Het DataType kenmerk kan de toepassing ook inschakelen om automatisch typespecifieke functies te bieden. Er kan bijvoorbeeld een mailto: koppeling worden gemaakt voor DataType.EmailAddress, en er kan een datumkiezer worden opgegeven in DataType.Date browsers die HTML5 ondersteunen. De DataType kenmerken verzenden HTML 5 data- -kenmerken (uitgesproken als gegevensstreepje) die HTML 5-browsers kunnen begrijpen. De DataType kenmerken bieden geen validatie.

DataType.Date specificeert niet het formaat van de datum die wordt weergegeven. Het gegevensveld wordt standaard weergegeven volgens de standaardformaten gebaseerd op de serverinstellingen CultureInfo.

Het DisplayFormat kenmerk wordt gebruikt om expliciet de datumnotatie op te geven:

[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime ReleaseDate { get; set; }

De ApplyFormatInEditMode instelling geeft aan dat de opmaak ook moet worden toegepast wanneer de waarde wordt weergegeven in een tekstvak voor bewerking. (Mogelijk wilt u dit niet voor sommige velden, bijvoorbeeld voor valutawaarden, wilt u waarschijnlijk niet dat het valutasymbool in het tekstvak wordt bewerkt.)

U kunt het DisplayFormat kenmerk zelf gebruiken, maar het is over het algemeen een goed idee om het DataType kenmerk te gebruiken. Het DataType kenmerk geeft de semantiek van de gegevens weer in plaats van hoe u deze op een scherm weergeeft en biedt de volgende voordelen die u niet krijgt met DisplayFormat:

  • De browser kan HTML5-functies inschakelen (bijvoorbeeld om een agendabesturingselement weer te geven, het valutasymbool dat geschikt is voor landinstellingen, e-mailkoppelingen, enzovoort)

  • Standaard worden in de browser gegevens weergegeven met de juiste indeling op basis van uw landinstelling.

  • Het DataType kenmerk kan MVC inschakelen om de juiste veldsjabloon te kiezen om de gegevens weer te geven (de DisplayFormat als deze door zichzelf wordt gebruikt, wordt de tekenreekssjabloon gebruikt).

Opmerking

jQuery-validatie werkt niet met het Range kenmerk en DateTime. Met de volgende code wordt bijvoorbeeld altijd een validatiefout aan de clientzijde weergegeven, zelfs wanneer de datum zich in het opgegeven bereik bevindt:

[Range(typeof(DateTime), "1/1/1966", "1/1/2020")]

Je moet jQuery-datumvalidatie deactiveren om het Range kenmerk te gebruiken met DateTime. Het is over het algemeen geen goede gewoonte om harde datums in uw modellen te compileren, dus het gebruik van het Range kenmerk en DateTime wordt afgeraden.

De volgende code toont het combineren van kenmerken op één regel:

using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

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

        [StringLength(60, MinimumLength = 3)]
        public string Title { get; set; }

        [Display(Name = "Release Date"), DataType(DataType.Date)]
        public DateTime ReleaseDate { get; set; }

        [RegularExpression(@"^[A-Z]+[a-zA-Z\s]*$"), Required, StringLength(30)]
        public string Genre { get; set; }

        [Range(1, 100), DataType(DataType.Currency)]
        [Column(TypeName = "decimal(18, 2)")]
        public decimal Price { get; set; }

        [RegularExpression(@"^[A-Z]+[a-zA-Z0-9""'\s-]*$"), StringLength(5)]
        public string Rating { get; set; }
    }
}

In het volgende deel van de reeks bekijken we de app en brengen we enkele verbeteringen aan in de automatisch gegenereerde Details en Delete methoden.

Aanvullende bronnen

In deze sectie:

  • Validatielogica wordt toegevoegd aan het Movie model.
  • U zorgt ervoor dat de validatieregels worden afgedwongen wanneer een gebruiker een film maakt of bewerkt.

Alles droog houden

Een van de ontwerpprincipes van MVC is DRY ('Don't Repeat Yourself'). ASP.NET Core MVC moedigt u aan om slechts één keer functionaliteit of gedrag op te geven en deze vervolgens overal in een app te laten zien. Dit vermindert de hoeveelheid code die u moet schrijven en maakt de code die u doet minder foutgevoelig, gemakkelijker te testen en gemakkelijker te onderhouden.

De validatieondersteuning van MVC en Entity Framework Core Code First is een goed voorbeeld van het DRY-principe in actie. U kunt declaratief validatieregels opgeven op één plaats (in de modelklasse) en de regels worden overal in de app afgedwongen.

Validatieregels toevoegen aan het filmmodel

De naamruimte DataAnnotations biedt een set ingebouwde validatiekenmerken die declaratief worden toegepast op een klasse of eigenschap. DataAnnotations bevat ook opmaakkenmerken zoals DataType die helpen bij het opmaken en bieden geen validatie.

Werk de Movie klasse bij om te profiteren van de ingebouwde Required, StringLengthen RegularExpressionRange validatiekenmerken.

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

    [StringLength(60, MinimumLength = 3)]
    [Required]
    public string Title { get; set; }

    [Display(Name = "Release Date")]
    [DataType(DataType.Date)]
    public DateTime ReleaseDate { get; set; }

    [Range(1, 100)]
    [DataType(DataType.Currency)]
    [Column(TypeName = "decimal(18, 2)")]
    public decimal Price { get; set; }

    [RegularExpression(@"^[A-Z]+[a-zA-Z\s]*$")]
    [Required]
    [StringLength(30)]
    public string Genre { get; set; }

    [RegularExpression(@"^[A-Z]+[a-zA-Z0-9""'\s-]*$")]
    [StringLength(5)]
    [Required]
    public string Rating { get; set; }
}

De validatiekenmerken geven het gedrag op dat u wilt afdwingen voor de modeleigenschappen waarop ze worden toegepast:

  • De Required en MinimumLength kenmerken geven aan dat een eigenschap een waarde moet hebben, maar niets voorkomt dat een gebruiker witruimte invoert om aan deze validatie te voldoen.

  • Het kenmerk RegularExpression wordt gebruikt om te beperken welke tekens kunnen worden ingevoerd. In de voorgaande code, "Genre":

    • Mag alleen letters gebruiken.
    • De eerste letter moet een hoofdletter zijn. Spaties zijn toegestaan, terwijl getallen en speciale tekens niet zijn toegestaan.
  • De RegularExpression "Beoordeling":

    • Vereist dat het eerste teken een hoofdletter is.
    • Hiermee worden speciale tekens en nummers toegestaan in achtereenvolgende spaties. "PG-13" is geldig voor een beoordeling, maar is niet geschikt voor een genre.
  • Het Range kenmerk beperkt een waarde tot binnen een opgegeven bereik.

  • StringLength Met het kenmerk kunt u de maximale lengte van een tekenreekseigenschap en eventueel de minimale lengte instellen.

  • Waardetypen (zoals decimal, int, float, ) DateTimezijn inherent vereist en hebben het [Required] kenmerk niet nodig.

Door validatieregels automatisch af te dwingen door ASP.NET Core, kunt u uw app robuuster maken. Het zorgt er ook voor dat u niet kunt vergeten om iets te valideren en per ongeluk slechte gegevens in de database toe te staan.

Validatiefout Gebruikersinterface

Voer de app uit en navigeer naar de Films-controller.

Tik op de koppeling Nieuwe maken om een nieuwe film toe te voegen. Vul het formulier in met een aantal ongeldige waarden. Zodra de jQuery-clientvalidatie de fout detecteert, wordt er een foutbericht weergegeven.

Formulier voor filmweergave met meerdere validatiefouten aan de clientzijde van jQuery

Opmerking

Mogelijk kunt u geen decimale komma's invoeren in decimale velden. Als u ondersteuning wilt bieden voor jQuery-validatie voor niet-Engelstalige landinstellingen die een komma (",") gebruiken voor een decimaalteken en niet-US-English datumnotaties, moet u stappen uitvoeren om uw app te globaliseren. Zie deze GitHub-opmerking 4076 voor instructies over het toevoegen van komma's.

U ziet hoe het formulier automatisch een geschikt validatiefoutbericht heeft weergegeven in elk veld met een ongeldige waarde. De fouten worden afgedwongen aan de clientzijde (met behulp van JavaScript en jQuery) en aan de serverzijde (voor het geval een gebruiker JavaScript heeft uitgeschakeld).

Een belangrijk voordeel is dat u geen enkele regel code in de MoviesController klasse of in de Create.cshtml weergave hoeft te wijzigen om deze validatiegebruikersinterface in te schakelen. De controller en weergaven die u eerder in deze zelfstudie hebt gemaakt, hebben automatisch de validatieregels opgehaald die u hebt opgegeven met behulp van validatiekenmerken voor de eigenschappen van de Movie modelklasse. Testvalidatie met behulp van de Edit actiemethode en dezelfde validatie wordt toegepast.

De formuliergegevens worden pas naar de server verzonden als er geen validatiefouten aan de clientzijde zijn. U kunt dit controleren door een onderbrekingspunt in de HTTP Post methode te plaatsen, met behulp van het hulpprogramma Fiddler of de hulpprogramma's voor F12-ontwikkelaars.

Hoe validatie werkt

Je vraagt je misschien af hoe de validatie-UI is gegenereerd zonder dat de code in de controller of views is bijgewerkt. De volgende code toont de twee Create methoden.

// GET: Movies/Create
public IActionResult Create()
{
    return View();
}

// POST: Movies/Create
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create(
    [Bind("ID,Title,ReleaseDate,Genre,Price, Rating")] Movie movie)
{
    if (ModelState.IsValid)
    {
        _context.Add(movie);
        await _context.SaveChangesAsync();
        return RedirectToAction("Index");
    }
    return View(movie);
}

De eerste (HTTP GET) Create actiemethode toont het initiële Create-formulier. De tweede ([HttpPost]) versie verwerkt het formulierbericht. Met de tweede Create methode (de [HttpPost] versie) roept ModelState.IsValid op om te controleren of de film validatiefouten heeft. Als u deze methode aanroept, worden alle validatiekenmerken geëvalueerd die zijn toegepast op het object. Als het object validatiefouten bevat, wordt het formulier opnieuw weergegeven met de Create methode. Als er geen fouten zijn, slaat de methode de nieuwe film op in de database. In ons voorbeeld van de film wordt het formulier niet op de server geplaatst wanneer er validatiefouten aan de clientzijde zijn gedetecteerd; de tweede Create methode wordt nooit aangeroepen wanneer er validatiefouten aan de clientzijde zijn. Als u JavaScript uitschakelt in uw browser, wordt clientvalidatie uitgeschakeld en kunt u de HTTP POST-methode CreateModelState.IsValid testen om validatiefouten te detecteren.

U kunt een onderbrekingspunt instellen in de [HttpPost] Create methode en controleren of de methode nooit wordt aangeroepen. Validatie aan de clientzijde verzendt de formuliergegevens niet wanneer er validatiefouten worden gedetecteerd. Als u JavaScript uitschakelt in uw browser en het formulier met fouten indient, wordt het onderbrekingspunt bereikt. U krijgt nog steeds volledige validatie zonder JavaScript.

In de volgende afbeelding ziet u hoe u JavaScript uitschakelt in de Firefox-browser.

Firefox: Schakel op het tabblad Inhoud van Opties het selectievakje Javascript inschakelen uit.

In de volgende afbeelding ziet u hoe u JavaScript uitschakelt in de Chrome-browser.

Google Chrome: Selecteer in de sectie Javascript van inhoudsinstellingen de optie Geen site toestaan Om JavaScript uit te voeren.

Nadat u JavaScript hebt uitgeschakeld, plaatst u ongeldige gegevens en doorloopt u het foutopsporingsprogramma.

Tijdens foutopsporing in een bericht met ongeldige gegevens geeft Intellisense op ModelState.IsValid aan dat de waarde onwaar is.

Het gedeelte van de Create.cshtml weergavesjabloon wordt weergegeven in de volgende markeringen:


<h4>Movie</h4>
<hr />
<div class="row">
    <div class="col-md-4">
        <form asp-action="Create">
            <div asp-validation-summary="ModelOnly" class="text-danger"></div>
            <div class="form-group">
                <label asp-for="Title" class="control-label"></label>
                <input asp-for="Title" class="form-control" />
                <span asp-validation-for="Title" class="text-danger"></span>
            </div>           
       
        @*Markup removed for brevity.*@

De voorgaande markeringen worden gebruikt door de actiemethoden om het oorspronkelijke formulier weer te geven en opnieuw weer te geven in het geval van een fout.

De Helper voor invoertags maakt gebruik van de kenmerken DataAnnotations en produceert HTML-kenmerken die nodig zijn voor jQuery-validatie aan de clientzijde. In de Helper voor validatietags worden validatiefouten weergegeven. Zie Validatie voor meer informatie.

Wat erg leuk is aan deze benadering is dat noch de controller noch de Create weergavesjabloon iets weet over de daadwerkelijke validatieregels die worden afgedwongen of over de specifieke foutberichten die worden weergegeven. De validatieregels en de foutreeksen worden alleen in de Movie klasse opgegeven. Dezelfde validatieregels worden automatisch toegepast op de Edit weergave en eventuele andere weergavesjablonen die u mogelijk maakt om uw model te bewerken.

Wanneer u validatielogica moet wijzigen, kunt u dit op precies één plaats doen door validatiekenmerken toe te voegen aan het model (in dit voorbeeld de Movie klasse). U hoeft zich geen zorgen te maken over verschillende onderdelen van de toepassing die inconsistent zijn met de manier waarop de regels worden afgedwongen. Alle validatielogica wordt op één plaats gedefinieerd en overal gebruikt. Hierdoor blijft de code zeer schoon en is het eenvoudig om de code te onderhouden en te ontwikkelen. En het betekent dat je het DRY-principe volledig respecteert.

DataType-kenmerken gebruiken

Open het Movie.cs bestand en bekijk de Movie klasse. De System.ComponentModel.DataAnnotations naamruimte biedt opmaakkenmerken naast de ingebouwde set validatiekenmerken. We hebben al een DataType opsommingswaarde toegepast op de releasedatum en op de prijsvelden. De volgende code toont de ReleaseDate en Price eigenschappen met het juiste DataType kenmerk.

[Display(Name = "Release Date")]
[DataType(DataType.Date)]
public DateTime ReleaseDate { get; set; }

[Range(1, 100)]
[DataType(DataType.Currency)]
public decimal Price { get; set; }

De DataType kenmerken bieden alleen hints voor de weergave-engine om de gegevens op te maken (en levert elementen/kenmerken zoals <a> voor URL's en <a href="mailto:EmailAddress.com"> voor e-mail. U kunt het RegularExpression kenmerk gebruiken om de indeling van de gegevens te valideren. Het DataType kenmerk wordt gebruikt om een gegevenstype op te geven dat specifieker is dan het intrinsieke type database. Dit zijn geen validatiekenmerken. In dit geval willen we alleen de datum bijhouden, niet de tijd. De DataType opsomming biedt veel gegevenstypen, zoals Datum, Tijd, PhoneNumber, Valuta, EmailAddress en meer. Het DataType kenmerk kan de toepassing ook inschakelen om automatisch typespecifieke functies te bieden. Er kan bijvoorbeeld een mailto: koppeling worden gemaakt voor DataType.EmailAddress, en er kan een datumkiezer worden opgegeven in DataType.Date browsers die HTML5 ondersteunen. De DataType kenmerken verzenden HTML 5 data- -kenmerken (uitgesproken als gegevensstreepje) die HTML 5-browsers kunnen begrijpen. De DataType kenmerken bieden geen validatie.

DataType.Date specificeert niet het formaat van de datum die wordt weergegeven. Het gegevensveld wordt standaard weergegeven volgens de standaardformaten gebaseerd op de serverinstellingen CultureInfo.

Het DisplayFormat kenmerk wordt gebruikt om expliciet de datumnotatie op te geven:

[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime ReleaseDate { get; set; }

De ApplyFormatInEditMode instelling geeft aan dat de opmaak ook moet worden toegepast wanneer de waarde wordt weergegeven in een tekstvak voor bewerking. (Mogelijk wilt u dit niet voor sommige velden, bijvoorbeeld voor valutawaarden, wilt u waarschijnlijk niet dat het valutasymbool in het tekstvak wordt bewerkt.)

U kunt het DisplayFormat kenmerk zelf gebruiken, maar het is over het algemeen een goed idee om het DataType kenmerk te gebruiken. Het DataType kenmerk geeft de semantiek van de gegevens weer in plaats van hoe u deze op een scherm weergeeft en biedt de volgende voordelen die u niet krijgt met DisplayFormat:

  • De browser kan HTML5-functies inschakelen (bijvoorbeeld om een agendabesturingselement weer te geven, het valutasymbool dat geschikt is voor landinstellingen, e-mailkoppelingen, enzovoort)

  • Standaard worden in de browser gegevens weergegeven met de juiste indeling op basis van uw landinstelling.

  • Het DataType kenmerk kan MVC inschakelen om de juiste veldsjabloon te kiezen om de gegevens weer te geven (de DisplayFormat als deze door zichzelf wordt gebruikt, wordt de tekenreekssjabloon gebruikt).

Opmerking

jQuery-validatie werkt niet met het Range kenmerk en DateTime. Met de volgende code wordt bijvoorbeeld altijd een validatiefout aan de clientzijde weergegeven, zelfs wanneer de datum zich in het opgegeven bereik bevindt:

[Range(typeof(DateTime), "1/1/1966", "1/1/2020")]

Je moet jQuery-datumvalidatie deactiveren om het Range kenmerk te gebruiken met DateTime. Het is over het algemeen geen goede gewoonte om harde datums in uw modellen te compileren, dus het gebruik van het Range kenmerk en DateTime wordt afgeraden.

De volgende code toont het combineren van kenmerken op één regel:

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

    [StringLength(60, MinimumLength = 3)]
    public string Title { get; set; }

    [Display(Name = "Release Date"), DataType(DataType.Date)]
    public DateTime ReleaseDate { get; set; }

    [RegularExpression(@"^[A-Z]+[a-zA-Z\s]*$"), Required, StringLength(30)]
    public string Genre { get; set; }

    [Range(1, 100), DataType(DataType.Currency)]
    [Column(TypeName = "decimal(18, 2)")]
    public decimal Price { get; set; }

    [RegularExpression(@"^[A-Z]+[a-zA-Z0-9""'\s-]*$"), StringLength(5)]
    public string Rating { get; set; }
}

In het volgende deel van de reeks bekijken we de app en brengen we enkele verbeteringen aan in de automatisch gegenereerde Details en Delete methoden.

Aanvullende bronnen