Dela via


Del 9, lägg till validering i en ASP.NET Core MVC-app

Anmärkning

Det här är inte den senaste versionen av den här artikeln. För den nuvarande utgåvan, se .NET 9-versionen av den här artikeln .

Varning

Den här versionen av ASP.NET Core stöds inte längre. Mer information finns i supportpolicyn för .NET och .NET Core. För den nuvarande utgåvan, se .NET 9-versionen av den här artikeln .

Viktigt!

Den här informationen gäller en förhandsversionsprodukt som kan ändras avsevärt innan den släpps kommersiellt. Microsoft lämnar inga garantier, uttryckliga eller underförstådda, med avseende på den information som tillhandahålls här.

För den nuvarande utgåvan, se .NET 9-versionen av den här artikeln .

Av Rick Anderson

I detta avsnitt:

  • Valideringslogik läggs till i Movie modellen.
  • Du ser till att verifieringsreglerna tillämpas varje gång en användare skapar eller redigerar en film.

Hålla saker TORRA

En av design grundsatserna i MVC är DRY ("Upprepa inte dig själv"). ASP.NET Core MVC uppmuntrar dig att bara ange funktioner eller beteenden en gång och sedan låta det återspeglas överallt i en app. Detta minskar mängden kod som du behöver skriva och gör koden du skriver mindre felbenägen, enklare att testa och enklare att underhålla.

Valideringsstödet från MVC och Entity Framework Core är ett bra exempel på principen DRY i praktiken. Du kan deklarativt ange verifieringsregler på ett ställe (i modellklassen) och reglerna tillämpas överallt i appen.

Validering i .NET 10

I .NET 10 har api:erna för enhetlig validering flyttats till Microsoft.Extensions.Validation NuGet-paketet. Den här ändringen gör validerings-API:erna tillgängliga utanför ASP.NET Core HTTP-scenarier.

Så här använder du API:erna Microsoft.Extensions.Validation :

  • Lägg till följande paketreferens:

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

    Funktionen är densamma men kräver nu en explicit paketreferens.

  • Registrera valideringstjänster med beroendeinmatning:

    builder.Services.AddValidation();
    

Ta bort tidigare redigerade data

I nästa steg läggs verifieringsregler till som inte tillåter null-värden. Kör appen, navigera till /Movies/Index, ta bort alla listade filmer och stoppa appen. Appen använder startdata nästa gång den körs.

Lägga till valideringsregler i filmmodellen

Namnområdet DataAnnotations innehåller en uppsättning inbyggda valideringsattribut som tillämpas deklarativt på en klass eller egenskap. DataAnnotations innehåller också formateringsattribut som DataType det hjälper till med formatering och ger ingen verifiering.

Movie Uppdatera klassen för att dra nytta av de inbyggda valideringsattributen Required, StringLength, RegularExpressionRange och formateringsattributetDataType.

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

Valideringsattributen anger det beteende som du vill tillämpa på de modellegenskaper som de tillämpas på:

  • Attributen Required och MinimumLength anger att en egenskap måste ha ett värde, men ingenting hindrar en användare från att ange tomt utrymme för att uppfylla den här valideringen.

  • Attributet RegularExpression används för att begränsa vilka tecken som kan matas in. I föregående kod, "Genre":

    • Får endast använda bokstäver.
    • Den första bokstaven måste vara versaler. Siffror och specialtecken är inte tillåtna, medan mellanslag är tillåtna.
  • RegularExpression "Omdöme":

    • Kräver att det första tecknet är versaler.
    • Tillåter specialtecken och siffror i efterföljande mellanrum. "PG-13" är giltig för en klassificering, men inte för en "Genre".
  • Attributet Range begränsar ett värde till inom ett angivet intervall.

  • Med StringLength attributet kan du ange den maximala längden på en strängegenskap och eventuellt dess minsta längd.

  • Värdetyper (till exempel decimal, int, float, DateTime) är av sig själva nödvändiga och behöver inte attributet [Required].

Om valideringsregler tillämpas automatiskt av ASP.NET Core blir din app mer robust. Det säkerställer också att du inte kan glömma att verifiera något och oavsiktligt släppa in felaktiga data i databasen.

Verifieringsfel i användargränssnittet

Kör appen och navigera till kontrollanten Filmer.

Välj länken Skapa ny för att lägga till en ny film. Fyll i formuläret med några ogiltiga värden. Så snart jQuery-verifieringen på klientsidan upptäcker felet visas ett felmeddelande.

Filmvisningsformulär med flera valideringsfel på jQuery-klientsidan

Anmärkning

Du kanske inte kan ange decimaltecken i decimalfält. Om du vill stödja jQuery-validering för språkvarianter som inte är engelska och som använder kommatecken (",") för decimaltecken och datumformat som inte US-English måste du vidta åtgärder för att globalisera din app. Se den här GitHub-kommentaren 4076 för instruktioner om hur du lägger till decimal kommatecken.

Observera hur formuläret automatiskt har renderat ett lämpligt valideringsfelmeddelande i varje fält som innehåller ett ogiltigt värde. Felen framtvingas både på klientsidan (med JavaScript och jQuery) och på serversidan (om en användare har JavaScript inaktiverat).

En viktig fördel är att du inte behövde ändra en enda kodrad i MoviesController klassen eller i Create.cshtml vyn för att aktivera det här valideringsgränssnittet. Kontrollanten och vyerna som du skapade tidigare i den här självstudien hämtade automatiskt de valideringsregler som du angav med hjälp av valideringsattribut på egenskaperna för modellklassen Movie . Testa valideringen med hjälp av Edit åtgärdsmetoden och samma validering tillämpas.

Formulärdata skickas inte till servern förrän det inte finns några verifieringsfel på klientsidan. Du kan kontrollera detta genom att placera en brytpunkt i HTTP Post metoden med hjälp av Fiddler-verktyget eller F12 Developer-verktygen.

Så här fungerar valideringen

Du kanske undrar hur verifieringsgränssnittet genererades utan några uppdateringar av koden i kontrollanten eller vyerna. Följande kod visar de två Create metoderna.

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

Den första åtgärdsmetoden (HTTP GET) Create visar det första skapa-formuläret. Den andra ([HttpPost]) versionen hanterar formulärinlägget. Den andra Create metoden ( [HttpPost] versionen) anropar ModelState.IsValid för att kontrollera om filmen har några valideringsfel. Om du anropar den här metoden utvärderas alla valideringsattribut som har tillämpats på objektet. Om objektet har valideringsfel Create visar metoden formuläret igen. Om det inte finns några fel sparar metoden den nya filmen i databasen. I vårt filmexempel publiceras inte formuläret på servern när det finns valideringsfel på klientsidan. den andra Create metoden anropas aldrig när det finns valideringsfel på klientsidan. Om du inaktiverar JavaScript i webbläsaren inaktiveras klientvalidering och du kan testa HTTP POST-metoden CreateModelState.IsValid för att identifiera eventuella valideringsfel.

