Część 8 serii samouczków na Razor stronach

Uwaga

Nie jest to najnowsza wersja tego artykułu. Aby zapoznać się z bieżącą wersją, zapoznaj się z wersją tego artykułu platformy .NET 8.

Ważne

Te informacje odnoszą się do produktu w wersji wstępnej, który może zostać znacząco zmodyfikowany, zanim zostanie wydany komercyjnie. Firma Microsoft nie udziela żadnych gwarancji, jawnych lub domniemanych, w odniesieniu do informacji podanych w tym miejscu.

Aby zapoznać się z bieżącą wersją, zapoznaj się z wersją tego artykułu platformy .NET 8.

Autor: Rick Anderson

W tej sekcji logika walidacji jest dodawana do Movie modelu. Reguły walidacji są wymuszane za każdym razem, gdy użytkownik tworzy lub edytuje film.

Walidacja

Kluczowy zestaw tworzenia oprogramowania nosi nazwę DRY ("D on R epeat Yself"). Razor Strony zachęcają do programowania, w którym funkcje są określane raz i są odzwierciedlane w całej aplikacji. Dry może pomóc:

  • Zmniejsz ilość kodu w aplikacji.
  • Zmniejszanie podatnych na błędy kodu i łatwiejsze testowanie i konserwację.

Obsługa walidacji zapewniana przez Razor strony i program Entity Framework jest dobrym przykładem zasady DRY:

  • Reguły walidacji są deklaratywne określone w jednym miejscu w klasie modelu.
  • Reguły są wymuszane wszędzie w aplikacji.

Dodawanie reguł walidacji do modelu filmu

System.ComponentModel.DataAnnotations Przestrzeń nazw zapewnia:

  • Zestaw wbudowanych atrybutów weryfikacji, które są stosowane deklaratywnie do klasy lub właściwości.
  • Takie atrybuty [DataType] formatowania ułatwiają formatowanie i nie zapewniają żadnej walidacji.

Zaktualizuj klasę Movie , aby korzystać z wbudowanych [Required]atrybutów , [StringLength], [RegularExpression]i [Range] walidacji.

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

namespace RazorPagesMovie.Models;

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

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

    [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; } = string.Empty;

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

Atrybuty walidacji określają działanie wymuszane wobec właściwości modelu, do których są stosowane:

  • Atrybuty [Required] i [MinimumLength] wskazują, że właściwość musi mieć wartość. Nic nie uniemożliwia użytkownikowi wprowadzania białych znaków w celu spełnienia tej weryfikacji.

  • Atrybut [RegularExpression] służy do ograniczania liczby znaków, które mogą być wprowadzane jako dane wejściowe. W poprzednim kodzie: Genre

    • Muszą być używane tylko litery.
    • Pierwsza litera musi być wielką literą. Dozwolone są białe spacje, a liczby i znaki specjalne nie są dozwolone.
  • Pomocnik RegularExpressionRating:

    • Pierwszy znak musi być wielką literą.
    • Kolejne znaki mogą być znakami specjalnymi i cyframi. Wartość "PG-13" jest prawidłowa dla oceny, ale kończy się niepowodzeniem dla elementu Genre.
  • Atrybut [Range] ogranicza wartość do określonego zakresu.

  • Atrybut [StringLength] może ustawić maksymalną długość właściwości ciągu i opcjonalnie jego minimalną długość.

  • Typy wartości, takie jak decimal, , floatint, DateTime, są z natury wymagane i nie wymagają atrybutu[Required].

Powyższe reguły weryfikacji są używane do pokazu, nie są optymalne dla systemu produkcyjnego. Na przykład powyższy element uniemożliwia wprowadzenie filmu tylko z dwoma znakami i nie zezwala na znaki specjalne w pliku Genre.

Automatyczne wymuszanie reguł weryfikacji przez ASP.NET Core pomaga:

  • Uczynić aplikację bardziej niezawodną.
  • Zmniejsz prawdopodobieństwo zapisania nieprawidłowych danych w bazie danych.

Interfejs użytkownika błędu walidacji na Razor stronach

Uruchom aplikację i przejdź do pozycji Strony/Filmy.

Wybierz link Utwórz nowy. Wypełnij formularz kilkoma nieprawidłowymi wartościami. Gdy walidacja po stronie klienta jQuery wykryje błąd, zostanie wyświetlony komunikat o błędzie.

Formularz widoku Movie (Film) z wieloma błędami walidacji jQuery po stronie klienta

Uwaga

Może nie być możliwe wprowadzenie przecinków dziesiętnych w polach dziesiętnych. Aby obsługiwać walidację jQuery dla ustawień regionalnych innych niż angielski, które używają przecinka (",") dla przecinka dziesiętnego i formatów dat innych niż angielskie stany USA, należy wykonać kroki w celu globalizacji aplikacji. Zobacz ten komentarz usługi GitHub 4076 , aby uzyskać instrukcje dotyczące dodawania przecinka dziesiętnego.

Zwróć uwagę, że formularz automatycznie renderował komunikat o błędzie weryfikacji w każdym polu zawierającym nieprawidłową wartość. Błędy są wymuszane po stronie klienta przy użyciu języków JavaScript i jQuery oraz po stronie serwera, gdy użytkownik wyłączył język JavaScript.

Znaczącą korzyścią jest to, że żadne zmiany kodu nie były niezbędne na stronach Tworzenie lub Edytowanie. Po zastosowaniu adnotacji danych do modelu interfejs użytkownika weryfikacji został włączony. Strony Razor utworzone w tym samouczku automatycznie podniosły reguły walidacji przy użyciu atrybutów weryfikacji we właściwościach Movie klasy modelu. Przetestuj walidację przy użyciu strony Edytuj. Ta sama weryfikacja jest stosowana.

Dane formularza nie są publikowane na serwerze, dopóki nie wystąpią żadne błędy weryfikacji po stronie klienta. Sprawdź, czy dane formularza nie są publikowane przez co najmniej jedną z następujących metod:

  • Umieść punkt przerwania w metodzie OnPostAsync . Prześlij formularz, wybierając pozycję Utwórz lub Zapisz. Punkt przerwania nigdy nie zostanie trafiony.
  • Użyj narzędzia Fiddler.
  • Użyj narzędzi programistycznych przeglądarki, aby monitorować ruch sieciowy.

Walidacja po stronie serwera

Gdy język JavaScript jest wyłączony w przeglądarce, przesłanie formularza z błędami spowoduje opublikowanie na serwerze.

Opcjonalne, testowe sprawdzanie poprawności po stronie serwera:

  1. Wyłącz język JavaScript w przeglądarce. Język JavaScript można wyłączyć przy użyciu narzędzi programistycznych przeglądarki. Jeśli nie można wyłączyć języka JavaScript w przeglądarce, spróbuj użyć innej przeglądarki.

  2. Ustaw punkt przerwania w OnPostAsync metodzie strony Tworzenie lub Edytowanie.

  3. Prześlij formularz z nieprawidłowymi danymi.

  4. Sprawdź, czy stan modelu jest nieprawidłowy:

     if (!ModelState.IsValid)
     {
        return Page();
     }
    

Alternatywnie wyłącz walidację po stronie klienta na serwerze.

Poniższy kod przedstawia część szkieletu Create.cshtml strony wcześniej w samouczku. Są one używane przez strony Tworzenie i edytowanie do:

  • Wyświetl formularz początkowy.
  • Redisplay formularza w przypadku błędu.
<form method="post">
    <div asp-validation-summary="ModelOnly" class="text-danger"></div>
    <div class="form-group">
        <label asp-for="Movie.Title" class="control-label"></label>
        <input asp-for="Movie.Title" class="form-control" />
        <span asp-validation-for="Movie.Title" class="text-danger"></span>
    </div>

Pomocnik tagów wejściowych używa atrybutów DataAnnotations i tworzy atrybuty HTML wymagane do weryfikacji jQuery po stronie klienta. Pomocnik tagu weryfikacji wyświetla błędy walidacji. Aby uzyskać więcej informacji, zobacz Walidacja .

Strony Tworzenie i edytowanie nie mają w nich żadnych reguł sprawdzania poprawności. Reguły walidacji i ciągi błędów są określone tylko w Movie klasie. Te reguły walidacji są automatycznie stosowane do Razor stron, które edytują Movie model.

Gdy logika walidacji musi ulec zmianie, jest wykonywana tylko w modelu. Walidacja jest stosowana spójnie w całej aplikacji, logika walidacji jest definiowana w jednym miejscu. Walidacja w jednym miejscu ułatwia czyszczenie kodu i ułatwia konserwację i aktualizowanie kodu.

Używanie atrybutów Typu danych

Sprawdź klasę Movie . System.ComponentModel.DataAnnotations Przestrzeń nazw udostępnia atrybuty formatowania oprócz wbudowanego zestawu atrybutów weryfikacji. Atrybut [DataType] jest stosowany do właściwości ReleaseDate i Price.

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

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

Atrybuty [DataType] zapewniają:

  • Wskazówki dotyczące aparatu wyświetlania w celu sformatowania danych.
  • Dostarcza atrybuty, takie jak <a> adres URL i <a href="mailto:EmailAddress.com"> adres e-mail.

Użyj atrybutu [RegularExpression] , aby zweryfikować format danych. Atrybut [DataType] służy do określania typu danych, który jest bardziej szczegółowy niż typ wewnętrzny bazy danych. [DataType] atrybuty nie są atrybutami walidacji. W przykładowej aplikacji wyświetlana jest tylko data bez godziny.

Wyliczenie DataType zawiera wiele typów danych, takich jak Date, , Time, CurrencyPhoneNumber, , EmailAddressi nie tylko.

Atrybuty [DataType] :

  • Umożliwia aplikacji automatyczne udostępnianie funkcji specyficznych dla typu. Można na przykład mailto: utworzyć link dla elementu DataType.EmailAddress.
  • Może udostępnić selektor DataType.Date dat w przeglądarkach, które obsługują kod HTML5.
  • Emituj kod HTML 5 data-, wymawiany jako "kreska danych", atrybuty używane przez przeglądarki HTML 5.
  • Nie należy podawać żadnej weryfikacji.

DataType.Date nie określa formatu wyświetlanej daty. Domyślnie pole danych jest wyświetlane zgodnie z domyślnymi formatami na podstawie serwera CultureInfo.

Adnotacja danych jest wymagana [Column(TypeName = "decimal(18, 2)")] , aby program Entity Framework Core mógł poprawnie mapować Price na walutę w bazie danych. Aby uzyskać więcej informacji, zobacz Typy danych.

Atrybut [DisplayFormat] jest używany do jawnego określenia formatu daty:

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

Ustawienie ApplyFormatInEditMode określa, że formatowanie zostanie zastosowane po wyświetleniu wartości do edycji. To zachowanie może nie być pożądane dla niektórych pól. Na przykład w wartościach walutowych symbol waluty zwykle nie jest poszukiwany w interfejsie użytkownika edycji.

Atrybut [DisplayFormat] może być używany samodzielnie, ale zazwyczaj dobrym pomysłem jest użycie atrybutu [DataType] . Atrybut [DataType] przekazuje semantyka danych, w przeciwieństwie do sposobu renderowania ich na ekranie. Atrybut [DataType] zapewnia następujące korzyści, które nie są dostępne w programie [DisplayFormat]:

  • Przeglądarka może włączyć funkcje HTML5, na przykład w celu wyświetlania kontrolki kalendarza, symbolu waluty odpowiedniego dla ustawień regionalnych, linków poczty e-mail itp.
  • Domyślnie przeglądarka renderuje dane przy użyciu poprawnego formatu na podstawie ustawień regionalnych.
  • Atrybut [DataType] może umożliwić platformie ASP.NET Core wybranie odpowiedniego szablonu pola do renderowania danych. Parametr DisplayFormat, jeśli jest używany przez siebie, używa szablonu ciągu.

Uwaga: sprawdzanie poprawności jQuery nie działa z atrybutem [Range] i DateTime. Na przykład następujący kod zawsze wyświetla błąd weryfikacji po stronie klienta, nawet jeśli data znajduje się w określonym zakresie:

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

Najlepszym rozwiązaniem jest unikanie kompilowania twardych dat w modelach, dlatego użycie atrybutu [Range] i DateTime jest zniechęcane. Użyj opcji Konfiguracja dla zakresów dat i innych wartości, które podlegają częstym zmianom, zamiast określać je w kodzie.

Poniższy kod przedstawia łączenie atrybutów w jednym wierszu:

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

namespace RazorPagesMovie.Models;

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

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

    [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; } = string.Empty;

    [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; } = string.Empty;
}

Rozpocznij pracę z usługą Razor Pages i EF Core pokazuje zaawansowane EF Core operacje na Razor stronach.

Stosowanie migracji

Adnotacje danych zastosowane do klasy zmieniają schemat. Na przykład do pola zastosowano Title adnotacje DataAnnotations:

[StringLength(60, MinimumLength = 3)]
[Required]
public string Title { get; set; } = string.Empty;
  • Ogranicza znaki do 60.
  • Nie zezwala na null wartość.

Tabela Movie ma obecnie następujący schemat:

CREATE TABLE [dbo].[Movie] (
    [ID]          INT             IDENTITY (1, 1) NOT NULL,
    [Title]       NVARCHAR (MAX)  NULL,
    [ReleaseDate] DATETIME2 (7)   NOT NULL,
    [Genre]       NVARCHAR (MAX)  NULL,
    [Price]       DECIMAL (18, 2) NOT NULL,
    [Rating]      NVARCHAR (MAX)  NULL,
    CONSTRAINT [PK_Movie] PRIMARY KEY CLUSTERED ([ID] ASC)
);

Powyższe zmiany schematu nie powodują zgłoszenia wyjątku przez platformę EF. Jednak utwórz migrację, aby schemat był zgodny z modelem.

W menu Narzędzia wybierz pozycję NuGet Menedżer pakietów > konsoli Menedżer pakietów. W usłudze PMC wprowadź następujące polecenia:

Add-Migration New_DataAnnotations
Update-Database

Update-Database uruchamia metodę UpNew_DataAnnotations klasy .

Przeanalizuj metodę Up:

public partial class New_DataAnnotations : Migration
{
    /// <inheritdoc />
    protected override void Up(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.AlterColumn<string>(
            name: "Title",
            table: "Movie",
            type: "nvarchar(60)",
            maxLength: 60,
            nullable: false,
            oldClrType: typeof(string),
            oldType: "nvarchar(max)");

        migrationBuilder.AlterColumn<string>(
            name: "Rating",
            table: "Movie",
            type: "nvarchar(5)",
            maxLength: 5,
            nullable: false,
            oldClrType: typeof(string),
            oldType: "nvarchar(max)");

        migrationBuilder.AlterColumn<string>(
            name: "Genre",
            table: "Movie",
            type: "nvarchar(30)",
            maxLength: 30,
            nullable: false,
            oldClrType: typeof(string),
            oldType: "nvarchar(max)");
    }

Zaktualizowana Movie tabela ma następujący schemat:

CREATE TABLE [dbo].[Movie] (
    [ID]          INT             IDENTITY (1, 1) NOT NULL,
    [Title]       NVARCHAR (60)   NOT NULL,
    [ReleaseDate] DATETIME2 (7)   NOT NULL,
    [Genre]       NVARCHAR (30)   NOT NULL,
    [Price]       DECIMAL (18, 2) NOT NULL,
    [Rating]      NVARCHAR (5)    NOT NULL,
    CONSTRAINT [PK_Movie] PRIMARY KEY CLUSTERED ([ID] ASC)
);

Publikowanie na platformie Azure

Aby uzyskać informacje na temat wdrażania na platformie Azure, zobacz Samouczek: tworzenie aplikacji ASP.NET Core na platformie Azure przy użyciu usługi SQL Database.

Dziękujemy za ukończenie tego wprowadzenia do Razor stron. Rozpocznij pracę ze stronami Razor i EF Core doskonale sprawdza się w tym samouczku.

Dodatkowe zasoby

Następne kroki

W tej sekcji logika walidacji jest dodawana do Movie modelu. Reguły walidacji są wymuszane za każdym razem, gdy użytkownik tworzy lub edytuje film.

Walidacja

Kluczowy zestaw tworzenia oprogramowania nosi nazwę DRY ("D on R epeat Yself"). Razor Strony zachęcają do programowania, w którym funkcje są określane raz i są odzwierciedlane w całej aplikacji. Dry może pomóc:

  • Zmniejsz ilość kodu w aplikacji.
  • Zmniejszanie podatnych na błędy kodu i łatwiejsze testowanie i konserwację.

Obsługa walidacji zapewniana przez Razor strony i program Entity Framework jest dobrym przykładem zasady DRY:

  • Reguły walidacji są deklaratywne określone w jednym miejscu w klasie modelu.
  • Reguły są wymuszane wszędzie w aplikacji.

Dodawanie reguł walidacji do modelu filmu

System.ComponentModel.DataAnnotations Przestrzeń nazw zapewnia:

  • Zestaw wbudowanych atrybutów weryfikacji, które są stosowane deklaratywnie do klasy lub właściwości.
  • Takie atrybuty [DataType] formatowania ułatwiają formatowanie i nie zapewniają żadnej walidacji.

Zaktualizuj klasę Movie , aby korzystać z wbudowanych [Required]atrybutów , [StringLength], [RegularExpression]i [Range] walidacji.

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

namespace RazorPagesMovie.Models;

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

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

    // [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; } = string.Empty;

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

Atrybuty walidacji określają działanie wymuszane wobec właściwości modelu, do których są stosowane:

  • Atrybuty [Required] i [MinimumLength] wskazują, że właściwość musi mieć wartość. Nic nie uniemożliwia użytkownikowi wprowadzania białych znaków w celu spełnienia tej weryfikacji.

  • Atrybut [RegularExpression] służy do ograniczania liczby znaków, które mogą być wprowadzane jako dane wejściowe. W poprzednim kodzie: Genre

    • Muszą być używane tylko litery.
    • Pierwsza litera musi być wielką literą. Białe spacje są dozwolone, gdy liczby i znaki specjalne są niedozwolone.
  • Pomocnik RegularExpressionRating:

    • Pierwszy znak musi być wielką literą.
    • Kolejne znaki mogą być znakami specjalnymi i cyframi. Wartość "PG-13" jest prawidłowa dla oceny, ale kończy się niepowodzeniem dla elementu Genre.
  • Atrybut [Range] ogranicza wartość do określonego zakresu.

  • Atrybut [StringLength] może ustawić maksymalną długość właściwości ciągu i opcjonalnie jego minimalną długość.

  • Typy wartości, takie jak decimal, , floatint, DateTime, są z natury wymagane i nie wymagają atrybutu[Required].

Powyższe reguły weryfikacji są używane do pokazu, nie są optymalne dla systemu produkcyjnego. Na przykład powyższy element uniemożliwia wprowadzenie filmu tylko z dwoma znakami i nie zezwala na znaki specjalne w pliku Genre.

Automatyczne wymuszanie reguł weryfikacji przez ASP.NET Core pomaga:

  • Uczynić aplikację bardziej niezawodną.
  • Zmniejsz prawdopodobieństwo zapisania nieprawidłowych danych w bazie danych.

Interfejs użytkownika błędu walidacji na Razor stronach

Uruchom aplikację i przejdź do pozycji Strony/Filmy.

Wybierz link Utwórz nowy. Wypełnij formularz kilkoma nieprawidłowymi wartościami. Gdy walidacja po stronie klienta jQuery wykryje błąd, zostanie wyświetlony komunikat o błędzie.

Formularz widoku Movie (Film) z wieloma błędami walidacji jQuery po stronie klienta

Uwaga

Może nie być możliwe wprowadzenie przecinków dziesiętnych w polach dziesiętnych. Aby obsługiwać walidację jQuery dla ustawień regionalnych innych niż angielski, które używają przecinka (",") dla przecinka dziesiętnego i formatów dat innych niż angielskie stany USA, należy wykonać kroki w celu globalizacji aplikacji. Zobacz ten komentarz usługi GitHub 4076 , aby uzyskać instrukcje dotyczące dodawania przecinka dziesiętnego.

Zwróć uwagę, że formularz automatycznie renderował komunikat o błędzie weryfikacji w każdym polu zawierającym nieprawidłową wartość. Błędy są wymuszane po stronie klienta przy użyciu języków JavaScript i jQuery oraz po stronie serwera, gdy użytkownik wyłączył język JavaScript.

Znaczącą korzyścią jest to, że żadne zmiany kodu nie były niezbędne na stronach Tworzenie lub Edytowanie. Po zastosowaniu adnotacji danych do modelu interfejs użytkownika weryfikacji został włączony. Strony Razor utworzone w tym samouczku automatycznie podniosły reguły walidacji przy użyciu atrybutów weryfikacji we właściwościach Movie klasy modelu. Przetestuj walidację przy użyciu strony Edytuj. Ta sama weryfikacja jest stosowana.

Dane formularza nie są publikowane na serwerze, dopóki nie wystąpią żadne błędy weryfikacji po stronie klienta. Sprawdź, czy dane formularza nie są publikowane przez co najmniej jedną z następujących metod:

  • Umieść punkt przerwania w metodzie OnPostAsync . Prześlij formularz, wybierając pozycję Utwórz lub Zapisz. Punkt przerwania nigdy nie zostanie trafiony.
  • Użyj narzędzia Fiddler.
  • Użyj narzędzi programistycznych przeglądarki, aby monitorować ruch sieciowy.

Walidacja po stronie serwera

Gdy język JavaScript jest wyłączony w przeglądarce, przesłanie formularza z błędami spowoduje opublikowanie na serwerze.

Opcjonalne, testowe sprawdzanie poprawności po stronie serwera:

  1. Wyłącz język JavaScript w przeglądarce. Język JavaScript można wyłączyć przy użyciu narzędzi programistycznych przeglądarki. Jeśli nie można wyłączyć języka JavaScript w przeglądarce, spróbuj użyć innej przeglądarki.

  2. Ustaw punkt przerwania w OnPostAsync metodzie strony Tworzenie lub Edytowanie.

  3. Prześlij formularz z nieprawidłowymi danymi.

  4. Sprawdź, czy stan modelu jest nieprawidłowy:

     if (!ModelState.IsValid)
     {
        return Page();
     }
    

Alternatywnie wyłącz walidację po stronie klienta na serwerze.

Poniższy kod przedstawia część szkieletu Create.cshtml strony wcześniej w samouczku. Są one używane przez strony Tworzenie i edytowanie do:

  • Wyświetl formularz początkowy.
  • Redisplay formularza w przypadku błędu.
<form method="post">
    <div asp-validation-summary="ModelOnly" class="text-danger"></div>
    <div class="form-group">
        <label asp-for="Movie.Title" class="control-label"></label>
        <input asp-for="Movie.Title" class="form-control" />
        <span asp-validation-for="Movie.Title" class="text-danger"></span>
    </div>

Pomocnik tagów wejściowych używa atrybutów DataAnnotations i tworzy atrybuty HTML wymagane do weryfikacji jQuery po stronie klienta. Pomocnik tagu weryfikacji wyświetla błędy walidacji. Aby uzyskać więcej informacji, zobacz Walidacja .

Strony Tworzenie i edytowanie nie mają w nich żadnych reguł sprawdzania poprawności. Reguły walidacji i ciągi błędów są określone tylko w Movie klasie. Te reguły walidacji są automatycznie stosowane do Razor stron, które edytują Movie model.

Gdy logika walidacji musi ulec zmianie, jest wykonywana tylko w modelu. Walidacja jest stosowana spójnie w całej aplikacji, logika walidacji jest definiowana w jednym miejscu. Walidacja w jednym miejscu ułatwia czyszczenie kodu i ułatwia konserwację i aktualizowanie kodu.

Używanie atrybutów Typu danych

Sprawdź klasę Movie . System.ComponentModel.DataAnnotations Przestrzeń nazw udostępnia atrybuty formatowania oprócz wbudowanego zestawu atrybutów weryfikacji. Atrybut [DataType] jest stosowany do właściwości ReleaseDate i Price.

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

Atrybuty [DataType] zapewniają:

  • Wskazówki dotyczące aparatu wyświetlania w celu sformatowania danych.
  • Dostarcza atrybuty, takie jak <a> adres URL i <a href="mailto:EmailAddress.com"> adres e-mail.

Użyj atrybutu [RegularExpression] , aby zweryfikować format danych. Atrybut [DataType] służy do określania typu danych, który jest bardziej szczegółowy niż typ wewnętrzny bazy danych. [DataType] atrybuty nie są atrybutami walidacji. W przykładowej aplikacji wyświetlana jest tylko data bez godziny.

Wyliczenie DataType zawiera wiele typów danych, takich jak Date, , Time, CurrencyPhoneNumber, , EmailAddressi nie tylko.

Atrybuty [DataType] :

  • Umożliwia aplikacji automatyczne udostępnianie funkcji specyficznych dla typu. Można na przykład mailto: utworzyć link dla elementu DataType.EmailAddress.
  • Może udostępnić selektor DataType.Date dat w przeglądarkach, które obsługują kod HTML5.
  • Emituj kod HTML 5 data-, wymawiany jako "kreska danych", atrybuty używane przez przeglądarki HTML 5.
  • Nie należy podawać żadnej weryfikacji.

DataType.Date nie określa formatu wyświetlanej daty. Domyślnie pole danych jest wyświetlane zgodnie z domyślnymi formatami na podstawie serwera CultureInfo.

Adnotacja danych jest wymagana [Column(TypeName = "decimal(18, 2)")] , aby program Entity Framework Core mógł poprawnie mapować Price na walutę w bazie danych. Aby uzyskać więcej informacji, zobacz Typy danych.

Atrybut [DisplayFormat] jest używany do jawnego określenia formatu daty:

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

Ustawienie ApplyFormatInEditMode określa, że formatowanie zostanie zastosowane po wyświetleniu wartości do edycji. To zachowanie może nie być pożądane dla niektórych pól. Na przykład w wartościach walutowych symbol waluty zwykle nie jest poszukiwany w interfejsie użytkownika edycji.

Atrybut [DisplayFormat] może być używany samodzielnie, ale zazwyczaj dobrym pomysłem jest użycie atrybutu [DataType] . Atrybut [DataType] przekazuje semantyka danych, w przeciwieństwie do sposobu renderowania ich na ekranie. Atrybut [DataType] zapewnia następujące korzyści, które nie są dostępne w programie [DisplayFormat]:

  • Przeglądarka może włączyć funkcje HTML5, na przykład w celu wyświetlania kontrolki kalendarza, symbolu waluty odpowiedniego dla ustawień regionalnych, linków poczty e-mail itp.
  • Domyślnie przeglądarka renderuje dane przy użyciu poprawnego formatu na podstawie ustawień regionalnych.
  • Atrybut [DataType] może umożliwić platformie ASP.NET Core wybranie odpowiedniego szablonu pola do renderowania danych. Parametr DisplayFormat, jeśli jest używany przez siebie, używa szablonu ciągu.

Uwaga: sprawdzanie poprawności jQuery nie działa z atrybutem [Range] i DateTime. Na przykład następujący kod zawsze wyświetla błąd weryfikacji po stronie klienta, nawet jeśli data znajduje się w określonym zakresie:

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

Najlepszym rozwiązaniem jest unikanie kompilowania twardych dat w modelach, dlatego użycie atrybutu [Range] i DateTime jest zniechęcane. Użyj opcji Konfiguracja dla zakresów dat i innych wartości, które podlegają częstym zmianom, zamiast określać je w kodzie.

Poniższy kod przedstawia łączenie atrybutów w jednym wierszu:

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

namespace RazorPagesMovie.Models;

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

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

    [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; } = string.Empty;

    [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; } = string.Empty;
}

Rozpocznij pracę z usługą Razor Pages i EF Core pokazuje zaawansowane EF Core operacje na Razor stronach.

Stosowanie migracji

Adnotacje danych zastosowane do klasy zmieniają schemat. Na przykład do pola zastosowano Title adnotacje DataAnnotations:

[StringLength(60, MinimumLength = 3)]
[Required]
public string Title { get; set; } = string.Empty;
  • Ogranicza znaki do 60.
  • Nie zezwala na null wartość.

Tabela Movie ma obecnie następujący schemat:

CREATE TABLE [dbo].[Movie] (
    [ID]          INT             IDENTITY (1, 1) NOT NULL,
    [Title]       NVARCHAR (MAX)  NULL,
    [ReleaseDate] DATETIME2 (7)   NOT NULL,
    [Genre]       NVARCHAR (MAX)  NULL,
    [Price]       DECIMAL (18, 2) NOT NULL,
    [Rating]      NVARCHAR (MAX)  NULL,
    CONSTRAINT [PK_Movie] PRIMARY KEY CLUSTERED ([ID] ASC)
);

Powyższe zmiany schematu nie powodują zgłoszenia wyjątku przez platformę EF. Jednak utwórz migrację, aby schemat był zgodny z modelem.

W menu Narzędzia wybierz pozycję NuGet Menedżer pakietów > konsoli Menedżer pakietów. W usłudze PMC wprowadź następujące polecenia:

Add-Migration New_DataAnnotations
Update-Database

Update-Database uruchamia metodę UpNew_DataAnnotations klasy .

Przeanalizuj metodę Up:

public partial class NewDataAnnotations : Migration
{
    /// <inheritdoc />
    protected override void Up(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.AlterColumn<string>(
            name: "Title",
            table: "Movie",
            type: "nvarchar(60)",
            maxLength: 60,
            nullable: false,
            oldClrType: typeof(string),
            oldType: "nvarchar(max)");

        migrationBuilder.AlterColumn<string>(
            name: "Rating",
            table: "Movie",
            type: "nvarchar(5)",
            maxLength: 5,
            nullable: false,
            oldClrType: typeof(string),
            oldType: "nvarchar(max)");

        migrationBuilder.AlterColumn<string>(
            name: "Genre",
            table: "Movie",
            type: "nvarchar(30)",
            maxLength: 30,
            nullable: false,
            oldClrType: typeof(string),
            oldType: "nvarchar(max)");
    }

Zaktualizowana Movie tabela ma następujący schemat:

CREATE TABLE [dbo].[Movie] (
    [ID]          INT             IDENTITY (1, 1) NOT NULL,
    [Title]       NVARCHAR (60)   NOT NULL,
    [ReleaseDate] DATETIME2 (7)   NOT NULL,
    [Genre]       NVARCHAR (30)   NOT NULL,
    [Price]       DECIMAL (18, 2) NOT NULL,
    [Rating]      NVARCHAR (5)    NOT NULL,
    CONSTRAINT [PK_Movie] PRIMARY KEY CLUSTERED ([ID] ASC)
);

Publikowanie na platformie Azure

Aby uzyskać informacje na temat wdrażania na platformie Azure, zobacz Samouczek: tworzenie aplikacji ASP.NET Core na platformie Azure przy użyciu usługi SQL Database.

Dziękujemy za ukończenie tego wprowadzenia do Razor stron. Rozpocznij pracę ze stronami Razor i EF Core doskonale sprawdza się w tym samouczku.

Dodatkowe zasoby

Następne kroki

W tej sekcji logika walidacji jest dodawana do Movie modelu. Reguły walidacji są wymuszane za każdym razem, gdy użytkownik tworzy lub edytuje film.

Walidacja

Kluczowy zestaw tworzenia oprogramowania nosi nazwę DRY ("D on R epeat Yself"). Razor Strony zachęcają do programowania, w którym funkcje są określane raz i są odzwierciedlane w całej aplikacji. Dry może pomóc:

  • Zmniejsz ilość kodu w aplikacji.
  • Zmniejszanie podatnych na błędy kodu i łatwiejsze testowanie i konserwację.

Obsługa walidacji zapewniana przez Razor strony i program Entity Framework jest dobrym przykładem zasady DRY:

  • Reguły walidacji są deklaratywne określone w jednym miejscu w klasie modelu.
  • Reguły są wymuszane wszędzie w aplikacji.

Dodawanie reguł walidacji do modelu filmu

System.ComponentModel.DataAnnotations Przestrzeń nazw zapewnia:

  • Zestaw wbudowanych atrybutów weryfikacji, które są stosowane deklaratywnie do klasy lub właściwości.
  • Takie atrybuty [DataType] formatowania ułatwiają formatowanie i nie zapewniają żadnej walidacji.

Zaktualizuj klasę Movie , aby korzystać z wbudowanych [Required]atrybutów , [StringLength], [RegularExpression]i [Range] walidacji.

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

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

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

        [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; } = string.Empty;

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

Atrybuty walidacji określają działanie wymuszane wobec właściwości modelu, do których są stosowane:

  • Atrybuty [Required] i [MinimumLength] wskazują, że właściwość musi mieć wartość. Nic nie uniemożliwia użytkownikowi wprowadzania białych znaków w celu spełnienia tej weryfikacji.

  • Atrybut [RegularExpression] służy do ograniczania liczby znaków, które mogą być wprowadzane jako dane wejściowe. W poprzednim kodzie: Genre

    • Muszą być używane tylko litery.
    • Pierwsza litera musi być wielką literą. Białe spacje są dozwolone, gdy liczby i znaki specjalne są niedozwolone.
  • Pomocnik RegularExpressionRating:

    • Pierwszy znak musi być wielką literą.
    • Kolejne znaki mogą być znakami specjalnymi i cyframi. Wartość "PG-13" jest prawidłowa dla oceny, ale kończy się niepowodzeniem dla elementu Genre.
  • Atrybut [Range] ogranicza wartość do określonego zakresu.

  • Atrybut [StringLength] może ustawić maksymalną długość właściwości ciągu i opcjonalnie jego minimalną długość.

  • Typy wartości, takie jak decimal, , floatint, DateTime, są z natury wymagane i nie wymagają atrybutu[Required].

Powyższe reguły weryfikacji są używane do pokazu, nie są optymalne dla systemu produkcyjnego. Na przykład powyższy element uniemożliwia wprowadzenie filmu tylko z dwoma znakami i nie zezwala na znaki specjalne w pliku Genre.

Automatyczne wymuszanie reguł weryfikacji przez ASP.NET Core pomaga:

  • Uczynić aplikację bardziej niezawodną.
  • Zmniejsz prawdopodobieństwo zapisania nieprawidłowych danych w bazie danych.

Interfejs użytkownika błędu walidacji na Razor stronach

Uruchom aplikację i przejdź do pozycji Strony/Filmy.

Wybierz link Utwórz nowy. Wypełnij formularz kilkoma nieprawidłowymi wartościami. Gdy walidacja po stronie klienta jQuery wykryje błąd, zostanie wyświetlony komunikat o błędzie.

Formularz widoku Movie (Film) z wieloma błędami walidacji jQuery po stronie klienta

Uwaga

Może nie być możliwe wprowadzenie przecinków dziesiętnych w polach dziesiętnych. Aby obsługiwać walidację jQuery dla ustawień regionalnych innych niż angielski, które używają przecinka (",") dla przecinka dziesiętnego i formatów dat innych niż angielskie stany USA, należy wykonać kroki w celu globalizacji aplikacji. Zobacz ten komentarz usługi GitHub 4076 , aby uzyskać instrukcje dotyczące dodawania przecinka dziesiętnego.

Zwróć uwagę, że formularz automatycznie renderował komunikat o błędzie weryfikacji w każdym polu zawierającym nieprawidłową wartość. Błędy są wymuszane po stronie klienta przy użyciu języków JavaScript i jQuery oraz po stronie serwera, gdy użytkownik wyłączył język JavaScript.

Znaczącą korzyścią jest to, że żadne zmiany kodu nie były niezbędne na stronach Tworzenie lub Edytowanie. Po zastosowaniu adnotacji danych do modelu interfejs użytkownika weryfikacji został włączony. Strony Razor utworzone w tym samouczku automatycznie podniosły reguły walidacji przy użyciu atrybutów weryfikacji we właściwościach Movie klasy modelu. Przetestuj walidację przy użyciu strony Edytuj. Ta sama weryfikacja jest stosowana.

Dane formularza nie są publikowane na serwerze, dopóki nie wystąpią żadne błędy weryfikacji po stronie klienta. Sprawdź, czy dane formularza nie są publikowane przez co najmniej jedną z następujących metod:

  • Umieść punkt przerwania w metodzie OnPostAsync . Prześlij formularz, wybierając pozycję Utwórz lub Zapisz. Punkt przerwania nigdy nie zostanie trafiony.
  • Użyj narzędzia Fiddler.
  • Użyj narzędzi programistycznych przeglądarki, aby monitorować ruch sieciowy.

Walidacja po stronie serwera

Gdy język JavaScript jest wyłączony w przeglądarce, przesłanie formularza z błędami spowoduje opublikowanie na serwerze.

Opcjonalne, testowe sprawdzanie poprawności po stronie serwera:

  1. Wyłącz język JavaScript w przeglądarce. Język JavaScript można wyłączyć przy użyciu narzędzi programistycznych przeglądarki. Jeśli nie możesz wyłączyć języka JavaScript w przeglądarce, spróbuj użyć innej przeglądarki.

  2. Ustaw punkt przerwania w OnPostAsync metodzie strony Tworzenie lub Edytowanie.

  3. Prześlij formularz z nieprawidłowymi danymi.

  4. Sprawdź, czy stan modelu jest nieprawidłowy:

     if (!ModelState.IsValid)
     {
        return Page();
     }
    

Alternatywnie wyłącz walidację po stronie klienta na serwerze.

Poniższy kod przedstawia część szkieletu Create.cshtml strony wcześniej w samouczku. Są one używane przez strony Tworzenie i edytowanie do:

  • Wyświetl formularz początkowy.
  • Redisplay formularza w przypadku błędu.
<form method="post">
    <div asp-validation-summary="ModelOnly" class="text-danger"></div>
    <div class="form-group">
        <label asp-for="Movie.Title" class="control-label"></label>
        <input asp-for="Movie.Title" class="form-control" />
        <span asp-validation-for="Movie.Title" class="text-danger"></span>
    </div>

Pomocnik tagów wejściowych używa atrybutów DataAnnotations i tworzy atrybuty HTML wymagane do weryfikacji jQuery po stronie klienta. Pomocnik tagu weryfikacji wyświetla błędy walidacji. Aby uzyskać więcej informacji, zobacz Walidacja .

Strony Tworzenie i edytowanie nie mają w nich żadnych reguł sprawdzania poprawności. Reguły walidacji i ciągi błędów są określone tylko w Movie klasie. Te reguły walidacji są automatycznie stosowane do Razor stron, które edytują Movie model.

Gdy logika walidacji musi ulec zmianie, jest wykonywana tylko w modelu. Walidacja jest stosowana spójnie w całej aplikacji, logika walidacji jest definiowana w jednym miejscu. Walidacja w jednym miejscu ułatwia czyszczenie kodu i ułatwia konserwację i aktualizowanie kodu.

Używanie atrybutów Typu danych

Sprawdź klasę Movie . System.ComponentModel.DataAnnotations Przestrzeń nazw udostępnia atrybuty formatowania oprócz wbudowanego zestawu atrybutów weryfikacji. Atrybut [DataType] jest stosowany do właściwości ReleaseDate i Price.

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

Atrybuty [DataType] zapewniają:

  • Wskazówki dotyczące aparatu wyświetlania w celu sformatowania danych.
  • Dostarcza atrybuty, takie jak <a> adres URL i <a href="mailto:EmailAddress.com"> adres e-mail.

Użyj atrybutu [RegularExpression] , aby zweryfikować format danych. Atrybut [DataType] służy do określania typu danych, który jest bardziej szczegółowy niż typ wewnętrzny bazy danych. [DataType] atrybuty nie są atrybutami walidacji. W przykładowej aplikacji wyświetlana jest tylko data bez godziny.

Wyliczenie DataType zawiera wiele typów danych, takich jak Date, , Time, CurrencyPhoneNumber, , EmailAddressi nie tylko.

Atrybuty [DataType] :

  • Może umożliwić aplikacji automatyczne udostępnianie funkcji specyficznych dla typu. Można na przykład mailto: utworzyć link dla elementu DataType.EmailAddress.
  • Może udostępnić selektor DataType.Date dat w przeglądarkach, które obsługują kod HTML5.
  • Emituj kod HTML 5 data-, wymawiany jako "kreska danych", atrybuty używane przez przeglądarki HTML 5.
  • Nie należy podawać żadnej weryfikacji.

DataType.Date nie określa formatu wyświetlanej daty. Domyślnie pole danych jest wyświetlane zgodnie z domyślnymi formatami na podstawie serwera CultureInfo.

Adnotacja danych jest wymagana [Column(TypeName = "decimal(18, 2)")] , aby program Entity Framework Core mógł poprawnie mapować Price na walutę w bazie danych. Aby uzyskać więcej informacji, zobacz Typy danych.

Atrybut [DisplayFormat] jest używany do jawnego określenia formatu daty:

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

Ustawienie ApplyFormatInEditMode określa, że formatowanie zostanie zastosowane po wyświetleniu wartości do edycji. To zachowanie może nie być pożądane dla niektórych pól. Na przykład w wartościach walutowych symbol waluty zwykle nie jest poszukiwany w interfejsie użytkownika edycji.

Atrybut [DisplayFormat] może być używany samodzielnie, ale zazwyczaj dobrym pomysłem jest użycie atrybutu [DataType] . Atrybut [DataType] przekazuje semantyka danych, w przeciwieństwie do sposobu renderowania ich na ekranie. Atrybut [DataType] zapewnia następujące korzyści, które nie są dostępne w programie [DisplayFormat]:

  • Przeglądarka może włączyć funkcje HTML5, na przykład w celu wyświetlania kontrolki kalendarza, symbolu waluty odpowiedniego dla ustawień regionalnych, linków poczty e-mail itp.
  • Domyślnie przeglądarka renderuje dane przy użyciu poprawnego formatu na podstawie ustawień regionalnych.
  • Atrybut [DataType] może umożliwić platformie ASP.NET Core wybranie odpowiedniego szablonu pola do renderowania danych. Parametr DisplayFormat, jeśli jest używany przez siebie, używa szablonu ciągu.

Uwaga: sprawdzanie poprawności jQuery nie działa z atrybutem [Range] i DateTime. Na przykład następujący kod zawsze wyświetla błąd weryfikacji po stronie klienta, nawet jeśli data znajduje się w określonym zakresie:

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

Najlepszym rozwiązaniem jest unikanie kompilowania twardych dat w modelach, dlatego użycie atrybutu [Range] i DateTime jest zniechęcane. Użyj opcji Konfiguracja dla zakresów dat i innych wartości, które podlegają częstym zmianom, zamiast określać je w kodzie.

Poniższy kod przedstawia łączenie atrybutów w jednym wierszu:

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

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

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

        [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; } = string.Empty;

        [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; } = string.Empty;
    }
}

Rozpocznij pracę z usługą Razor Pages i EF Core pokazuje zaawansowane EF Core operacje na Razor stronach.

Stosowanie migracji

Adnotacje danych zastosowane do klasy zmieniają schemat. Na przykład do pola zastosowano Title adnotacje DataAnnotations:

[StringLength(60, MinimumLength = 3)]
[Required]
public string Title { get; set; } = string.Empty;
  • Ogranicza znaki do 60.
  • Nie zezwala na null wartość.

Tabela Movie ma obecnie następujący schemat:

CREATE TABLE [dbo].[Movie] (
    [ID]          INT             IDENTITY (1, 1) NOT NULL,
    [Title]       NVARCHAR (MAX)  NULL,
    [ReleaseDate] DATETIME2 (7)   NOT NULL,
    [Genre]       NVARCHAR (MAX)  NULL,
    [Price]       DECIMAL (18, 2) NOT NULL,
    [Rating]      NVARCHAR (MAX)  NULL,
    CONSTRAINT [PK_Movie] PRIMARY KEY CLUSTERED ([ID] ASC)
);

Powyższe zmiany schematu nie powodują zgłoszenia wyjątku przez platformę EF. Jednak utwórz migrację, aby schemat był zgodny z modelem.

W menu Narzędzia wybierz pozycję NuGet Menedżer pakietów > konsoli Menedżer pakietów. W usłudze PMC wprowadź następujące polecenia:

Add-Migration New_DataAnnotations
Update-Database

Update-Database uruchamia metodę UpNew_DataAnnotations klasy .

Przeanalizuj metodę Up:

public partial class New_DataAnnotations : Migration
{
    protected override void Up(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.AlterColumn<string>(
            name: "Title",
            table: "Movie",
            type: "nvarchar(60)",
            maxLength: 60,
            nullable: false,
            oldClrType: typeof(string),
            oldType: "nvarchar(max)");

        migrationBuilder.AlterColumn<string>(
            name: "Rating",
            table: "Movie",
            type: "nvarchar(5)",
            maxLength: 5,
            nullable: false,
            oldClrType: typeof(string),
            oldType: "nvarchar(max)");

        migrationBuilder.AlterColumn<string>(
            name: "Genre",
            table: "Movie",
            type: "nvarchar(30)",
            maxLength: 30,
            nullable: false,
            oldClrType: typeof(string),
            oldType: "nvarchar(max)");
    }

Zaktualizowana Movie tabela ma następujący schemat:

CREATE TABLE [dbo].[Movie] (
    [ID]          INT             IDENTITY (1, 1) NOT NULL,
    [Title]       NVARCHAR (60)   NOT NULL,
    [ReleaseDate] DATETIME2 (7)   NOT NULL,
    [Genre]       NVARCHAR (30)   NOT NULL,
    [Price]       DECIMAL (18, 2) NOT NULL,
    [Rating]      NVARCHAR (5)    NOT NULL,
    CONSTRAINT [PK_Movie] PRIMARY KEY CLUSTERED ([ID] ASC)
);

Publikowanie na platformie Azure

Aby uzyskać informacje na temat wdrażania na platformie Azure, zobacz Samouczek: tworzenie aplikacji ASP.NET Core na platformie Azure przy użyciu usługi SQL Database.

Dziękujemy za ukończenie tego wprowadzenia do Razor stron. Rozpocznij pracę ze stronami Razor i EF Core doskonale sprawdza się w tym samouczku.

Dodatkowe zasoby

Następne kroki

W tej sekcji logika walidacji jest dodawana do Movie modelu. Reguły walidacji są wymuszane za każdym razem, gdy użytkownik tworzy lub edytuje film.

Walidacja

Kluczowy zestaw tworzenia oprogramowania nosi nazwę DRY ("D on R epeat Yself"). Razor Strony zachęcają do programowania, w którym funkcje są określane raz i są odzwierciedlane w całej aplikacji. Dry może pomóc:

  • Zmniejsz ilość kodu w aplikacji.
  • Zmniejszanie podatnych na błędy kodu i łatwiejsze testowanie i konserwację.

Obsługa walidacji zapewniana przez Razor strony i program Entity Framework jest dobrym przykładem zasady DRY:

  • Reguły walidacji są deklaratywne określone w jednym miejscu w klasie modelu.
  • Reguły są wymuszane wszędzie w aplikacji.

Dodawanie reguł walidacji do modelu filmu

DataAnnotations Przestrzeń nazw zapewnia:

  • Zestaw wbudowanych atrybutów weryfikacji, które są stosowane deklaratywnie do klasy lub właściwości.
  • Takie atrybuty [DataType] formatowania ułatwiają formatowanie i nie zapewniają żadnej walidacji.

Zaktualizuj klasę Movie , aby korzystać z wbudowanych [Required]atrybutów , [StringLength], [RegularExpression]i [Range] walidacji.

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

namespace RazorPagesMovie.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; }
    }
}

Atrybuty walidacji określają działanie wymuszane wobec właściwości modelu, do których są stosowane:

  • Atrybuty [Required] i [MinimumLength] wskazują, że właściwość musi mieć wartość. Nic nie uniemożliwia użytkownikowi wprowadzania białych znaków w celu spełnienia tej weryfikacji.

  • Atrybut [RegularExpression] służy do ograniczania liczby znaków, które mogą być wprowadzane jako dane wejściowe. W poprzednim kodzie: Genre

    • Muszą być używane tylko litery.
    • Pierwsza litera musi być wielką literą. Białe spacje są dozwolone, gdy liczby i znaki specjalne są niedozwolone.
  • Pomocnik RegularExpressionRating:

    • Pierwszy znak musi być wielką literą.
    • Kolejne znaki mogą być znakami specjalnymi i cyframi. Wartość "PG-13" jest prawidłowa dla oceny, ale kończy się niepowodzeniem dla elementu Genre.
  • Atrybut [Range] ogranicza wartość do określonego zakresu.

  • Atrybut [StringLength] może ustawić maksymalną długość właściwości ciągu i opcjonalnie jego minimalną długość.

  • Typy wartości, takie jak decimal, , floatint, DateTime, są z natury wymagane i nie wymagają atrybutu[Required].

Powyższe reguły weryfikacji są używane do pokazu, nie są optymalne dla systemu produkcyjnego. Na przykład powyższy element uniemożliwia wprowadzenie filmu tylko z dwoma znakami i nie zezwala na znaki specjalne w pliku Genre.

Automatyczne wymuszanie reguł weryfikacji przez ASP.NET Core pomaga:

  • Uczynić aplikację bardziej niezawodną.
  • Zmniejsz prawdopodobieństwo zapisania nieprawidłowych danych w bazie danych.

Interfejs użytkownika błędu walidacji na Razor stronach

Uruchom aplikację i przejdź do pozycji Strony/Filmy.

Wybierz link Utwórz nowy. Wypełnij formularz kilkoma nieprawidłowymi wartościami. Gdy walidacja po stronie klienta jQuery wykryje błąd, zostanie wyświetlony komunikat o błędzie.

Formularz widoku Movie (Film) z wieloma błędami walidacji jQuery po stronie klienta

Uwaga

Może nie być możliwe wprowadzenie przecinków dziesiętnych w polach dziesiętnych. Aby obsługiwać walidację jQuery dla ustawień regionalnych innych niż angielski, które używają przecinka (",") dla przecinka dziesiętnego i formatów dat innych niż angielskie stany USA, należy wykonać kroki w celu globalizacji aplikacji. Zobacz ten komentarz usługi GitHub 4076 , aby uzyskać instrukcje dotyczące dodawania przecinka dziesiętnego.

Zwróć uwagę, że formularz automatycznie renderował komunikat o błędzie weryfikacji w każdym polu zawierającym nieprawidłową wartość. Błędy są wymuszane po stronie klienta przy użyciu języków JavaScript i jQuery oraz po stronie serwera, gdy użytkownik wyłączył język JavaScript.

Znaczącą korzyścią jest to, że żadne zmiany kodu nie były niezbędne na stronach Tworzenie lub Edytowanie. Po zastosowaniu adnotacji danych do modelu interfejs użytkownika weryfikacji został włączony. Strony Razor utworzone w tym samouczku automatycznie podniosły reguły walidacji przy użyciu atrybutów weryfikacji we właściwościach Movie klasy modelu. Przetestuj walidację przy użyciu strony Edytuj. Ta sama weryfikacja jest stosowana.

Dane formularza nie są publikowane na serwerze, dopóki nie wystąpią żadne błędy weryfikacji po stronie klienta. Sprawdź, czy dane formularza nie są publikowane przez co najmniej jedną z następujących metod:

  • Umieść punkt przerwania w metodzie OnPostAsync . Prześlij formularz, wybierając pozycję Utwórz lub Zapisz. Punkt przerwania nigdy nie zostanie trafiony.
  • Użyj narzędzia Fiddler.
  • Użyj narzędzi programistycznych przeglądarki, aby monitorować ruch sieciowy.

Walidacja po stronie serwera

Gdy język JavaScript jest wyłączony w przeglądarce, przesłanie formularza z błędami spowoduje opublikowanie na serwerze.

Opcjonalne, testowe sprawdzanie poprawności po stronie serwera:

  1. Wyłącz język JavaScript w przeglądarce. Język JavaScript można wyłączyć przy użyciu narzędzi programistycznych przeglądarki. Jeśli nie można wyłączyć języka JavaScript w przeglądarce, spróbuj użyć innej przeglądarki.

  2. Ustaw punkt przerwania w OnPostAsync metodzie strony Tworzenie lub Edytowanie.

  3. Prześlij formularz z nieprawidłowymi danymi.

  4. Sprawdź, czy stan modelu jest nieprawidłowy:

     if (!ModelState.IsValid)
     {
        return Page();
     }
    

Alternatywnie wyłącz walidację po stronie klienta na serwerze.

Poniższy kod przedstawia część szkieletu Create.cshtml strony wcześniej w samouczku. Są one używane przez strony Tworzenie i edytowanie do:

  • Wyświetl formularz początkowy.
  • Redisplay formularza w przypadku błędu.
<form method="post">
    <div asp-validation-summary="ModelOnly" class="text-danger"></div>
    <div class="form-group">
        <label asp-for="Movie.Title" class="control-label"></label>
        <input asp-for="Movie.Title" class="form-control" />
        <span asp-validation-for="Movie.Title" class="text-danger"></span>
    </div>

Pomocnik tagów wejściowych używa atrybutów DataAnnotations i tworzy atrybuty HTML wymagane do weryfikacji jQuery po stronie klienta. Pomocnik tagu weryfikacji wyświetla błędy walidacji. Aby uzyskać więcej informacji, zobacz Walidacja .

Strony Tworzenie i edytowanie nie mają w nich żadnych reguł sprawdzania poprawności. Reguły walidacji i ciągi błędów są określone tylko w Movie klasie. Te reguły walidacji są automatycznie stosowane do Razor stron, które edytują Movie model.