Du kan ange en brytpunkt i [HttpPost] Create metoden och kontrollera att metoden aldrig anropas. Verifiering på klientsidan skickar inte formulärdata när valideringsfel upptäcks. Om du inaktiverar JavaScript i din webbläsare och sedan skickar formuläret med fel, kommer brytpunkten att slås. Du får fortfarande fullständig validering utan JavaScript.

Följande bild visar hur du inaktiverar JavaScript i webbläsaren Firefox.

Firefox: Avmarkera kryssrutan Aktivera Javascript på fliken Innehåll i Alternativ.

Följande bild visar hur du inaktiverar JavaScript i Webbläsaren Chrome.

Google Chrome: I avsnittet Javascript i Innehållsinställningar väljer du Tillåt inte att någon webbplats kör JavaScript.

När du har inaktiverat JavaScript publicerar du ogiltiga data och går igenom felsökningsprogrammet.

När du felsöker ett inlägg med ogiltiga data visar Intellisense på ModelState.IsValid att värdet är falskt.

En del av vymallen Create.cshtml visas i följande markering:

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

Den föregående markeringen används av åtgärdsmetoderna för att visa det inledande formuläret och för att visa det igen i händelse av ett fel.

Hjälpverktyget för indatataggen använder attributen DataAnnotations och skapar HTML-attribut som behövs för jQuery-validering på klientsidan. Hjälpen för verifieringstaggen visar valideringsfel. Mer information finns i Validering .

Det som verkligen är trevligt med den här metoden är att varken kontrollanten eller vymallen Create vet något om de faktiska verifieringsregler som tillämpas eller om de specifika felmeddelanden som visas. Verifieringsreglerna och felsträngarna anges endast i Movie klassen. Samma verifieringsregler tillämpas automatiskt på Edit vyn och andra vymallar som du kan skapa som redigerar din modell.

När du behöver ändra valideringslogik kan du göra det på exakt ett ställe genom att lägga till valideringsattribut i modellen (i det här exemplet Movie klassen). Du behöver inte bekymra dig om att olika delar av programmet är inkonsekventa med hur reglerna tillämpas – all valideringslogik definieras på ett och samma ställe och används överallt. Detta håller koden mycket ren och gör det enkelt att underhålla och utvecklas. Och det betyder att du kommer att respektera DRY-principen fullt ut.

Använda DataType-attribut

Movie.cs Öppna filen och granska Movie klassen. Namnområdet System.ComponentModel.DataAnnotations innehåller formateringsattribut utöver den inbyggda uppsättningen valideringsattribut. Vi har redan tillämpat ett DataType uppräkningsvärde på lanseringsdatumet och på prisfälten. Följande kod visar ReleaseDate egenskaperna och Price med lämpligt DataType attribut.

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

Attributen DataType ger bara tips för vymotorn för att formatera data och tillhandahåller element/attribut, till exempel <a> för URL:er och <a href="mailto:EmailAddress.com"> för e-post. Du kan använda attributet RegularExpression för att verifiera dataformatet. Attributet DataType används för att ange en datatyp som är mer specifik än databasens inbyggda typ, de är inte valideringsattribut. I det här fallet vill vi bara hålla reda på datumet, inte tiden. Uppräkning DataType innehåller många datatyper, till exempel datum, tid, telefonnummer, valuta, e-postadress med mera. Attributet DataType kan också göra det möjligt för programmet att automatiskt tillhandahålla typspecifika funktioner. En länk kan till exempel mailto: skapas för DataType.EmailAddress och en datumväljare kan anges för DataType.Date i webbläsare som stöder HTML5. Attributen DataType genererar HTML 5-attribut data- (uttalat datastreck) som HTML 5-webbläsare kan förstå. Attributen DataType tillhandahåller ingen validering.

DataType.Date anger inte formatet för det datum som visas. Som standard visas datafältet enligt standardformaten baserat på serverns CultureInfo.

Attributet DisplayFormat används för att uttryckligen ange datumformatet:

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

Inställningen ApplyFormatInEditMode anger att formateringen också ska användas när värdet visas i en textruta för redigering. (Du kanske inte vill det för vissa fält, till exempel för valutavärden, du vill förmodligen inte ha valutasymbolen i textrutan för redigering.)

Du kan använda DisplayFormat attributet självt, men det är vanligtvis en bra idé att använda attributet DataType . Attributet DataType förmedlar semantiken för data i stället för hur du renderar dem på en skärm och ger följande fördelar som du inte får med DisplayFormat:

  • Webbläsaren kan aktivera HTML5-funktioner (till exempel för att visa en kalenderkontroll, språkanpassad valutasymbol, e-postlänkar osv.)

  • Som standard renderar webbläsaren data med rätt format baserat på dina nationella inställningar.

  • Attributet DataType kan göra det möjligt för MVC att välja rätt fältmall för att återge data (om det DisplayFormat används av sig själv använder strängmallen).

Anmärkning

jQuery-validering fungerar inte med attributet Range och DateTime. Följande kod visar till exempel alltid ett verifieringsfel på klientsidan, även när datumet ligger inom det angivna intervallet:

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

Du måste inaktivera jQuery-datumverifiering för att använda Range attributet med DateTime. Det är vanligtvis inte en bra idé att kompilera hårda datum i dina modeller, så att använda Range attributet och DateTime rekommenderas inte.

Följande kod visar hur du kombinerar attribut på en rad:

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

I nästa del av serien granskar vi appen och gör några förbättringar av de automatiskt genererade Details metoderna och Delete metoderna.

Ytterligare resurser

I detta avsnitt:

  • Valideringslogik läggs till i Movie modellen.
  • Du ser till att verifieringsreglerna tillämpas varje gång en användare skapar eller redigerar en film.

Hålla saker TORRA

En av design grundsatserna i MVC är DRY ("Upprepa inte dig själv"). ASP.NET Core MVC uppmuntrar dig att bara ange funktioner eller beteenden en gång och sedan låta det återspeglas överallt i en app. Detta minskar mängden kod som du behöver skriva och gör koden du skriver mindre felbenägen, enklare att testa och enklare att underhålla.

Valideringsstödet från MVC och Entity Framework Core Code First är ett bra exempel på principen DRY i praktiken. Du kan deklarativt ange verifieringsregler på ett ställe (i modellklassen) och reglerna tillämpas överallt i appen.

Ta bort tidigare redigerade data

I nästa steg läggs verifieringsregler till som inte tillåter null-värden. Kör appen, navigera till /Movies/Index, ta bort alla listade filmer och stoppa appen. Appen använder startdata nästa gång den körs.

Lägga till valideringsregler i filmmodellen

Namnområdet DataAnnotations innehåller en uppsättning inbyggda valideringsattribut som tillämpas deklarativt på en klass eller egenskap. DataAnnotations innehåller också formateringsattribut som DataType det hjälper till med formatering och ger ingen verifiering.

Movie Uppdatera klassen för att dra nytta av de inbyggda valideringsattributen Required, StringLength, RegularExpressionRange och formateringsattributetDataType.

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