Gdy logika walidacji musi ulec zmianie, jest wykonywana tylko w modelu. Walidacja jest stosowana spójnie w całej aplikacji, logika walidacji jest definiowana w jednym miejscu. Walidacja w jednym miejscu ułatwia czyszczenie kodu i ułatwia konserwację i aktualizowanie kodu.

Używanie atrybutów Typu danych

Sprawdź klasę Movie . System.ComponentModel.DataAnnotations Przestrzeń nazw udostępnia atrybuty formatowania oprócz wbudowanego zestawu atrybutów weryfikacji. Atrybut [DataType] jest stosowany do właściwości ReleaseDate i Price.

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

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

Atrybuty [DataType] zapewniają:

  • Wskazówki dotyczące aparatu wyświetlania w celu sformatowania danych.
  • Dostarcza atrybuty, takie jak <a> adres URL i <a href="mailto:EmailAddress.com"> adres e-mail.

Użyj atrybutu [RegularExpression] , aby zweryfikować format danych. Atrybut [DataType] służy do określania typu danych, który jest bardziej szczegółowy niż typ wewnętrzny bazy danych. [DataType] atrybuty nie są atrybutami walidacji. W przykładowej aplikacji wyświetlana jest tylko data bez godziny.

Wyliczenie DataType zawiera wiele typów danych, takich jak Date, , Time, CurrencyPhoneNumber, , EmailAddressi nie tylko.

Atrybuty [DataType] :

  • Może umożliwić aplikacji automatyczne udostępnianie funkcji specyficznych dla typu. Można na przykład mailto: utworzyć link dla elementu DataType.EmailAddress.
  • Może udostępnić selektor DataType.Date dat w przeglądarkach, które obsługują kod HTML5.
  • Emituj kod HTML 5 data-, wymawiany jako "kreska danych", atrybuty używane przez przeglądarki HTML 5.
  • Nie należy podawać żadnej weryfikacji.

DataType.Date nie określa formatu wyświetlanej daty. Domyślnie pole danych jest wyświetlane zgodnie z domyślnymi formatami na podstawie serwera CultureInfo.

Adnotacja danych jest wymagana [Column(TypeName = "decimal(18, 2)")] , aby program Entity Framework Core mógł poprawnie mapować Price na walutę w bazie danych. Aby uzyskać więcej informacji, zobacz Typy danych.

Atrybut [DisplayFormat] jest używany do jawnego określenia formatu daty:

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

Ustawienie ApplyFormatInEditMode określa, że formatowanie zostanie zastosowane po wyświetleniu wartości do edycji. To zachowanie może nie być pożądane dla niektórych pól. Na przykład w wartościach walutowych symbol waluty zwykle nie jest poszukiwany w interfejsie użytkownika edycji.

Atrybut [DisplayFormat] może być używany samodzielnie, ale zazwyczaj dobrym pomysłem jest użycie atrybutu [DataType] . Atrybut [DataType] przekazuje semantyka danych, w przeciwieństwie do sposobu renderowania ich na ekranie. Atrybut [DataType] zapewnia następujące korzyści, które nie są dostępne w programie [DisplayFormat]:

  • Przeglądarka może włączyć funkcje HTML5, na przykład w celu wyświetlania kontrolki kalendarza, symbolu waluty odpowiedniego dla ustawień regionalnych, linków poczty e-mail itp.
  • Domyślnie przeglądarka renderuje dane przy użyciu poprawnego formatu na podstawie ustawień regionalnych.
  • Atrybut [DataType] może umożliwić platformie ASP.NET Core wybranie odpowiedniego szablonu pola do renderowania danych. Parametr DisplayFormat, jeśli jest używany przez siebie, używa szablonu ciągu.

Uwaga: sprawdzanie poprawności jQuery nie działa z atrybutem [Range] i DateTime. Na przykład następujący kod zawsze wyświetla błąd weryfikacji po stronie klienta, nawet jeśli data znajduje się w określonym zakresie:

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

Najlepszym rozwiązaniem jest unikanie kompilowania twardych dat w modelach, dlatego użycie atrybutu [Range] i DateTime jest zniechęcane. Użyj opcji Konfiguracja dla zakresów dat i innych wartości, które podlegają częstym zmianom, zamiast określać je w kodzie.

Poniższy kod przedstawia łączenie atrybutów w jednym wierszu:

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

Rozpocznij pracę z usługą Razor Pages i EF Core pokazuje zaawansowane EF Core operacje na Razor stronach.

Stosowanie migracji

Adnotacje danych zastosowane do klasy zmieniają schemat. Na przykład do pola zastosowano Title adnotacje DataAnnotations:

[StringLength(60, MinimumLength = 3)]
[Required]
public string Title { get; set; }
  • Ogranicza znaki do 60.
  • Nie zezwala na null wartość.

Tabela Movie ma obecnie następujący schemat:

CREATE TABLE [dbo].[Movie] (
    [ID]          INT             IDENTITY (1, 1) NOT NULL,
    [Title]       NVARCHAR (MAX)  NULL,
    [ReleaseDate] DATETIME2 (7)   NOT NULL,
    [Genre]       NVARCHAR (MAX)  NULL,
    [Price]       DECIMAL (18, 2) NOT NULL,
    [Rating]      NVARCHAR (MAX)  NULL,
    CONSTRAINT [PK_Movie] PRIMARY KEY CLUSTERED ([ID] ASC)
);

Powyższe zmiany schematu nie powodują zgłoszenia wyjątku przez platformę EF. Jednak utwórz migrację, aby schemat był zgodny z modelem.

W menu Narzędzia wybierz pozycję NuGet Menedżer pakietów > konsoli Menedżer pakietów. W usłudze PMC wprowadź następujące polecenia:

Add-Migration New_DataAnnotations
Update-Database

Update-DatabaseUp uruchamia metody New_DataAnnotations klasy . Przeanalizuj metodę Up:

public partial class New_DataAnnotations : Migration
{
    protected override void Up(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.AlterColumn<string>(
            name: "Title",
            table: "Movie",
            maxLength: 60,
            nullable: false,
            oldClrType: typeof(string),
            oldNullable: true);

        migrationBuilder.AlterColumn<string>(
            name: "Rating",
            table: "Movie",
            maxLength: 5,
            nullable: false,
            oldClrType: typeof(string),
            oldNullable: true);

        migrationBuilder.AlterColumn<string>(
            name: "Genre",
            table: "Movie",
            maxLength: 30,
            nullable: false,
            oldClrType: typeof(string),
            oldNullable: true);
    }

Zaktualizowana Movie tabela ma następujący schemat:

CREATE TABLE [dbo].[Movie] (
    [ID]          INT             IDENTITY (1, 1) NOT NULL,
    [Title]       NVARCHAR (60)   NOT NULL,
    [ReleaseDate] DATETIME2 (7)   NOT NULL,
    [Genre]       NVARCHAR (30)   NOT NULL,
    [Price]       DECIMAL (18, 2) NOT NULL,
    [Rating]      NVARCHAR (5)    NOT NULL,
    CONSTRAINT [PK_Movie] PRIMARY KEY CLUSTERED ([ID] ASC)
);

Publikowanie na platformie Azure

Aby uzyskać informacje na temat wdrażania na platformie Azure, zobacz Samouczek: tworzenie aplikacji ASP.NET Core na platformie Azure przy użyciu usługi SQL Database.

Dziękujemy za ukończenie tego wprowadzenia do Razor stron. Rozpocznij pracę ze stronami Razor i EF Core doskonale sprawdza się w tym samouczku.

Niezawodne wzorce aplikacji internetowej

Aby uzyskać wskazówki dotyczące tworzenia nowoczesnej, niezawodnej, wydajnej, wydajnej, ekonomicznej i skalowalnej aplikacji ASP.NET Core, od podstaw lub refaktoryzacji istniejącej aplikacji, zobacz Niezawodny wzorzecaplikacji internetowej for.NET YouTube.

Dodatkowe zasoby

Następne kroki