Valideringsattributen anger det beteende som du vill tillämpa på de modellegenskaper som de tillämpas på:

  • Attributen Required och MinimumLength anger att en egenskap måste ha ett värde, men ingenting hindrar en användare från att ange tomt utrymme för att uppfylla den här valideringen.

  • Attributet RegularExpression används för att begränsa vilka tecken som kan matas in. I föregående kod, "Genre":

    • Får endast använda bokstäver.
    • Den första bokstaven måste vara versaler. Siffror och specialtecken är inte tillåtna, medan mellanslag är tillåtna.
  • RegularExpression "Omdöme":

    • Kräver att det första tecknet är versaler.
    • Tillåter specialtecken och siffror i efterföljande mellanrum. "PG-13" är giltig för en klassificering, men inte för en "Genre".
  • Attributet Range begränsar ett värde till inom ett angivet intervall.

  • Med StringLength attributet kan du ange den maximala längden på en strängegenskap och eventuellt dess minsta längd.

  • Värdetyper (till exempel decimal, int, float, DateTime) är av sig själva nödvändiga och behöver inte attributet [Required].

Om valideringsregler tillämpas automatiskt av ASP.NET Core blir din app mer robust. Det säkerställer också att du inte kan glömma att verifiera något och oavsiktligt släppa in felaktiga data i databasen.

Verifieringsfel i användargränssnittet

Kör appen och navigera till kontrollanten Filmer.

Välj länken Skapa ny för att lägga till en ny film. Fyll i formuläret med några ogiltiga värden. Så snart jQuery-verifieringen på klientsidan upptäcker felet visas ett felmeddelande.

Filmvisningsformulär med flera valideringsfel på jQuery-klientsidan

Anmärkning

Du kanske inte kan ange decimaltecken i decimalfält. Om du vill stödja jQuery-validering för språkvarianter som inte är engelska och som använder kommatecken (",") för decimaltecken och datumformat som inte US-English måste du vidta åtgärder för att globalisera din app. Se den här GitHub-kommentaren 4076 för instruktioner om hur du lägger till decimal kommatecken.

Observera hur formuläret automatiskt har renderat ett lämpligt valideringsfelmeddelande i varje fält som innehåller ett ogiltigt värde. Felen framtvingas både på klientsidan (med JavaScript och jQuery) och på serversidan (om en användare har JavaScript inaktiverat).

En viktig fördel är att du inte behövde ändra en enda kodrad i MoviesController klassen eller i Create.cshtml vyn för att aktivera det här valideringsgränssnittet. Kontrollanten och vyerna som du skapade tidigare i den här självstudien hämtade automatiskt de valideringsregler som du angav med hjälp av valideringsattribut på egenskaperna för modellklassen Movie . Testa valideringen med hjälp av Edit åtgärdsmetoden och samma validering tillämpas.

Formulärdata skickas inte till servern förrän det inte finns några verifieringsfel på klientsidan. Du kan kontrollera detta genom att placera en brytpunkt i HTTP Post metoden med hjälp av Fiddler-verktyget eller F12 Developer-verktygen.

Så här fungerar valideringen

Du kanske undrar hur verifieringsgränssnittet genererades utan några uppdateringar av koden i kontrollanten eller vyerna. Följande kod visar de två Create metoderna.

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

Den första åtgärdsmetoden (HTTP GET) Create visar det första skapa-formuläret. Den andra ([HttpPost]) versionen hanterar formulärinlägget. Den andra Create metoden ( [HttpPost] versionen) anropar ModelState.IsValid för att kontrollera om filmen har några valideringsfel. Om du anropar den här metoden utvärderas alla valideringsattribut som har tillämpats på objektet. Om objektet har valideringsfel Create visar metoden formuläret igen. Om det inte finns några fel sparar metoden den nya filmen i databasen. I vårt filmexempel publiceras inte formuläret på servern när det finns valideringsfel på klientsidan. den andra Create metoden anropas aldrig när det finns valideringsfel på klientsidan. Om du inaktiverar JavaScript i webbläsaren inaktiveras klientvalidering och du kan testa HTTP POST-metoden CreateModelState.IsValid för att identifiera eventuella valideringsfel.

Du kan ange en brytpunkt i [HttpPost] Create metoden och kontrollera att metoden aldrig anropas. Verifiering på klientsidan skickar inte formulärdata när valideringsfel upptäcks. Om du inaktiverar JavaScript i din webbläsare och sedan skickar formuläret med fel, kommer brytpunkten att slås. Du får fortfarande fullständig validering utan JavaScript.

Följande bild visar hur du inaktiverar JavaScript i webbläsaren Firefox.

Firefox: Avmarkera kryssrutan Aktivera Javascript på fliken Innehåll i Alternativ.

Följande bild visar hur du inaktiverar JavaScript i Webbläsaren Chrome.

Google Chrome: I avsnittet Javascript i Innehållsinställningar väljer du Tillåt inte att någon webbplats kör JavaScript.

När du har inaktiverat JavaScript publicerar du ogiltiga data och går igenom felsökningsprogrammet.

När du felsöker ett inlägg med ogiltiga data visar Intellisense på ModelState.IsValid att värdet är falskt.

En del av vymallen Create.cshtml visas i följande markering:

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

Den föregående markeringen används av åtgärdsmetoderna för att visa det inledande formuläret och för att visa det igen i händelse av ett fel.

Hjälpverktyget för indatataggen använder attributen DataAnnotations och skapar HTML-attribut som behövs för jQuery-validering på klientsidan. Hjälpen för verifieringstaggen visar valideringsfel. Mer information finns i Validering .

Det som verkligen är trevligt med den här metoden är att varken kontrollanten eller vymallen Create vet något om de faktiska verifieringsregler som tillämpas eller om de specifika felmeddelanden som visas. Verifieringsreglerna och felsträngarna anges endast i Movie klassen. Samma verifieringsregler tillämpas automatiskt på Edit vyn och andra vymallar som du kan skapa som redigerar din modell.

När du behöver ändra valideringslogik kan du göra det på exakt ett ställe genom att lägga till valideringsattribut i modellen (i det här exemplet Movie klassen). Du behöver inte bekymra dig om att olika delar av programmet är inkonsekventa med hur reglerna tillämpas – all valideringslogik definieras på ett och samma ställe och används överallt. Detta håller koden mycket ren och gör det enkelt att underhålla och utvecklas. Och det betyder att du kommer att respektera DRY-principen fullt ut.

Använda DataType-attribut

Movie.cs Öppna filen och granska Movie klassen. Namnområdet System.ComponentModel.DataAnnotations innehåller formateringsattribut utöver den inbyggda uppsättningen valideringsattribut. Vi har redan tillämpat ett DataType uppräkningsvärde på lanseringsdatumet och på prisfälten. Följande kod visar ReleaseDate egenskaperna och Price med lämpligt DataType attribut.

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

Attributen DataType ger bara tips för vymotorn för att formatera data och tillhandahåller element/attribut, till exempel <a> för URL:er och <a href="mailto:EmailAddress.com"> för e-post. Du kan använda attributet RegularExpression för att verifiera dataformatet. Attributet DataType används för att ange en datatyp som är mer specifik än databasens inbyggda typ, de är inte valideringsattribut. I det här fallet vill vi bara hålla reda på datumet, inte tiden. Uppräkning DataType innehåller många datatyper, till exempel datum, tid, telefonnummer, valuta, e-postadress med mera. Attributet DataType kan också göra det möjligt för programmet att automatiskt tillhandahålla typspecifika funktioner. En länk kan till exempel mailto: skapas för DataType.EmailAddress och en datumväljare kan anges för DataType.Date i webbläsare som stöder HTML5. Attributen DataType genererar HTML 5-attribut data- (uttalat datastreck) som HTML 5-webbläsare kan förstå. Attributen DataType tillhandahåller ingen validering.

DataType.Date anger inte formatet för det datum som visas. Som standard visas datafältet enligt standardformaten baserat på serverns CultureInfo.

Attributet DisplayFormat används för att uttryckligen ange datumformatet:

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

Inställningen ApplyFormatInEditMode anger att formateringen också ska användas när värdet visas i en textruta för redigering. (Du kanske inte vill det för vissa fält, till exempel för valutavärden, du vill förmodligen inte ha valutasymbolen i textrutan för redigering.)

Du kan använda DisplayFormat attributet självt, men det är vanligtvis en bra idé att använda attributet DataType . Attributet DataType förmedlar semantiken för data i stället för hur du renderar dem på en skärm och ger följande fördelar som du inte får med DisplayFormat:

  • Webbläsaren kan aktivera HTML5-funktioner (till exempel för att visa en kalenderkontroll, språkanpassad valutasymbol, e-postlänkar osv.)

  • Som standard renderar webbläsaren data med rätt format baserat på dina nationella inställningar.

  • Attributet DataType kan göra det möjligt för MVC att välja rätt fältmall för att återge data (om det DisplayFormat används av sig själv använder strängmallen).

Anmärkning

jQuery-validering fungerar inte med attributet Range och DateTime. Följande kod visar till exempel alltid ett verifieringsfel på klientsidan, även när datumet ligger inom det angivna intervallet:

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

Du måste inaktivera jQuery-datumverifiering för att använda Range attributet med DateTime. Det är vanligtvis inte en bra idé att kompilera hårda datum i dina modeller, så att använda Range attributet och DateTime rekommenderas inte.

Följande kod visar hur du kombinerar attribut på en rad:

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

I nästa del av serien granskar vi appen och gör några förbättringar av de automatiskt genererade Details metoderna och Delete metoderna.

Ytterligare resurser

I detta avsnitt:

  • Valideringslogik läggs till i Movie modellen.
  • Du ser till att verifieringsreglerna tillämpas varje gång en användare skapar eller redigerar en film.

Hålla saker TORRA

En av design grundsatserna i MVC är DRY ("Upprepa inte dig själv"). ASP.NET Core MVC uppmuntrar dig att bara ange funktioner eller beteenden en gång och sedan låta det återspeglas överallt i en app. Detta minskar mängden kod som du behöver skriva och gör koden du skriver mindre felbenägen, enklare att testa och enklare att underhålla.

Valideringsstödet från MVC och Entity Framework Core Code First är ett bra exempel på principen DRY i praktiken. Du kan deklarativt ange verifieringsregler på ett ställe (i modellklassen) och reglerna tillämpas överallt i appen.

Lägga till valideringsregler i filmmodellen

Namnområdet DataAnnotations innehåller en uppsättning inbyggda valideringsattribut som tillämpas deklarativt på en klass eller egenskap. DataAnnotations innehåller också formateringsattribut som DataType det hjälper till med formatering och ger ingen verifiering.

Movie Uppdatera klassen för att dra nytta av de inbyggda valideringsattributen Required, StringLength, RegularExpressionRange och formateringsattributetDataType.

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

Valideringsattributen anger det beteende som du vill tillämpa på de modellegenskaper som de tillämpas på:

  • Attributen Required och MinimumLength anger att en egenskap måste ha ett värde, men ingenting hindrar en användare från att ange tomt utrymme för att uppfylla den här valideringen.

  • Attributet RegularExpression används för att begränsa vilka tecken som kan matas in. I föregående kod, "Genre":

    • Får endast använda bokstäver.
    • Den första bokstaven måste vara versaler. Siffror och specialtecken är inte tillåtna, medan mellanslag är tillåtna.
  • RegularExpression "Omdöme":

    • Kräver att det första tecknet är versaler.
    • Tillåter specialtecken och siffror i efterföljande mellanrum. "PG-13" är giltig för en klassificering, men inte för en "Genre".
  • Attributet Range begränsar ett värde till inom ett angivet intervall.

  • Med StringLength attributet kan du ange den maximala längden på en strängegenskap och eventuellt dess minsta längd.

  • Värdetyper (till exempel decimal, int, float, DateTime) är av sig själva nödvändiga och behöver inte attributet [Required].

Om valideringsregler tillämpas automatiskt av ASP.NET Core blir din app mer robust. Det säkerställer också att du inte kan glömma att verifiera något och oavsiktligt släppa in felaktiga data i databasen.

Verifieringsfel i användargränssnittet

Kör appen och navigera till kontrollanten Filmer.

Välj länken Skapa ny för att lägga till en ny film. Fyll i formuläret med några ogiltiga värden. Så snart jQuery-verifieringen på klientsidan upptäcker felet visas ett felmeddelande.

Filmvisningsformulär med flera valideringsfel på jQuery-klientsidan

Anmärkning

Du kanske inte kan ange decimaltecken i decimalfält. Om du vill stödja jQuery-validering för språkvarianter som inte är engelska och som använder kommatecken (",") för decimaltecken och datumformat som inte US-English måste du vidta åtgärder för att globalisera din app. Se den här GitHub-kommentaren 4076 för instruktioner om hur du lägger till decimal kommatecken.

Observera hur formuläret automatiskt har renderat ett lämpligt valideringsfelmeddelande i varje fält som innehåller ett ogiltigt värde. Felen framtvingas både på klientsidan (med JavaScript och jQuery) och på serversidan (om en användare har JavaScript inaktiverat).

En viktig fördel är att du inte behövde ändra en enda kodrad i MoviesController klassen eller i Create.cshtml vyn för att aktivera det här valideringsgränssnittet. Kontrollanten och vyerna som du skapade tidigare i den här självstudien hämtade automatiskt de valideringsregler som du angav med hjälp av valideringsattribut på egenskaperna för modellklassen Movie . Testa valideringen med hjälp av Edit åtgärdsmetoden och samma validering tillämpas.

Formulärdata skickas inte till servern förrän det inte finns några verifieringsfel på klientsidan. Du kan kontrollera detta genom att placera en brytpunkt i HTTP Post metoden med hjälp av Fiddler-verktyget eller F12 Developer-verktygen.

Så här fungerar valideringen

Du kanske undrar hur verifieringsgränssnittet genererades utan några uppdateringar av koden i kontrollanten eller vyerna. Följande kod visar de två Create metoderna.

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

Den första åtgärdsmetoden (HTTP GET) Create visar det första skapa-formuläret. Den andra ([HttpPost]) versionen hanterar formulärinlägget. Den andra Create metoden ( [HttpPost] versionen) anropar ModelState.IsValid för att kontrollera om filmen har några valideringsfel. Om du anropar den här metoden utvärderas alla valideringsattribut som har tillämpats på objektet. Om objektet har valideringsfel Create visar metoden formuläret igen. Om det inte finns några fel sparar metoden den nya filmen i databasen. I vårt filmexempel publiceras inte formuläret på servern när det finns valideringsfel på klientsidan. den andra Create metoden anropas aldrig när det finns valideringsfel på klientsidan. Om du inaktiverar JavaScript i webbläsaren inaktiveras klientvalidering och du kan testa HTTP POST-metoden CreateModelState.IsValid för att identifiera eventuella valideringsfel.

Du kan ange en brytpunkt i [HttpPost] Create metoden och kontrollera att metoden aldrig anropas. Verifiering på klientsidan skickar inte formulärdata när valideringsfel upptäcks. Om du inaktiverar JavaScript i din webbläsare och sedan skickar formuläret med fel, kommer brytpunkten att slås. Du får fortfarande fullständig validering utan JavaScript.

Följande bild visar hur du inaktiverar JavaScript i webbläsaren Firefox.

Firefox: Avmarkera kryssrutan Aktivera Javascript på fliken Innehåll i Alternativ.

Följande bild visar hur du inaktiverar JavaScript i Webbläsaren Chrome.

Google Chrome: I avsnittet Javascript i Innehållsinställningar väljer du Tillåt inte att någon webbplats kör JavaScript.

När du har inaktiverat JavaScript publicerar du ogiltiga data och går igenom felsökningsprogrammet.

När du felsöker ett inlägg med ogiltiga data visar Intellisense på ModelState.IsValid att värdet är falskt.

En del av vymallen Create.cshtml visas i följande markering:

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

Den föregående markeringen används av åtgärdsmetoderna för att visa det inledande formuläret och för att visa det igen i händelse av ett fel.

Hjälpverktyget för indatataggen använder attributen DataAnnotations och skapar HTML-attribut som behövs för jQuery-validering på klientsidan. Hjälpen för verifieringstaggen visar valideringsfel. Mer information finns i Validering .

Det som verkligen är trevligt med den här metoden är att varken kontrollanten eller vymallen Create vet något om de faktiska verifieringsregler som tillämpas eller om de specifika felmeddelanden som visas. Verifieringsreglerna och felsträngarna anges endast i Movie klassen. Samma verifieringsregler tillämpas automatiskt på Edit vyn och andra vymallar som du kan skapa som redigerar din modell.

När du behöver ändra valideringslogik kan du göra det på exakt ett ställe genom att lägga till valideringsattribut i modellen (i det här exemplet Movie klassen). Du behöver inte bekymra dig om att olika delar av programmet är inkonsekventa med hur reglerna tillämpas – all valideringslogik definieras på ett och samma ställe och används överallt. Detta håller koden mycket ren och gör det enkelt att underhålla och utvecklas. Och det betyder att du kommer att respektera DRY-principen fullt ut.

Använda DataType-attribut

Movie.cs Öppna filen och granska Movie klassen. Namnområdet System.ComponentModel.DataAnnotations innehåller formateringsattribut utöver den inbyggda uppsättningen valideringsattribut. Vi har redan tillämpat ett DataType uppräkningsvärde på lanseringsdatumet och på prisfälten. Följande kod visar ReleaseDate egenskaperna och Price med lämpligt DataType attribut.

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

Attributen DataType ger bara tips för vymotorn för att formatera data och tillhandahåller element/attribut, till exempel <a> för URL:er och <a href="mailto:EmailAddress.com"> för e-post. Du kan använda attributet RegularExpression för att verifiera dataformatet. Attributet DataType används för att ange en datatyp som är mer specifik än databasens inbyggda typ, de är inte valideringsattribut. I det här fallet vill vi bara hålla reda på datumet, inte tiden. Uppräkning DataType innehåller många datatyper, till exempel datum, tid, telefonnummer, valuta, e-postadress med mera. Attributet DataType kan också göra det möjligt för programmet att automatiskt tillhandahålla typspecifika funktioner. En länk kan till exempel mailto: skapas för DataType.EmailAddress och en datumväljare kan anges för DataType.Date i webbläsare som stöder HTML5. Attributen DataType genererar HTML 5-attribut data- (uttalat datastreck) som HTML 5-webbläsare kan förstå. Attributen DataType tillhandahåller ingen validering.

DataType.Date anger inte formatet för det datum som visas. Som standard visas datafältet enligt standardformaten baserat på serverns CultureInfo.

Attributet DisplayFormat används för att uttryckligen ange datumformatet:

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

Inställningen ApplyFormatInEditMode anger att formateringen också ska användas när värdet visas i en textruta för redigering. (Du kanske inte vill det för vissa fält, till exempel för valutavärden, du vill förmodligen inte ha valutasymbolen i textrutan för redigering.)

Du kan använda DisplayFormat attributet självt, men det är vanligtvis en bra idé att använda attributet DataType . Attributet DataType förmedlar semantiken för data i stället för hur du renderar dem på en skärm och ger följande fördelar som du inte får med DisplayFormat:

  • Webbläsaren kan aktivera HTML5-funktioner (till exempel för att visa en kalenderkontroll, språkanpassad valutasymbol, e-postlänkar osv.)

  • Som standard renderar webbläsaren data med rätt format baserat på dina nationella inställningar.

  • Attributet DataType kan göra det möjligt för MVC att välja rätt fältmall för att återge data (om det DisplayFormat används av sig själv använder strängmallen).

Anmärkning

jQuery-validering fungerar inte med attributet Range och DateTime. Följande kod visar till exempel alltid ett verifieringsfel på klientsidan, även när datumet ligger inom det angivna intervallet:

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

Du måste inaktivera jQuery-datumverifiering för att använda Range attributet med DateTime. Det är vanligtvis inte en bra idé att kompilera hårda datum i dina modeller, så att använda Range attributet och DateTime rekommenderas inte.

Följande kod visar hur du kombinerar attribut på en rad:

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

I nästa del av serien granskar vi appen och gör några förbättringar av de automatiskt genererade Details metoderna och Delete metoderna.

Ytterligare resurser

I detta avsnitt:

  • Valideringslogik läggs till i Movie modellen.
  • Du ser till att verifieringsreglerna tillämpas varje gång en användare skapar eller redigerar en film.

Hålla saker TORRA

En av design grundsatserna i MVC är DRY ("Upprepa inte dig själv"). ASP.NET Core MVC uppmuntrar dig att bara ange funktioner eller beteenden en gång och sedan låta det återspeglas överallt i en app. Detta minskar mängden kod som du behöver skriva och gör koden du skriver mindre felbenägen, enklare att testa och enklare att underhålla.

Valideringsstödet från MVC och Entity Framework Core Code First är ett bra exempel på principen DRY i praktiken. Du kan deklarativt ange verifieringsregler på ett ställe (i modellklassen) och reglerna tillämpas överallt i appen.

Lägga till valideringsregler i filmmodellen

Namnområdet DataAnnotations innehåller en uppsättning inbyggda valideringsattribut som tillämpas deklarativt på en klass eller egenskap. DataAnnotations innehåller också formateringsattribut som DataType det hjälper till med formatering och ger ingen verifiering.

Movie Uppdatera klassen för att dra nytta av de inbyggda Required, StringLength, RegularExpressionoch Range valideringsattributen.

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

Valideringsattributen anger det beteende som du vill tillämpa på de modellegenskaper som de tillämpas på:

  • Attributen Required och MinimumLength anger att en egenskap måste ha ett värde, men ingenting hindrar en användare från att ange tomt utrymme för att uppfylla den här valideringen.

  • Attributet RegularExpression används för att begränsa vilka tecken som kan matas in. I föregående kod, "Genre":

    • Får endast använda bokstäver.
    • Den första bokstaven måste vara versaler. Siffror och specialtecken är inte tillåtna, medan mellanslag är tillåtna.
  • RegularExpression "Omdöme":

    • Kräver att det första tecknet är versaler.
    • Tillåter specialtecken och siffror i efterföljande mellanrum. "PG-13" är giltig för en klassificering, men inte för en "Genre".
  • Attributet Range begränsar ett värde till inom ett angivet intervall.

  • Med StringLength attributet kan du ange den maximala längden på en strängegenskap och eventuellt dess minsta längd.

  • Värdetyper (till exempel decimal, int, float, DateTime) är av sig själva nödvändiga och behöver inte attributet [Required].

Om valideringsregler tillämpas automatiskt av ASP.NET Core blir din app mer robust. Det säkerställer också att du inte kan glömma att verifiera något och oavsiktligt släppa in felaktiga data i databasen.

Verifieringsfel i användargränssnittet

Kör appen och navigera till kontrollanten Filmer.

Välj länken Skapa ny för att lägga till en ny film. Fyll i formuläret med några ogiltiga värden. Så snart jQuery-verifieringen på klientsidan upptäcker felet visas ett felmeddelande.

Filmvisningsformulär med flera valideringsfel på jQuery-klientsidan

Anmärkning

Du kanske inte kan ange decimaltecken i decimalfält. Om du vill stödja jQuery-validering för språkvarianter som inte är engelska och som använder kommatecken (",") för decimaltecken och datumformat som inte US-English måste du vidta åtgärder för att globalisera din app. Se den här GitHub-kommentaren 4076 för instruktioner om hur du lägger till decimal kommatecken.

Observera hur formuläret automatiskt har renderat ett lämpligt valideringsfelmeddelande i varje fält som innehåller ett ogiltigt värde. Felen framtvingas både på klientsidan (med JavaScript och jQuery) och på serversidan (om en användare har JavaScript inaktiverat).

En viktig fördel är att du inte behövde ändra en enda kodrad i MoviesController klassen eller i Create.cshtml vyn för att aktivera det här valideringsgränssnittet. Kontrollanten och vyerna som du skapade tidigare i den här självstudien hämtade automatiskt de valideringsregler som du angav med hjälp av valideringsattribut på egenskaperna för modellklassen Movie . Testa valideringen med hjälp av Edit åtgärdsmetoden och samma validering tillämpas.

Formulärdata skickas inte till servern förrän det inte finns några verifieringsfel på klientsidan. Du kan kontrollera detta genom att placera en brytpunkt i HTTP Post metoden med hjälp av Fiddler-verktyget eller F12 Developer-verktygen.

Så här fungerar valideringen

Du kanske undrar hur verifieringsgränssnittet genererades utan några uppdateringar av koden i kontrollanten eller vyerna. Följande kod visar de två Create metoderna.

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

Den första åtgärdsmetoden (HTTP GET) Create visar det första skapa-formuläret. Den andra ([HttpPost]) versionen hanterar formulärinlägget. Den andra Create metoden ( [HttpPost] versionen) anropar ModelState.IsValid för att kontrollera om filmen har några valideringsfel. Om du anropar den här metoden utvärderas alla valideringsattribut som har tillämpats på objektet. Om objektet har valideringsfel Create visar metoden formuläret igen. Om det inte finns några fel sparar metoden den nya filmen i databasen. I vårt filmexempel publiceras inte formuläret på servern när det finns valideringsfel på klientsidan. den andra Create metoden anropas aldrig när det finns valideringsfel på klientsidan. Om du inaktiverar JavaScript i webbläsaren inaktiveras klientvalidering och du kan testa HTTP POST-metoden CreateModelState.IsValid för att identifiera eventuella valideringsfel.

Du kan ange en brytpunkt i [HttpPost] Create metoden och kontrollera att metoden aldrig anropas. Verifiering på klientsidan skickar inte formulärdata när valideringsfel upptäcks. Om du inaktiverar JavaScript i din webbläsare och sedan skickar formuläret med fel, kommer brytpunkten att slås. Du får fortfarande fullständig validering utan JavaScript.

Följande bild visar hur du inaktiverar JavaScript i webbläsaren Firefox.

Firefox: Avmarkera kryssrutan Aktivera Javascript på fliken Innehåll i Alternativ.

Följande bild visar hur du inaktiverar JavaScript i Webbläsaren Chrome.

Google Chrome: I avsnittet Javascript i Innehållsinställningar väljer du Tillåt inte att någon webbplats kör JavaScript.

När du har inaktiverat JavaScript publicerar du ogiltiga data och går igenom felsökningsprogrammet.

När du felsöker ett inlägg med ogiltiga data visar Intellisense på ModelState.IsValid att värdet är falskt.

En del av vymallen Create.cshtml visas i följande markering:

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

Den föregående markeringen används av åtgärdsmetoderna för att visa det inledande formuläret och för att visa det igen i händelse av ett fel.

Hjälpverktyget för indatataggen använder attributen DataAnnotations och skapar HTML-attribut som behövs för jQuery-validering på klientsidan. Hjälpen för verifieringstaggen visar valideringsfel. Mer information finns i Validering .

Det som verkligen är trevligt med den här metoden är att varken kontrollanten eller vymallen Create vet något om de faktiska verifieringsregler som tillämpas eller om de specifika felmeddelanden som visas. Verifieringsreglerna och felsträngarna anges endast i Movie klassen. Samma verifieringsregler tillämpas automatiskt på Edit vyn och andra vymallar som du kan skapa som redigerar din modell.

När du behöver ändra valideringslogik kan du göra det på exakt ett ställe genom att lägga till valideringsattribut i modellen (i det här exemplet Movie klassen). Du behöver inte bekymra dig om att olika delar av programmet är inkonsekventa med hur reglerna tillämpas – all valideringslogik definieras på ett och samma ställe och används överallt. Detta håller koden mycket ren och gör det enkelt att underhålla och utvecklas. Och det betyder att du kommer att respektera DRY-principen fullt ut.

Använda DataType-attribut

Movie.cs Öppna filen och granska Movie klassen. Namnområdet System.ComponentModel.DataAnnotations innehåller formateringsattribut utöver den inbyggda uppsättningen valideringsattribut. Vi har redan tillämpat ett DataType uppräkningsvärde på lanseringsdatumet och på prisfälten. Följande kod visar ReleaseDate egenskaperna och Price med lämpligt DataType attribut.

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

Attributen DataType ger bara tips för vymotorn för att formatera data och tillhandahåller element/attribut, till exempel <a> för URL:er och <a href="mailto:EmailAddress.com"> för e-post. Du kan använda attributet RegularExpression för att verifiera dataformatet. Attributet DataType används för att ange en datatyp som är mer specifik än databasens inbyggda typ, de är inte valideringsattribut. I det här fallet vill vi bara hålla reda på datumet, inte tiden. Uppräkning DataType innehåller många datatyper, till exempel datum, tid, telefonnummer, valuta, e-postadress med mera. Attributet DataType kan också göra det möjligt för programmet att automatiskt tillhandahålla typspecifika funktioner. En länk kan till exempel mailto: skapas för DataType.EmailAddress och en datumväljare kan anges för DataType.Date i webbläsare som stöder HTML5. Attributen DataType genererar HTML 5-attribut data- (uttalat datastreck) som HTML 5-webbläsare kan förstå. Attributen DataType tillhandahåller ingen validering.

DataType.Date anger inte formatet för det datum som visas. Som standard visas datafältet enligt standardformaten baserat på serverns CultureInfo.

Attributet DisplayFormat används för att uttryckligen ange datumformatet:

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

Inställningen ApplyFormatInEditMode anger att formateringen också ska användas när värdet visas i en textruta för redigering. (Du kanske inte vill det för vissa fält, till exempel för valutavärden, du vill förmodligen inte ha valutasymbolen i textrutan för redigering.)

Du kan använda DisplayFormat attributet självt, men det är vanligtvis en bra idé att använda attributet DataType . Attributet DataType förmedlar semantiken för data i stället för hur du renderar dem på en skärm och ger följande fördelar som du inte får med DisplayFormat:

  • Webbläsaren kan aktivera HTML5-funktioner (till exempel för att visa en kalenderkontroll, språkanpassad valutasymbol, e-postlänkar osv.)

  • Som standard renderar webbläsaren data med rätt format baserat på dina nationella inställningar.

  • Attributet DataType kan göra det möjligt för MVC att välja rätt fältmall för att återge data (om det DisplayFormat används av sig själv använder strängmallen).

Anmärkning

jQuery-validering fungerar inte med attributet Range och DateTime. Följande kod visar till exempel alltid ett verifieringsfel på klientsidan, även när datumet ligger inom det angivna intervallet:

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

Du måste inaktivera jQuery-datumverifiering för att använda Range attributet med DateTime. Det är vanligtvis inte en bra idé att kompilera hårda datum i dina modeller, så att använda Range attributet och DateTime rekommenderas inte.

Följande kod visar hur du kombinerar attribut på en rad:

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

I nästa del av serien granskar vi appen och gör några förbättringar av de automatiskt genererade Details metoderna och Delete metoderna.

Ytterligare resurser

I detta avsnitt:

  • Valideringslogik läggs till i Movie modellen.
  • Du ser till att verifieringsreglerna tillämpas varje gång en användare skapar eller redigerar en film.

Hålla saker TORRA

En av design grundsatserna i MVC är DRY ("Upprepa inte dig själv"). ASP.NET Core MVC uppmuntrar dig att bara ange funktioner eller beteenden en gång och sedan låta det återspeglas överallt i en app. Detta minskar mängden kod som du behöver skriva och gör koden du skriver mindre felbenägen, enklare att testa och enklare att underhålla.

Valideringsstödet från MVC och Entity Framework Core Code First är ett bra exempel på principen DRY i praktiken. Du kan deklarativt ange verifieringsregler på ett ställe (i modellklassen) och reglerna tillämpas överallt i appen.

Lägga till valideringsregler i filmmodellen

Namnområdet DataAnnotations innehåller en uppsättning inbyggda valideringsattribut som tillämpas deklarativt på en klass eller egenskap. DataAnnotations innehåller också formateringsattribut som DataType det hjälper till med formatering och ger ingen verifiering.

Movie Uppdatera klassen för att dra nytta av de inbyggda Required, StringLength, RegularExpressionoch Range valideringsattributen.

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

Valideringsattributen anger det beteende som du vill tillämpa på de modellegenskaper som de tillämpas på:

  • Attributen Required och MinimumLength anger att en egenskap måste ha ett värde, men ingenting hindrar en användare från att ange tomt utrymme för att uppfylla den här valideringen.

  • Attributet RegularExpression används för att begränsa vilka tecken som kan matas in. I föregående kod, "Genre":

    • Får endast använda bokstäver.
    • Den första bokstaven måste vara versaler. Mellanslag är tillåtna, medan siffror och specialtecken inte är tillåtna.
  • RegularExpression "Omdöme":

    • Kräver att det första tecknet är versaler.
    • Tillåter specialtecken och siffror i efterföljande mellanrum. "PG-13" är giltig för en klassificering, men inte för en "Genre".
  • Attributet Range begränsar ett värde till inom ett angivet intervall.

  • Med StringLength attributet kan du ange den maximala längden på en strängegenskap och eventuellt dess minsta längd.

  • Värdetyper (till exempel decimal, int, float, DateTime) är av sig själva nödvändiga och behöver inte attributet [Required].

Om valideringsregler tillämpas automatiskt av ASP.NET Core blir din app mer robust. Det säkerställer också att du inte kan glömma att verifiera något och oavsiktligt släppa in felaktiga data i databasen.

Verifieringsfel i användargränssnittet

Kör appen och navigera till kontrollanten Filmer.

Tryck på länken Skapa ny för att lägga till en ny film. Fyll i formuläret med några ogiltiga värden. Så snart jQuery-verifieringen på klientsidan upptäcker felet visas ett felmeddelande.

Filmvisningsformulär med flera valideringsfel på jQuery-klientsidan

Anmärkning

Du kanske inte kan ange decimaltecken i decimalfält. Om du vill stödja jQuery-validering för språkvarianter som inte är engelska och som använder kommatecken (",") för decimaltecken och datumformat som inte US-English måste du vidta åtgärder för att globalisera din app. Se den här GitHub-kommentaren 4076 för instruktioner om hur du lägger till decimal kommatecken.

Observera hur formuläret automatiskt har renderat ett lämpligt valideringsfelmeddelande i varje fält som innehåller ett ogiltigt värde. Felen framtvingas både på klientsidan (med JavaScript och jQuery) och på serversidan (om en användare har JavaScript inaktiverat).

En viktig fördel är att du inte behövde ändra en enda kodrad i MoviesController klassen eller i Create.cshtml vyn för att aktivera det här valideringsgränssnittet. Kontrollanten och vyerna som du skapade tidigare i den här självstudien hämtade automatiskt de valideringsregler som du angav med hjälp av valideringsattribut på egenskaperna för modellklassen Movie . Testa valideringen med hjälp av Edit åtgärdsmetoden och samma validering tillämpas.

Formulärdata skickas inte till servern förrän det inte finns några verifieringsfel på klientsidan. Du kan kontrollera detta genom att placera en brytpunkt i HTTP Post metoden med hjälp av Fiddler-verktyget eller F12 Developer-verktygen.

Så här fungerar valideringen

Du kanske undrar hur verifieringsgränssnittet genererades utan några uppdateringar av koden i kontrollanten eller vyerna. Följande kod visar de två Create metoderna.

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

Den första åtgärdsmetoden (HTTP GET) Create visar det första skapa-formuläret. Den andra ([HttpPost]) versionen hanterar formulärinlägget. Den andra Create metoden ( [HttpPost] versionen) anropar ModelState.IsValid för att kontrollera om filmen har några valideringsfel. Om du anropar den här metoden utvärderas alla valideringsattribut som har tillämpats på objektet. Om objektet har valideringsfel Create visar metoden formuläret igen. Om det inte finns några fel sparar metoden den nya filmen i databasen. I vårt filmexempel publiceras inte formuläret på servern när det finns valideringsfel på klientsidan. den andra Create metoden anropas aldrig när det finns valideringsfel på klientsidan. Om du inaktiverar JavaScript i webbläsaren inaktiveras klientvalidering och du kan testa HTTP POST-metoden CreateModelState.IsValid för att identifiera eventuella valideringsfel.

Du kan ange en brytpunkt i [HttpPost] Create metoden och kontrollera att metoden aldrig anropas. Verifiering på klientsidan skickar inte formulärdata när valideringsfel upptäcks. Om du inaktiverar JavaScript i din webbläsare och sedan skickar formuläret med fel, kommer brytpunkten att slås. Du får fortfarande fullständig validering utan JavaScript.

Följande bild visar hur du inaktiverar JavaScript i webbläsaren Firefox.

Firefox: Avmarkera kryssrutan Aktivera Javascript på fliken Innehåll i Alternativ.

Följande bild visar hur du inaktiverar JavaScript i Webbläsaren Chrome.

Google Chrome: I avsnittet Javascript i Innehållsinställningar väljer du Tillåt inte att någon webbplats kör JavaScript.

När du har inaktiverat JavaScript publicerar du ogiltiga data och går igenom felsökningsprogrammet.

När du felsöker ett inlägg med ogiltiga data visar Intellisense på ModelState.IsValid att värdet är falskt.

Den del av vymallen Create.cshtml som visas i följande markup:


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

Den föregående markeringen används av aktionsmetoderna för att visa det ursprungliga formuläret och för att visa det igen vid ett fel.

Hjälpverktyget för indatataggen använder attributen DataAnnotations och skapar HTML-attribut som behövs för jQuery-validering på klientsidan. Hjälpen för verifieringstaggen visar valideringsfel. Mer information finns i Validering .

Det som verkligen är trevligt med den här metoden är att varken kontrollanten eller vymallen Create vet något om de faktiska verifieringsregler som tillämpas eller om de specifika felmeddelanden som visas. Verifieringsreglerna och felsträngarna anges endast i Movie klassen. Samma verifieringsregler tillämpas automatiskt på Edit vyn och andra vymallar som du kan skapa som redigerar din modell.

När du behöver ändra valideringslogik kan du göra det på exakt ett ställe genom att lägga till valideringsattribut i modellen (i det här exemplet Movie klassen). Du behöver inte bekymra dig om att olika delar av programmet är inkonsekventa med hur reglerna tillämpas – all valideringslogik definieras på ett och samma ställe och används överallt. Detta håller koden mycket ren och gör det enkelt att underhålla och utvecklas. Och det betyder att du kommer att respektera DRY-principen fullt ut.

Använda DataType-attribut

Movie.cs Öppna filen och granska Movie klassen. Namnområdet System.ComponentModel.DataAnnotations innehåller formateringsattribut utöver den inbyggda uppsättningen valideringsattribut. Vi har redan tillämpat ett DataType uppräkningsvärde på lanseringsdatumet och på prisfälten. Följande kod visar ReleaseDate egenskaperna och Price med lämpligt DataType attribut.

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

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

Attributen DataType ger bara tips för vymotorn för att formatera data (och tillhandahåller element/attribut, till exempel <a> för URL:er och <a href="mailto:EmailAddress.com"> för e-post. Du kan använda attributet RegularExpression för att verifiera dataformatet. Attributet DataType används för att ange en datatyp som är mer specifik än databasens inbyggda typ, de är inte valideringsattribut. I det här fallet vill vi bara hålla reda på datumet, inte tiden. Uppräkning DataType innehåller många datatyper, till exempel datum, tid, telefonnummer, valuta, e-postadress med mera. Attributet DataType kan också göra det möjligt för programmet att automatiskt tillhandahålla typspecifika funktioner. En länk kan till exempel mailto: skapas för DataType.EmailAddress och en datumväljare kan tillhandahållas för DataType.Date i webbläsare som stöder HTML5. Attributen DataType genererar HTML 5-attribut data- (uttalat datastreck) som HTML 5-webbläsare kan förstå. Attributen DataType tillhandahåller ingen validering.

DataType.Date anger inte formatet för det datum som visas. Som standard visas datafältet enligt standardformaten baserat på serverns CultureInfo.

Attributet DisplayFormat används för att uttryckligen ange datumformatet:

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

Inställningen ApplyFormatInEditMode anger att formateringen också ska användas när värdet visas i en textruta för redigering. (Du kanske inte vill det för vissa fält, till exempel för valutavärden, du vill förmodligen inte ha valutasymbolen i textrutan för redigering.)

Du kan använda DisplayFormat attributet självt, men det är vanligtvis en bra idé att använda attributet DataType . Attributet DataType förmedlar semantiken för data i stället för hur du renderar dem på en skärm och ger följande fördelar som du inte får med DisplayFormat:

  • Webbläsaren kan aktivera HTML5-funktioner (till exempel för att visa en kalenderkontroll, språkanpassad valutasymbol, e-postlänkar osv.)

  • Som standard renderar webbläsaren data med rätt format baserat på dina nationella inställningar.

  • Attributet DataType kan göra det möjligt för MVC att välja rätt fältmall för att återge data (om det DisplayFormat används av sig själv använder strängmallen).

Anmärkning

jQuery-validering fungerar inte med attributet Range och DateTime. Följande kod visar till exempel alltid ett verifieringsfel på klientsidan, även när datumet ligger inom det angivna intervallet:

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

Du måste inaktivera jQuery-datumverifiering för att använda Range attributet med DateTime. Det är vanligtvis inte en bra idé att kompilera hårda datum i dina modeller, så att använda Range attributet och DateTime rekommenderas inte.

Följande kod visar hur du kombinerar attribut på en rad:

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

I nästa del av serien granskar vi appen och gör några förbättringar av de automatiskt genererade Details metoderna och Delete metoderna.

Ytterligare resurser