Notatka
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Uwaga
Nie jest to najnowsza wersja tego artykułu. Aby zapoznać się z aktualną wersją, zobacz artykuł w wersji .NET 10.
Ostrzeżenie
Ta wersja ASP.NET Core nie jest już obsługiwana. Aby uzyskać więcej informacji, zobacz zasady pomocy technicznej platformy .NET i platformy .NET Core. Aby zapoznać się z aktualną wersją, zobacz artykuł w wersji .NET 10.
W tej sekcji:
- Logika walidacji jest dodawana do
Moviemodelu. - Upewnij się, że reguły walidacji są wymuszane za każdym razem, gdy użytkownik tworzy lub edytuje film.
Utrzymywanie suchych elementów
Jedną z zasad projektowania MVC jest DRY ("Nie powtarzaj się"). ASP.NET Core MVC zachęca do określenia funkcjonalności lub zachowania tylko raz, a następnie ich odzwierciedlenia wszędzie w aplikacji. Zmniejsza to ilość kodu potrzebnego do zapisania i sprawia, że kod, który zapisujesz mniej podatny na błędy, ułatwia testowanie i ułatwia konserwację.
Obsługa walidacji zapewniana przez MVC i Entity Framework Core jest dobrym przykładem zasady DRY w działaniu. Reguły walidacji można deklaratywne określić w jednym miejscu (w klasie modelu), a reguły są wymuszane wszędzie w aplikacji.
Usuń wcześniej edytowane dane
W następnym kroku zostaną dodane reguły sprawdzania poprawności, które nie zezwalają na wartości null.
Uruchom aplikację, przejdź do /Movies/Indexpozycji , usuń wszystkie wymienione filmy i zatrzymaj aplikację. Aplikacja użyje danych początkowych przy następnym uruchomieniu.
Dodawanie reguł walidacji do modelu filmu
Przestrzeń nazw DataAnnotations udostępnia zestaw wbudowanych atrybutów weryfikacji, które są stosowane deklaratywnie do klasy lub właściwości. DataAnnotations zawiera również atrybuty formatowania, takie jak DataType, które pomagają w formatowaniu i nie zapewniają żadnej walidacji.
Zaktualizuj klasę Movie, aby korzystać z wbudowanych atrybutów weryfikacji Required, StringLength, RegularExpression, Range oraz atrybutu formatowania DataType.
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; }
}
Atrybuty weryfikacji określają zachowanie, które chcesz wymusić na właściwościach modelu, do których są stosowane:
Atrybuty
RequirediMinimumLengthwskazują, że właściwość musi mieć wartość, ale nic nie uniemożliwia użytkownikowi wprowadzania białych znaków w celu spełnienia tej weryfikacji.Atrybut
RegularExpressionsłuży do ograniczania liczby znaków, które mogą być wprowadzane jako dane wejściowe. W poprzednim kodzie w polu „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.
W atrybucie
RegularExpression„Rating” (Klasyfikacja):- Pierwszy znak musi być wielką literą.
- Pozwala na użycie znaków specjalnych i cyfr w kolejnych odstępach. Dla atrybutu "Rating" wartość „PG-13” jest prawidłowa, ale dla atrybutu "Genre" nie.
Atrybut
Rangeogranicza wartość do określonego zakresu.Atrybut
StringLengthumożliwia ustawienie maksymalnej długości właściwości ciągu i opcjonalnie jego minimalnej długości.Typy wartości (takie jak
decimal,int,float,DateTime) są z natury wymagane i nie wymagają atrybutu[Required].
Automatyczne wymuszanie reguł weryfikacji przez platformę ASP.NET Core pomaga zwiększyć niezawodność aplikacji. Gwarantuje to również, że nie zapomnisz o zweryfikowaniu czegoś i nie dopuścisz do przypadkowego wprowadzenia złych danych do bazy danych.
Błąd walidacji interfejsu użytkownika
Uruchom aplikację i przejdź do kontrolera Filmy.
Wybierz link Utwórz nowy, aby dodać nowy film. Wypełnij formularz kilkoma nieprawidłowymi wartościami. Gdy tylko walidacja po stronie klienta jQuery wykryje błąd, zostanie wyświetlony komunikat o błędzie.
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ż anglojęzyczne, które używają przecinka (",") jako separatora dziesiętnego, oraz dla formatów dat spoza USA, należy przeprowadzić globalizację aplikacji. Zobacz ten komentarz usługi GitHub 4076 , aby uzyskać instrukcje dotyczące dodawania przecinka dziesiętnego.
Zwróć uwagę, że formularz automatycznie renderował odpowiedni 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) i po stronie serwera (w przypadku wyłączenia języka JavaScript przez użytkownika).
Ważną korzyścią jest to, że aby włączyć ten interfejs weryfikacji, nie trzeba zmieniać pojedynczego wiersza kodu w klasie MoviesController lub w widoku Create.cshtml. Kontroler i widoki utworzone wcześniej w tym samouczku automatycznie rozpoznały reguły weryfikacji określone przy użyciu atrybutów weryfikacji we właściwościach klasy modelu Movie. Przetestuj walidację przy użyciu metody akcji Edit, a następnie zastosuj tę samą walidację.
Dane formularza nie są wysyłane do serwera, dopóki nie wystąpią żadne błędy weryfikacji po stronie klienta. Możesz to sprawdzić, ustawiając punkt przerwania w metodzie HTTP Post, za pomocą narzędzia Fiddler lub narzędzi programistycznych F12.
Jak działa walidacja
Możesz się zastanawiać, w jaki sposób wygenerowano interfejs weryfikacji użytkownika bez żadnych aktualizacji kodu w kontrolerze lub widokach. Poniższy kod przedstawia dwie Create metody.
// 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);
}
Pierwsza metoda akcji (HTTP GET) Create wyświetla początkowy formularz Utwórz. Druga wersja ([HttpPost]) obsługuje przesyłanie formularzy. Druga Create metoda (wersja [HttpPost] ) wywołuje metodę ModelState.IsValid w celu sprawdzenia, czy film ma jakiekolwiek błędy walidacji. Wywołanie tej metody ocenia wszystkie atrybuty walidacji, które zostały zastosowane do obiektu. Jeśli obiekt zawiera błędy weryfikacji, Create metoda ponownie wyświetli formularz. Jeśli nie ma żadnych błędów, metoda zapisuje nowy film w bazie danych. W naszym przykładzie filmu formularz nie jest publikowany na serwerze, gdy występują błędy walidacji wykryte po stronie klienta; druga Create metoda nigdy nie jest wywoływana, gdy występują błędy weryfikacji po stronie klienta. Jeśli wyłączysz język JavaScript w przeglądarce, walidacja klienta jest wyłączona i możesz przetestować metodę Create HTTP POSTModelState.IsValid, wykrywając błędy walidacji.
Możesz ustawić punkt przerwania w metodzie [HttpPost] Create i sprawdzić, czy metoda nigdy nie jest wywoływana, walidacja po stronie klienta nie będzie przesyłać danych formularza po wykryciu błędów walidacji. Jeśli wyłączysz JavaScript w przeglądarce, a następnie prześlesz formularz z błędami, zostanie osiągnięty punkt przerwania. Nadal uzyskujesz pełną walidację bez języka JavaScript.
Na poniższej ilustracji przedstawiono sposób wyłączania języka JavaScript w przeglądarce Chrome. Wyszukaj w ustawieniach, aby dowiedzieć się, jak wyłączyć język JavaScript w używanej przeglądarce.
Po wyłączeniu języka JavaScript opublikuj nieprawidłowe dane i przejdź przez debuger.
Część szablonu widoku Create.cshtml jest przedstawiona w następującym kodzie znaczników:
<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.*@
Powyższy znacznik jest używany przez metody działania do wyświetlania początkowego formularza i ponownego wyświetlenia go w przypadku błędu.
Naprawdę miło jest to, że ani kontroler, ani Create szablon widoku nie wie nic o rzeczywistych regułach walidacji, które są wymuszane, ani o wyświetlanych konkretnych komunikatach o błędach. Reguły walidacji i ciągi błędów są określone tylko w Movie klasie. Te same reguły sprawdzania poprawności są automatycznie stosowane do Edit widoku i wszystkich innych szablonów widoków, które można utworzyć, aby edytować model.
Jeśli musisz zmienić logikę weryfikacji, możesz to zrobić w dokładnie jednym miejscu, dodając atrybuty weryfikacji do modelu (w tym przykładzie Movie klasa). Nie trzeba martwić się o niespójność różnych części aplikacji ze sposobem wymuszania reguł — cała logika walidacji zostanie zdefiniowana w jednym miejscu i używana wszędzie. Dzięki temu kod jest bardzo czysty i ułatwia konserwację i rozwijanie. Oznacza to, że będziesz w pełni przestrzegać zasady DRY.
Używanie atrybutów Typu danych
Movie.cs Otwórz plik i sprawdź klasęMovie.
System.ComponentModel.DataAnnotations Przestrzeń nazw udostępnia atrybuty formatowania oprócz wbudowanego zestawu atrybutów weryfikacji. Zastosowaliśmy już tę wartość wyliczenia do daty wydania i pól cenowych. Poniższy kod pokazuje właściwości ReleaseDate i Price z atrybutem DataType, który jest odpowiedni.
[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 dostarczają jedynie wskazówek dla aparatu wyświetlania, jak sformatować dane, i zapewniają elementy/atrybuty, takie jak <a> dla URL'u i <a href="mailto:EmailAddress.com"> dla adresu e-mail. Możesz użyć 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, nie są atrybutami walidacji. W tym przypadku chcemy śledzić tylko datę, a nie godzinę. Wyliczenie DataType zawiera wiele typów danych, takich jak Data, Godzina, Numer telefonu, Waluta, Adres e-mail i inne. Atrybut DataType może również umożliwić aplikacji automatyczne udostępnianie funkcji specyficznych dla typu. Na przykład można utworzyć link dla elementu mailto:, a selektor dat można zapewnić DataType.EmailAddress w przeglądarkach obsługujących HTML5. Atrybuty DataType emitują atrybuty HTML 5 data- (czytane jako data dash, czyli "kreska danych"), które przeglądarki HTML 5 mogą zrozumieć. Atrybuty DataTypenie zapewniają żadnej walidacji.
DataType.Date nie określa formatu wyświetlanej daty. Domyślnie pole danych jest wyświetlane zgodnie z domyślnie zdefiniowanymi formatami serwera CultureInfo.
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 powinno być również stosowane, gdy wartość jest wyświetlana w polu tekstowym do edycji. (Możesz nie chcieć tego dla niektórych pól — na przykład w przypadku wartości walutowych prawdopodobnie nie chcesz, aby symbol waluty w polu tekstowym był edytowany).
Możesz użyć atrybutu DisplayFormat samodzielnie, ale zazwyczaj warto skorzystać z atrybutu DataType. Atrybut DataType przekazuje semantyka danych, w przeciwieństwie do sposobu renderowania ich na ekranie, i zapewnia następujące korzyści, które nie są uzyskiwane za pomocą elementu 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 będzie renderować dane przy użyciu poprawnego formatu na podstawie ustawień regionalnych.
Atrybut
DataTypemoże umożliwić MVC wybranie odpowiedniego szablonu pola w celu renderowania danych (DisplayFormat, jeśli używany samodzielnie, używa szablonu dla ciągów).
Zastosuj migracje
Niektóre atrybuty weryfikacji wpływają na schemat bazy danych. Na przykład [Required] tworzy kolumnę NOT NULL i [StringLength(60)] ogranicza typ kolumny do nvarchar(60). Uruchom migrację, aby zachować spójność schematu bazy danych z modelem.
W menu Tools wybierz pozycję NuGet Menedżer pakietów > Menedżer pakietów Console.
W usłudze PMC wprowadź następujące polecenia:
Add-Migration New_DataAnnotations
Update-Database
Treści powiązane
W tej sekcji:
- Logika walidacji jest dodawana do
Moviemodelu. - Upewnij się, że reguły walidacji są wymuszane za każdym razem, gdy użytkownik tworzy lub edytuje film.
Utrzymywanie suchych elementów
Jedną z zasad projektowania MVC jest DRY ("Nie powtarzaj się"). ASP.NET Core MVC zachęca do określenia funkcjonalności lub zachowania tylko raz, a następnie ich odzwierciedlenia wszędzie w aplikacji. Zmniejsza to ilość kodu potrzebnego do zapisania i sprawia, że kod, który zapisujesz mniej podatny na błędy, ułatwia testowanie i ułatwia konserwację.
Obsługa walidacji zapewniana przez MVC i Entity Framework Core jest dobrym przykładem zasady DRY w działaniu. Reguły walidacji można deklaratywne określić w jednym miejscu (w klasie modelu), a reguły są wymuszane wszędzie w aplikacji.
Usuń wcześniej edytowane dane
W następnym kroku zostaną dodane reguły sprawdzania poprawności, które nie zezwalają na wartości null.
Uruchom aplikację, przejdź do /Movies/Indexpozycji , usuń wszystkie wymienione filmy i zatrzymaj aplikację. Aplikacja użyje danych początkowych przy następnym uruchomieniu.
Dodawanie reguł walidacji do modelu filmu
Przestrzeń nazw DataAnnotations udostępnia zestaw wbudowanych atrybutów weryfikacji, które są stosowane deklaratywnie do klasy lub właściwości. DataAnnotations zawiera również atrybuty formatowania, takie jak DataType, które pomagają w formatowaniu i nie zapewniają żadnej walidacji.
Zaktualizuj klasę Movie, aby korzystać z wbudowanych atrybutów weryfikacji Required, StringLength, RegularExpression, Range oraz atrybutu formatowania DataType.
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; }
}
Atrybuty weryfikacji określają zachowanie, które chcesz wymusić na właściwościach modelu, do których są stosowane:
Atrybuty
RequirediMinimumLengthwskazują, że właściwość musi mieć wartość, ale nic nie uniemożliwia użytkownikowi wprowadzania białych znaków w celu spełnienia tej weryfikacji.Atrybut
RegularExpressionsłuży do ograniczania liczby znaków, które mogą być wprowadzane jako dane wejściowe. W poprzednim kodzie w polu „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.
W atrybucie
RegularExpression„Rating” (Klasyfikacja):- Pierwszy znak musi być wielką literą.
- Pozwala na użycie znaków specjalnych i cyfr w kolejnych odstępach. Dla atrybutu "Rating" wartość „PG-13” jest prawidłowa, ale dla atrybutu "Genre" nie.
Atrybut
Rangeogranicza wartość do określonego zakresu.Atrybut
StringLengthumożliwia ustawienie maksymalnej długości właściwości ciągu i opcjonalnie jego minimalnej długości.Typy wartości (takie jak
decimal,int,float,DateTime) są z natury wymagane i nie wymagają atrybutu[Required].
Automatyczne wymuszanie reguł weryfikacji przez platformę ASP.NET Core pomaga zwiększyć niezawodność aplikacji. Gwarantuje to również, że nie zapomnisz o zweryfikowaniu czegoś i nie dopuścisz do przypadkowego wprowadzenia złych danych do bazy danych.
Błąd walidacji interfejsu użytkownika
Uruchom aplikację i przejdź do kontrolera Filmy.
Wybierz link Utwórz nowy, aby dodać nowy film. Wypełnij formularz kilkoma nieprawidłowymi wartościami. Gdy tylko walidacja po stronie klienta jQuery wykryje błąd, zostanie wyświetlony komunikat o błędzie.
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ż anglojęzyczne, które używają przecinka (",") jako separatora dziesiętnego, oraz dla formatów dat spoza USA, należy przeprowadzić globalizację aplikacji. Zobacz ten komentarz usługi GitHub 4076 , aby uzyskać instrukcje dotyczące dodawania przecinka dziesiętnego.
Zwróć uwagę, że formularz automatycznie renderował odpowiedni 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) i po stronie serwera (w przypadku wyłączenia języka JavaScript przez użytkownika).
Ważną korzyścią jest to, że aby włączyć ten interfejs weryfikacji, nie trzeba zmieniać pojedynczego wiersza kodu w klasie MoviesController lub w widoku Create.cshtml. Kontroler i widoki utworzone wcześniej w tym samouczku automatycznie rozpoznały reguły weryfikacji określone przy użyciu atrybutów weryfikacji we właściwościach klasy modelu Movie. Przetestuj walidację przy użyciu metody akcji Edit, a następnie zastosuj tę samą walidację.
Dane formularza nie są wysyłane do serwera, dopóki nie wystąpią żadne błędy weryfikacji po stronie klienta. Możesz to sprawdzić, ustawiając punkt przerwania w metodzie HTTP Post, za pomocą narzędzia Fiddler lub narzędzi programistycznych F12.
Jak działa walidacja
Możesz się zastanawiać, w jaki sposób wygenerowano interfejs weryfikacji użytkownika bez żadnych aktualizacji kodu w kontrolerze lub widokach. Poniższy kod przedstawia dwie Create metody.
// 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);
}
Pierwsza metoda akcji (HTTP GET) Create wyświetla początkowy formularz Utwórz. Druga wersja ([HttpPost]) obsługuje przesyłanie formularzy. Druga Create metoda (wersja [HttpPost] ) wywołuje metodę ModelState.IsValid w celu sprawdzenia, czy film ma jakiekolwiek błędy walidacji. Wywołanie tej metody ocenia wszystkie atrybuty walidacji, które zostały zastosowane do obiektu. Jeśli obiekt zawiera błędy weryfikacji, Create metoda ponownie wyświetli formularz. Jeśli nie ma żadnych błędów, metoda zapisuje nowy film w bazie danych. W naszym przykładzie filmu formularz nie jest publikowany na serwerze, gdy występują błędy walidacji wykryte po stronie klienta; druga Create metoda nigdy nie jest wywoływana, gdy występują błędy weryfikacji po stronie klienta. Jeśli wyłączysz język JavaScript w przeglądarce, walidacja klienta jest wyłączona i możesz przetestować metodę Create HTTP POSTModelState.IsValid, wykrywając błędy walidacji.
Możesz ustawić punkt przerwania w metodzie [HttpPost] Create i sprawdzić, czy metoda nigdy nie jest wywoływana, walidacja po stronie klienta nie będzie przesyłać danych formularza po wykryciu błędów walidacji. Jeśli wyłączysz JavaScript w przeglądarce, a następnie prześlesz formularz z błędami, zostanie osiągnięty punkt przerwania. Nadal uzyskujesz pełną walidację bez języka JavaScript.
Na poniższej ilustracji przedstawiono sposób wyłączania języka JavaScript w przeglądarce Firefox.
Na poniższej ilustracji przedstawiono sposób wyłączania języka JavaScript w przeglądarce Chrome.
Po wyłączeniu języka JavaScript opublikuj nieprawidłowe dane i przejdź przez debuger.
Część szablonu widoku Create.cshtml jest przedstawiona w następującym kodzie znaczników:
<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.*@
Powyższy znacznik jest używany przez metody działania do wyświetlania początkowego formularza i ponownego wyświetlenia go w przypadku błędu.
Naprawdę miło jest to, że ani kontroler, ani Create szablon widoku nie wie nic o rzeczywistych regułach walidacji, które są wymuszane, ani o wyświetlanych konkretnych komunikatach o błędach. Reguły walidacji i ciągi błędów są określone tylko w Movie klasie. Te same reguły sprawdzania poprawności są automatycznie stosowane do Edit widoku i wszystkich innych szablonów widoków, które można utworzyć, aby edytować model.
Jeśli musisz zmienić logikę weryfikacji, możesz to zrobić w dokładnie jednym miejscu, dodając atrybuty weryfikacji do modelu (w tym przykładzie Movie klasa). Nie trzeba martwić się o niespójność różnych części aplikacji ze sposobem wymuszania reguł — cała logika walidacji zostanie zdefiniowana w jednym miejscu i używana wszędzie. Dzięki temu kod jest bardzo czysty i ułatwia konserwację i rozwijanie. Oznacza to, że będziesz w pełni przestrzegać zasady DRY.
Używanie atrybutów Typu danych
Movie.cs Otwórz plik i sprawdź klasęMovie.
System.ComponentModel.DataAnnotations Przestrzeń nazw udostępnia atrybuty formatowania oprócz wbudowanego zestawu atrybutów weryfikacji. Zastosowaliśmy już tę wartość wyliczenia do daty wydania i pól cenowych. Poniższy kod pokazuje właściwości ReleaseDate i Price z atrybutem DataType, który jest odpowiedni.
[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 dostarczają jedynie wskazówek dla aparatu wyświetlania, jak sformatować dane, i zapewniają elementy/atrybuty, takie jak <a> dla URL'u i <a href="mailto:EmailAddress.com"> dla adresu e-mail. Możesz użyć 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, nie są atrybutami walidacji. W tym przypadku chcemy śledzić tylko datę, a nie godzinę. Wyliczenie DataType zawiera wiele typów danych, takich jak Data, Godzina, Numer telefonu, Waluta, Adres e-mail i inne. Atrybut DataType może również umożliwić aplikacji automatyczne udostępnianie funkcji specyficznych dla typu. Na przykład można utworzyć link dla elementu mailto:, a selektor dat można zapewnić DataType.EmailAddress w przeglądarkach obsługujących HTML5. Atrybuty DataType emitują atrybuty HTML 5 data- (czytane jako data dash, czyli "kreska danych"), które przeglądarki HTML 5 mogą zrozumieć. Atrybuty DataTypenie zapewniają żadnej walidacji.
DataType.Date nie określa formatu wyświetlanej daty. Domyślnie pole danych jest wyświetlane zgodnie z domyślnie zdefiniowanymi formatami serwera CultureInfo.
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 powinno być również stosowane, gdy wartość jest wyświetlana w polu tekstowym do edycji. (Możesz nie chcieć tego dla niektórych pól — na przykład w przypadku wartości walutowych prawdopodobnie nie chcesz, aby symbol waluty w polu tekstowym był edytowany).
Możesz użyć atrybutu DisplayFormat samodzielnie, ale zazwyczaj warto skorzystać z atrybutu DataType. Atrybut DataType przekazuje semantyka danych, w przeciwieństwie do sposobu renderowania ich na ekranie, i zapewnia następujące korzyści, które nie są uzyskiwane za pomocą elementu 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 będzie renderować dane przy użyciu poprawnego formatu na podstawie ustawień regionalnych.
Atrybut
DataTypemoże umożliwić MVC wybranie odpowiedniego szablonu pola w celu renderowania danych (DisplayFormat, jeśli używany samodzielnie, używa szablonu dla ciągów).
Uwaga
Sprawdzanie poprawności zapytania 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")]
Aby użyć atrybutu Range z DateTime, należy wyłączyć walidację daty jQuery. Zazwyczaj nie jest dobrą praktyką używać konkretnych dat w modelach danych, dlatego odradza się korzystanie z atrybutów Range i DateTime.
Poniższy kod przedstawia łączenie atrybutów w jednym wierszu:
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; }
}
Zastosuj migracje
Niektóre atrybuty weryfikacji wpływają na schemat bazy danych. Na przykład [Required] tworzy kolumnę NOT NULL i [StringLength(60)] ogranicza typ kolumny do nvarchar(60). Uruchom migrację, aby zachować spójność schematu bazy danych z modelem.
W menu Tools wybierz pozycję NuGet Menedżer pakietów > Menedżer pakietów Console.
W usłudze PMC wprowadź następujące polecenia:
Add-Migration New_DataAnnotations
Update-Database
W następnej części serii przejrzymy aplikację i wprowadzimy pewne ulepszenia w metodach Details i Delete automatycznie wygenerowanych.
Treści powiązane
W tej sekcji:
- Logika walidacji jest dodawana do
Moviemodelu. - Upewnij się, że reguły walidacji są wymuszane za każdym razem, gdy użytkownik tworzy lub edytuje film.
Utrzymywanie suchych elementów
Jedną z zasad projektowania MVC jest DRY ("Nie powtarzaj się"). ASP.NET Core MVC zachęca do określenia funkcjonalności lub zachowania tylko raz, a następnie ich odzwierciedlenia wszędzie w aplikacji. Zmniejsza to ilość kodu potrzebnego do zapisania i sprawia, że kod, który zapisujesz mniej podatny na błędy, ułatwia testowanie i ułatwia konserwację.
Obsługa walidacji zapewniana przez MVC i Entity Framework Core Code First jest dobrym przykładem zasady DRY w działaniu. Reguły walidacji można deklaratywne określić w jednym miejscu (w klasie modelu), a reguły są wymuszane wszędzie w aplikacji.
Usuń wcześniej edytowane dane
W następnym kroku zostaną dodane reguły sprawdzania poprawności, które nie zezwalają na wartości null.
Uruchom aplikację, przejdź do /Movies/Indexpozycji , usuń wszystkie wymienione filmy i zatrzymaj aplikację. Aplikacja użyje danych początkowych przy następnym uruchomieniu.
Dodawanie reguł walidacji do modelu filmu
Przestrzeń nazw DataAnnotations udostępnia zestaw wbudowanych atrybutów weryfikacji, które są stosowane deklaratywnie do klasy lub właściwości. DataAnnotations zawiera również atrybuty formatowania, takie jak DataType, które pomagają w formatowaniu i nie zapewniają żadnej walidacji.
Zaktualizuj klasę Movie, aby korzystać z wbudowanych atrybutów weryfikacji Required, StringLength, RegularExpression, Range oraz atrybutu formatowania DataType.
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; }
}
Atrybuty weryfikacji określają zachowanie, które chcesz wymusić na właściwościach modelu, do których są stosowane:
Atrybuty
RequirediMinimumLengthwskazują, że właściwość musi mieć wartość, ale nic nie uniemożliwia użytkownikowi wprowadzania białych znaków w celu spełnienia tej weryfikacji.Atrybut
RegularExpressionsłuży do ograniczania liczby znaków, które mogą być wprowadzane jako dane wejściowe. W poprzednim kodzie w polu „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.
W atrybucie
RegularExpression„Rating” (Klasyfikacja):- Pierwszy znak musi być wielką literą.
- Pozwala na użycie znaków specjalnych i cyfr w kolejnych odstępach. Dla atrybutu "Rating" wartość „PG-13” jest prawidłowa, ale dla atrybutu "Genre" nie.
Atrybut
Rangeogranicza wartość do określonego zakresu.Atrybut
StringLengthumożliwia ustawienie maksymalnej długości właściwości ciągu i opcjonalnie jego minimalnej długości.Typy wartości (takie jak
decimal,int,float,DateTime) są z natury wymagane i nie wymagają atrybutu[Required].
Automatyczne wymuszanie reguł weryfikacji przez platformę ASP.NET Core pomaga zwiększyć niezawodność aplikacji. Gwarantuje to również, że nie zapomnisz o zweryfikowaniu czegoś i nie dopuścisz do przypadkowego wprowadzenia złych danych do bazy danych.
Błąd walidacji interfejsu użytkownika
Uruchom aplikację i przejdź do kontrolera Filmy.
Wybierz link Utwórz nowy, aby dodać nowy film. Wypełnij formularz kilkoma nieprawidłowymi wartościami. Gdy tylko walidacja po stronie klienta jQuery wykryje błąd, zostanie wyświetlony komunikat o błędzie.
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ż anglojęzyczne, które używają przecinka (",") jako separatora dziesiętnego, oraz dla formatów dat spoza USA, należy przeprowadzić globalizację aplikacji. Zobacz ten komentarz usługi GitHub 4076 , aby uzyskać instrukcje dotyczące dodawania przecinka dziesiętnego.
Zwróć uwagę, że formularz automatycznie renderował odpowiedni 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) i po stronie serwera (w przypadku wyłączenia języka JavaScript przez użytkownika).
Ważną korzyścią jest to, że aby włączyć ten interfejs weryfikacji, nie trzeba zmieniać pojedynczego wiersza kodu w klasie MoviesController lub w widoku Create.cshtml. Kontroler i widoki utworzone wcześniej w tym samouczku automatycznie rozpoznały reguły weryfikacji określone przy użyciu atrybutów weryfikacji we właściwościach klasy modelu Movie. Przetestuj walidację przy użyciu metody akcji Edit, a następnie zastosuj tę samą walidację.
Dane formularza nie są wysyłane do serwera, dopóki nie wystąpią żadne błędy weryfikacji po stronie klienta. Możesz to sprawdzić, ustawiając punkt przerwania w metodzie HTTP Post, za pomocą narzędzia Fiddler lub narzędzi programistycznych F12.
Jak działa walidacja
Możesz się zastanawiać, w jaki sposób wygenerowano interfejs weryfikacji użytkownika bez żadnych aktualizacji kodu w kontrolerze lub widokach. Poniższy kod przedstawia dwie Create metody.
// 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);
}
Pierwsza metoda akcji (HTTP GET) Create wyświetla początkowy formularz Utwórz. Druga wersja ([HttpPost]) obsługuje przesyłanie formularzy. Druga Create metoda (wersja [HttpPost] ) wywołuje metodę ModelState.IsValid w celu sprawdzenia, czy film ma jakiekolwiek błędy walidacji. Wywołanie tej metody ocenia wszystkie atrybuty walidacji, które zostały zastosowane do obiektu. Jeśli obiekt zawiera błędy weryfikacji, Create metoda ponownie wyświetli formularz. Jeśli nie ma żadnych błędów, metoda zapisuje nowy film w bazie danych. W naszym przykładzie filmu formularz nie jest publikowany na serwerze, gdy występują błędy walidacji wykryte po stronie klienta; druga Create metoda nigdy nie jest wywoływana, gdy występują błędy weryfikacji po stronie klienta. Jeśli wyłączysz język JavaScript w przeglądarce, walidacja klienta jest wyłączona i możesz przetestować metodę Create HTTP POSTModelState.IsValid, wykrywając błędy walidacji.
Możesz ustawić punkt przerwania w metodzie [HttpPost] Create i sprawdzić, czy metoda nigdy nie jest wywoływana, walidacja po stronie klienta nie będzie przesyłać danych formularza po wykryciu błędów walidacji. Jeśli wyłączysz JavaScript w przeglądarce, a następnie prześlesz formularz z błędami, zostanie osiągnięty punkt przerwania. Nadal uzyskujesz pełną walidację bez języka JavaScript.
Na poniższej ilustracji przedstawiono sposób wyłączania języka JavaScript w przeglądarce Firefox.
Na poniższej ilustracji przedstawiono sposób wyłączania języka JavaScript w przeglądarce Chrome.
Po wyłączeniu języka JavaScript opublikuj nieprawidłowe dane i przejdź przez debuger.
Część szablonu widoku Create.cshtml jest przedstawiona w następującym kodzie znaczników:
<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.*@
Powyższy znacznik jest używany przez metody działania do wyświetlania początkowego formularza i ponownego wyświetlenia go w przypadku błędu.
Naprawdę miło jest to, że ani kontroler, ani Create szablon widoku nie wie nic o rzeczywistych regułach walidacji, które są wymuszane, ani o wyświetlanych konkretnych komunikatach o błędach. Reguły walidacji i ciągi błędów są określone tylko w Movie klasie. Te same reguły sprawdzania poprawności są automatycznie stosowane do Edit widoku i wszystkich innych szablonów widoków, które można utworzyć, aby edytować model.
Jeśli musisz zmienić logikę weryfikacji, możesz to zrobić w dokładnie jednym miejscu, dodając atrybuty weryfikacji do modelu (w tym przykładzie Movie klasa). Nie trzeba martwić się o niespójność różnych części aplikacji ze sposobem wymuszania reguł — cała logika walidacji zostanie zdefiniowana w jednym miejscu i używana wszędzie. Dzięki temu kod jest bardzo czysty i ułatwia konserwację i rozwijanie. Oznacza to, że będziesz w pełni przestrzegać zasady DRY.
Używanie atrybutów Typu danych
Movie.cs Otwórz plik i sprawdź klasęMovie.
System.ComponentModel.DataAnnotations Przestrzeń nazw udostępnia atrybuty formatowania oprócz wbudowanego zestawu atrybutów weryfikacji. Zastosowaliśmy już tę wartość wyliczenia do daty wydania i pól cenowych. Poniższy kod pokazuje właściwości ReleaseDate i Price z atrybutem DataType, który jest odpowiedni.
[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 dostarczają jedynie wskazówek dla aparatu wyświetlania, jak sformatować dane, i zapewniają elementy/atrybuty, takie jak <a> dla URL'u i <a href="mailto:EmailAddress.com"> dla adresu e-mail. Możesz użyć 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, nie są atrybutami walidacji. W tym przypadku chcemy śledzić tylko datę, a nie godzinę. Wyliczenie DataType zawiera wiele typów danych, takich jak Data, Godzina, Numer telefonu, Waluta, Adres e-mail i inne. Atrybut DataType może również umożliwić aplikacji automatyczne udostępnianie funkcji specyficznych dla typu. Na przykład można utworzyć link dla elementu mailto:, a selektor dat można zapewnić DataType.EmailAddress w przeglądarkach obsługujących HTML5. Atrybuty DataType emitują atrybuty HTML 5 data- (czytane jako data dash, czyli "kreska danych"), które przeglądarki HTML 5 mogą zrozumieć. Atrybuty DataTypenie zapewniają żadnej walidacji.
DataType.Date nie określa formatu wyświetlanej daty. Domyślnie pole danych jest wyświetlane zgodnie z domyślnie zdefiniowanymi formatami serwera CultureInfo.
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 powinno być również stosowane, gdy wartość jest wyświetlana w polu tekstowym do edycji. (Możesz nie chcieć tego dla niektórych pól — na przykład w przypadku wartości walutowych prawdopodobnie nie chcesz, aby symbol waluty w polu tekstowym był edytowany).
Możesz użyć atrybutu DisplayFormat samodzielnie, ale zazwyczaj warto skorzystać z atrybutu DataType. Atrybut DataType przekazuje semantyka danych, w przeciwieństwie do sposobu renderowania ich na ekranie, i zapewnia następujące korzyści, które nie są uzyskiwane za pomocą elementu 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 będzie renderować dane przy użyciu poprawnego formatu na podstawie ustawień regionalnych.
Atrybut
DataTypemoże umożliwić MVC wybranie odpowiedniego szablonu pola w celu renderowania danych (DisplayFormat, jeśli używany samodzielnie, używa szablonu dla ciągów).
Uwaga
Sprawdzanie poprawności zapytania 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")]
Aby użyć atrybutu Range z DateTime, należy wyłączyć walidację daty jQuery. Zazwyczaj nie jest dobrą praktyką używać konkretnych dat w modelach danych, dlatego odradza się korzystanie z atrybutów Range i DateTime.
Poniższy kod przedstawia łączenie atrybutów w jednym wierszu:
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; }
}
Zastosuj migracje
Niektóre atrybuty weryfikacji wpływają na schemat bazy danych. Na przykład [Required] tworzy kolumnę NOT NULL i [StringLength(60)] ogranicza typ kolumny do nvarchar(60). Uruchom migrację, aby zachować spójność schematu bazy danych z modelem.
W menu Tools wybierz pozycję NuGet Menedżer pakietów > Menedżer pakietów Console.
W usłudze PMC wprowadź następujące polecenia:
Add-Migration New_DataAnnotations
Update-Database
W następnej części serii przejrzymy aplikację i wprowadzimy pewne ulepszenia w metodach Details i Delete automatycznie wygenerowanych.
Treści powiązane
W tej sekcji:
- Logika walidacji jest dodawana do
Moviemodelu. - Upewnij się, że reguły walidacji są wymuszane za każdym razem, gdy użytkownik tworzy lub edytuje film.
Utrzymywanie suchych elementów
Jedną z zasad projektowania MVC jest DRY ("Nie powtarzaj się"). ASP.NET Core MVC zachęca do określenia funkcjonalności lub zachowania tylko raz, a następnie ich odzwierciedlenia wszędzie w aplikacji. Zmniejsza to ilość kodu potrzebnego do zapisania i sprawia, że kod, który zapisujesz mniej podatny na błędy, ułatwia testowanie i ułatwia konserwację.
Obsługa walidacji zapewniana przez MVC i Entity Framework Core Code First jest dobrym przykładem zasady DRY w działaniu. Reguły walidacji można deklaratywne określić w jednym miejscu (w klasie modelu), a reguły są wymuszane wszędzie w aplikacji.
Dodawanie reguł walidacji do modelu filmu
Przestrzeń nazw DataAnnotations udostępnia zestaw wbudowanych atrybutów weryfikacji, które są stosowane deklaratywnie do klasy lub właściwości. DataAnnotations zawiera również atrybuty formatowania, takie jak DataType, które pomagają w formatowaniu i nie zapewniają żadnej walidacji.
Zaktualizuj klasę Movie, aby korzystać z wbudowanych atrybutów weryfikacji Required, StringLength, RegularExpression, Range oraz atrybutu formatowania DataType.
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; }
}
Atrybuty weryfikacji określają zachowanie, które chcesz wymusić na właściwościach modelu, do których są stosowane:
Atrybuty
RequirediMinimumLengthwskazują, że właściwość musi mieć wartość, ale nic nie uniemożliwia użytkownikowi wprowadzania białych znaków w celu spełnienia tej weryfikacji.Atrybut
RegularExpressionsłuży do ograniczania liczby znaków, które mogą być wprowadzane jako dane wejściowe. W poprzednim kodzie w polu „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.
W atrybucie
RegularExpression„Rating” (Klasyfikacja):- Pierwszy znak musi być wielką literą.
- Pozwala na użycie znaków specjalnych i cyfr w kolejnych odstępach. Dla atrybutu "Rating" wartość „PG-13” jest prawidłowa, ale dla atrybutu "Genre" nie.
Atrybut
Rangeogranicza wartość do określonego zakresu.Atrybut
StringLengthumożliwia ustawienie maksymalnej długości właściwości ciągu i opcjonalnie jego minimalnej długości.Typy wartości (takie jak
decimal,int,float,DateTime) są z natury wymagane i nie wymagają atrybutu[Required].
Automatyczne wymuszanie reguł weryfikacji przez platformę ASP.NET Core pomaga zwiększyć niezawodność aplikacji. Gwarantuje to również, że nie zapomnisz o zweryfikowaniu czegoś i nie dopuścisz do przypadkowego wprowadzenia złych danych do bazy danych.
Błąd walidacji interfejsu użytkownika
Uruchom aplikację i przejdź do kontrolera Filmy.
Wybierz link Utwórz nowy, aby dodać nowy film. Wypełnij formularz kilkoma nieprawidłowymi wartościami. Gdy tylko walidacja po stronie klienta jQuery wykryje błąd, zostanie wyświetlony komunikat o błędzie.
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ż anglojęzyczne, które używają przecinka (",") jako separatora dziesiętnego, oraz dla formatów dat spoza USA, należy przeprowadzić globalizację aplikacji. Zobacz ten komentarz usługi GitHub 4076 , aby uzyskać instrukcje dotyczące dodawania przecinka dziesiętnego.
Zwróć uwagę, że formularz automatycznie renderował odpowiedni 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) i po stronie serwera (w przypadku wyłączenia języka JavaScript przez użytkownika).
Ważną korzyścią jest to, że aby włączyć ten interfejs weryfikacji, nie trzeba zmieniać pojedynczego wiersza kodu w klasie MoviesController lub w widoku Create.cshtml. Kontroler i widoki utworzone wcześniej w tym samouczku automatycznie rozpoznały reguły weryfikacji określone przy użyciu atrybutów weryfikacji we właściwościach klasy modelu Movie. Przetestuj walidację przy użyciu metody akcji Edit, a następnie zastosuj tę samą walidację.
Dane formularza nie są wysyłane do serwera, dopóki nie wystąpią żadne błędy weryfikacji po stronie klienta. Możesz to sprawdzić, ustawiając punkt przerwania w metodzie HTTP Post, za pomocą narzędzia Fiddler lub narzędzi programistycznych F12.
Jak działa walidacja
Możesz się zastanawiać, w jaki sposób wygenerowano interfejs weryfikacji użytkownika bez żadnych aktualizacji kodu w kontrolerze lub widokach. Poniższy kod przedstawia dwie Create metody.
// 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);
}
Pierwsza metoda akcji (HTTP GET) Create wyświetla początkowy formularz Utwórz. Druga wersja ([HttpPost]) obsługuje przesyłanie formularzy. Druga Create metoda (wersja [HttpPost] ) wywołuje metodę ModelState.IsValid w celu sprawdzenia, czy film ma jakiekolwiek błędy walidacji. Wywołanie tej metody ocenia wszystkie atrybuty walidacji, które zostały zastosowane do obiektu. Jeśli obiekt zawiera błędy weryfikacji, Create metoda ponownie wyświetli formularz. Jeśli nie ma żadnych błędów, metoda zapisuje nowy film w bazie danych. W naszym przykładzie filmu formularz nie jest publikowany na serwerze, gdy występują błędy walidacji wykryte po stronie klienta; druga Create metoda nigdy nie jest wywoływana, gdy występują błędy weryfikacji po stronie klienta. Jeśli wyłączysz język JavaScript w przeglądarce, walidacja klienta jest wyłączona i możesz przetestować metodę Create HTTP POSTModelState.IsValid, wykrywając błędy walidacji.
Możesz ustawić punkt przerwania w metodzie [HttpPost] Create i sprawdzić, czy metoda nigdy nie jest wywoływana, walidacja po stronie klienta nie będzie przesyłać danych formularza po wykryciu błędów walidacji. Jeśli wyłączysz JavaScript w przeglądarce, a następnie prześlesz formularz z błędami, zostanie osiągnięty punkt przerwania. Nadal uzyskujesz pełną walidację bez języka JavaScript.
Na poniższej ilustracji przedstawiono sposób wyłączania języka JavaScript w przeglądarce Firefox.
Na poniższej ilustracji przedstawiono sposób wyłączania języka JavaScript w przeglądarce Chrome.
Po wyłączeniu języka JavaScript opublikuj nieprawidłowe dane i przejdź przez debuger.
Część szablonu widoku Create.cshtml jest przedstawiona w następującym kodzie znaczników:
<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.*@
Powyższy znacznik jest używany przez metody działania do wyświetlania początkowego formularza i ponownego wyświetlenia go w przypadku błędu.
Naprawdę miło jest to, że ani kontroler, ani Create szablon widoku nie wie nic o rzeczywistych regułach walidacji, które są wymuszane, ani o wyświetlanych konkretnych komunikatach o błędach. Reguły walidacji i ciągi błędów są określone tylko w Movie klasie. Te same reguły sprawdzania poprawności są automatycznie stosowane do Edit widoku i wszystkich innych szablonów widoków, które można utworzyć, aby edytować model.
Jeśli musisz zmienić logikę weryfikacji, możesz to zrobić w dokładnie jednym miejscu, dodając atrybuty weryfikacji do modelu (w tym przykładzie Movie klasa). Nie trzeba martwić się o niespójność różnych części aplikacji ze sposobem wymuszania reguł — cała logika walidacji zostanie zdefiniowana w jednym miejscu i używana wszędzie. Dzięki temu kod jest bardzo czysty i ułatwia konserwację i rozwijanie. Oznacza to, że będziesz w pełni przestrzegać zasady DRY.
Używanie atrybutów Typu danych
Movie.cs Otwórz plik i sprawdź klasęMovie.
System.ComponentModel.DataAnnotations Przestrzeń nazw udostępnia atrybuty formatowania oprócz wbudowanego zestawu atrybutów weryfikacji. Zastosowaliśmy już tę wartość wyliczenia do daty wydania i pól cenowych. Poniższy kod pokazuje właściwości ReleaseDate i Price z atrybutem DataType, który jest odpowiedni.
[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 dostarczają jedynie wskazówek dla aparatu wyświetlania, jak sformatować dane, i zapewniają elementy/atrybuty, takie jak <a> dla URL'u i <a href="mailto:EmailAddress.com"> dla adresu e-mail. Możesz użyć 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, nie są atrybutami walidacji. W tym przypadku chcemy śledzić tylko datę, a nie godzinę. Wyliczenie DataType zawiera wiele typów danych, takich jak Data, Godzina, Numer telefonu, Waluta, Adres e-mail i inne. Atrybut DataType może również umożliwić aplikacji automatyczne udostępnianie funkcji specyficznych dla typu. Na przykład można utworzyć link dla elementu mailto:, a selektor dat można zapewnić DataType.EmailAddress w przeglądarkach obsługujących HTML5. Atrybuty DataType emitują atrybuty HTML 5 data- (czytane jako data dash, czyli "kreska danych"), które przeglądarki HTML 5 mogą zrozumieć. Atrybuty DataTypenie zapewniają żadnej walidacji.
DataType.Date nie określa formatu wyświetlanej daty. Domyślnie pole danych jest wyświetlane zgodnie z domyślnie zdefiniowanymi formatami serwera CultureInfo.
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 powinno być również stosowane, gdy wartość jest wyświetlana w polu tekstowym do edycji. (Możesz nie chcieć tego dla niektórych pól — na przykład w przypadku wartości walutowych prawdopodobnie nie chcesz, aby symbol waluty w polu tekstowym był edytowany).
Możesz użyć atrybutu DisplayFormat samodzielnie, ale zazwyczaj warto skorzystać z atrybutu DataType. Atrybut DataType przekazuje semantyka danych, w przeciwieństwie do sposobu renderowania ich na ekranie, i zapewnia następujące korzyści, które nie są uzyskiwane za pomocą elementu 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 będzie renderować dane przy użyciu poprawnego formatu na podstawie ustawień regionalnych.
Atrybut
DataTypemoże umożliwić MVC wybranie odpowiedniego szablonu pola w celu renderowania danych (DisplayFormat, jeśli używany samodzielnie, używa szablonu dla ciągów).
Uwaga
Sprawdzanie poprawności zapytania 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")]
Aby użyć atrybutu Range z DateTime, należy wyłączyć walidację daty jQuery. Zazwyczaj nie jest dobrą praktyką używać konkretnych dat w modelach danych, dlatego odradza się korzystanie z atrybutów Range i DateTime.
Poniższy kod przedstawia łączenie atrybutów w jednym wierszu:
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; }
}
Zastosuj migracje
Niektóre atrybuty weryfikacji wpływają na schemat bazy danych. Na przykład [Required] tworzy kolumnę NOT NULL i [StringLength(60)] ogranicza typ kolumny do nvarchar(60). Uruchom migrację, aby zachować spójność schematu bazy danych z modelem.
W menu Tools wybierz pozycję NuGet Menedżer pakietów > Menedżer pakietów Console.
W usłudze PMC wprowadź następujące polecenia:
Add-Migration New_DataAnnotations
Update-Database
W tej sekcji:
- Logika walidacji jest dodawana do
Moviemodelu. - Upewnij się, że reguły walidacji są wymuszane za każdym razem, gdy użytkownik tworzy lub edytuje film.
Utrzymywanie suchych elementów
Jedną z zasad projektowania MVC jest DRY ("Nie powtarzaj się"). ASP.NET Core MVC zachęca do określenia funkcjonalności lub zachowania tylko raz, a następnie ich odzwierciedlenia wszędzie w aplikacji. Zmniejsza to ilość kodu potrzebnego do zapisania i sprawia, że kod, który zapisujesz mniej podatny na błędy, ułatwia testowanie i ułatwia konserwację.
Obsługa walidacji zapewniana przez MVC i Entity Framework Core Code First jest dobrym przykładem zasady DRY w działaniu. Reguły walidacji można deklaratywne określić w jednym miejscu (w klasie modelu), a reguły są wymuszane wszędzie w aplikacji.
Dodawanie reguł walidacji do modelu filmu
Przestrzeń nazw DataAnnotations udostępnia zestaw wbudowanych atrybutów weryfikacji, które są stosowane deklaratywnie do klasy lub właściwości. DataAnnotations zawiera również atrybuty formatowania, takie jak DataType, które pomagają w formatowaniu i nie zapewniają żadnej walidacji.
Zaktualizuj klasę Movie, aby korzystać z wbudowanych atrybutów walidacji Required, StringLength, RegularExpression i Range.
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; }
}
}
Atrybuty weryfikacji określają zachowanie, które chcesz wymusić na właściwościach modelu, do których są stosowane:
Atrybuty
RequirediMinimumLengthwskazują, że właściwość musi mieć wartość, ale nic nie uniemożliwia użytkownikowi wprowadzania białych znaków w celu spełnienia tej weryfikacji.Atrybut
RegularExpressionsłuży do ograniczania liczby znaków, które mogą być wprowadzane jako dane wejściowe. W poprzednim kodzie w polu „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.
W atrybucie
RegularExpression„Rating” (Klasyfikacja):- Pierwszy znak musi być wielką literą.
- Pozwala na użycie znaków specjalnych i cyfr w kolejnych odstępach. Dla atrybutu "Rating" wartość „PG-13” jest prawidłowa, ale dla atrybutu "Genre" nie.
Atrybut
Rangeogranicza wartość do określonego zakresu.Atrybut
StringLengthumożliwia ustawienie maksymalnej długości właściwości ciągu i opcjonalnie jego minimalnej długości.Typy wartości (takie jak
decimal,int,float,DateTime) są z natury wymagane i nie wymagają atrybutu[Required].
Automatyczne wymuszanie reguł weryfikacji przez platformę ASP.NET Core pomaga zwiększyć niezawodność aplikacji. Gwarantuje to również, że nie zapomnisz o zweryfikowaniu czegoś i nie dopuścisz do przypadkowego wprowadzenia złych danych do bazy danych.
Błąd walidacji interfejsu użytkownika
Uruchom aplikację i przejdź do kontrolera Filmy.
Wybierz link Utwórz nowy, aby dodać nowy film. Wypełnij formularz kilkoma nieprawidłowymi wartościami. Gdy tylko walidacja po stronie klienta jQuery wykryje błąd, zostanie wyświetlony komunikat o błędzie.
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ż anglojęzyczne, które używają przecinka (",") jako separatora dziesiętnego, oraz dla formatów dat spoza USA, należy przeprowadzić globalizację aplikacji. Zobacz ten komentarz usługi GitHub 4076 , aby uzyskać instrukcje dotyczące dodawania przecinka dziesiętnego.
Zwróć uwagę, że formularz automatycznie renderował odpowiedni 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) i po stronie serwera (w przypadku wyłączenia języka JavaScript przez użytkownika).
Ważną korzyścią jest to, że aby włączyć ten interfejs weryfikacji, nie trzeba zmieniać pojedynczego wiersza kodu w klasie MoviesController lub w widoku Create.cshtml. Kontroler i widoki utworzone wcześniej w tym samouczku automatycznie rozpoznały reguły weryfikacji określone przy użyciu atrybutów weryfikacji we właściwościach klasy modelu Movie. Przetestuj walidację przy użyciu metody akcji Edit, a następnie zastosuj tę samą walidację.
Dane formularza nie są wysyłane do serwera, dopóki nie wystąpią żadne błędy weryfikacji po stronie klienta. Możesz to sprawdzić, ustawiając punkt przerwania w metodzie HTTP Post, za pomocą narzędzia Fiddler lub narzędzi programistycznych F12.
Jak działa walidacja
Możesz się zastanawiać, w jaki sposób wygenerowano interfejs weryfikacji użytkownika bez żadnych aktualizacji kodu w kontrolerze lub widokach. Poniższy kod przedstawia dwie Create metody.
// 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);
}
Pierwsza metoda akcji (HTTP GET) Create wyświetla początkowy formularz Utwórz. Druga wersja ([HttpPost]) obsługuje przesyłanie formularzy. Druga Create metoda (wersja [HttpPost] ) wywołuje metodę ModelState.IsValid w celu sprawdzenia, czy film ma jakiekolwiek błędy walidacji. Wywołanie tej metody ocenia wszystkie atrybuty walidacji, które zostały zastosowane do obiektu. Jeśli obiekt zawiera błędy weryfikacji, Create metoda ponownie wyświetli formularz. Jeśli nie ma żadnych błędów, metoda zapisuje nowy film w bazie danych. W naszym przykładzie filmu formularz nie jest publikowany na serwerze, gdy występują błędy walidacji wykryte po stronie klienta; druga Create metoda nigdy nie jest wywoływana, gdy występują błędy weryfikacji po stronie klienta. Jeśli wyłączysz język JavaScript w przeglądarce, walidacja klienta jest wyłączona i możesz przetestować metodę Create HTTP POSTModelState.IsValid, wykrywając błędy walidacji.
Możesz ustawić punkt przerwania w metodzie [HttpPost] Create i sprawdzić, czy metoda nigdy nie jest wywoływana, walidacja po stronie klienta nie będzie przesyłać danych formularza po wykryciu błędów walidacji. Jeśli wyłączysz JavaScript w przeglądarce, a następnie prześlesz formularz z błędami, zostanie osiągnięty punkt przerwania. Nadal uzyskujesz pełną walidację bez języka JavaScript.
Na poniższej ilustracji przedstawiono sposób wyłączania języka JavaScript w przeglądarce Firefox.
Na poniższej ilustracji przedstawiono sposób wyłączania języka JavaScript w przeglądarce Chrome.
Po wyłączeniu języka JavaScript opublikuj nieprawidłowe dane i przejdź przez debuger.
Część szablonu widoku Create.cshtml jest przedstawiona w następującym kodzie znaczników:
<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.*@
Powyższy znacznik jest używany przez metody działania do wyświetlania początkowego formularza i ponownego wyświetlenia go w przypadku błędu.
Naprawdę miło jest to, że ani kontroler, ani Create szablon widoku nie wie nic o rzeczywistych regułach walidacji, które są wymuszane, ani o wyświetlanych konkretnych komunikatach o błędach. Reguły walidacji i ciągi błędów są określone tylko w Movie klasie. Te same reguły sprawdzania poprawności są automatycznie stosowane do Edit widoku i wszystkich innych szablonów widoków, które można utworzyć, aby edytować model.
Jeśli musisz zmienić logikę weryfikacji, możesz to zrobić w dokładnie jednym miejscu, dodając atrybuty weryfikacji do modelu (w tym przykładzie Movie klasa). Nie trzeba martwić się o niespójność różnych części aplikacji ze sposobem wymuszania reguł — cała logika walidacji zostanie zdefiniowana w jednym miejscu i używana wszędzie. Dzięki temu kod jest bardzo czysty i ułatwia konserwację i rozwijanie. Oznacza to, że będziesz w pełni przestrzegać zasady DRY.
Używanie atrybutów Typu danych
Movie.cs Otwórz plik i sprawdź klasęMovie.
System.ComponentModel.DataAnnotations Przestrzeń nazw udostępnia atrybuty formatowania oprócz wbudowanego zestawu atrybutów weryfikacji. Zastosowaliśmy już tę wartość wyliczenia do daty wydania i pól cenowych. Poniższy kod pokazuje właściwości ReleaseDate i Price z atrybutem DataType, który jest odpowiedni.
[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 dostarczają jedynie wskazówek dla aparatu wyświetlania, jak sformatować dane, i zapewniają elementy/atrybuty, takie jak <a> dla URL'u i <a href="mailto:EmailAddress.com"> dla adresu e-mail. Możesz użyć 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, nie są atrybutami walidacji. W tym przypadku chcemy śledzić tylko datę, a nie godzinę. Wyliczenie DataType zawiera wiele typów danych, takich jak Data, Godzina, Numer telefonu, Waluta, Adres e-mail i inne. Atrybut DataType może również umożliwić aplikacji automatyczne udostępnianie funkcji specyficznych dla typu. Na przykład można utworzyć link dla elementu mailto:, a selektor dat można zapewnić DataType.EmailAddress w przeglądarkach obsługujących HTML5. Atrybuty DataType emitują atrybuty HTML 5 data- (czytane jako data dash, czyli "kreska danych"), które przeglądarki HTML 5 mogą zrozumieć. Atrybuty DataTypenie zapewniają żadnej walidacji.
DataType.Date nie określa formatu wyświetlanej daty. Domyślnie pole danych jest wyświetlane zgodnie z domyślnie zdefiniowanymi formatami serwera CultureInfo.
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 powinno być również stosowane, gdy wartość jest wyświetlana w polu tekstowym do edycji. (Możesz nie chcieć tego dla niektórych pól — na przykład w przypadku wartości walutowych prawdopodobnie nie chcesz, aby symbol waluty w polu tekstowym był edytowany).
Możesz użyć atrybutu DisplayFormat samodzielnie, ale zazwyczaj warto skorzystać z atrybutu DataType. Atrybut DataType przekazuje semantyka danych, w przeciwieństwie do sposobu renderowania ich na ekranie, i zapewnia następujące korzyści, które nie są uzyskiwane za pomocą elementu 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 będzie renderować dane przy użyciu poprawnego formatu na podstawie ustawień regionalnych.
Atrybut
DataTypemoże umożliwić MVC wybranie odpowiedniego szablonu pola w celu renderowania danych (DisplayFormat, jeśli używany samodzielnie, używa szablonu dla ciągów).
Uwaga
Sprawdzanie poprawności zapytania 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")]
Aby użyć atrybutu Range z DateTime, należy wyłączyć walidację daty jQuery. Zazwyczaj nie jest dobrą praktyką używać konkretnych dat w modelach danych, dlatego odradza się korzystanie z atrybutów Range i DateTime.
Poniższy kod przedstawia łączenie atrybutów w jednym wierszu:
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; }
}
}
Zastosuj migracje
Niektóre atrybuty weryfikacji wpływają na schemat bazy danych. Na przykład [Required] tworzy kolumnę NOT NULL i [StringLength(60)] ogranicza typ kolumny do nvarchar(60). Uruchom migrację, aby zachować spójność schematu bazy danych z modelem.
W menu Tools wybierz pozycję NuGet Menedżer pakietów > Menedżer pakietów Console.
W usłudze PMC wprowadź następujące polecenia:
Add-Migration New_DataAnnotations
Update-Database
W następnej części serii przejrzymy aplikację i wprowadzimy pewne ulepszenia w metodach Details i Delete automatycznie wygenerowanych.
Treści powiązane
W tej sekcji:
- Logika walidacji jest dodawana do
Moviemodelu. - Upewnij się, że reguły walidacji są wymuszane za każdym razem, gdy użytkownik tworzy lub edytuje film.
Utrzymywanie suchych elementów
Jedną z zasad projektowania MVC jest DRY ("Nie powtarzaj się"). ASP.NET Core MVC zachęca do określenia funkcjonalności lub zachowania tylko raz, a następnie ich odzwierciedlenia wszędzie w aplikacji. Zmniejsza to ilość kodu potrzebnego do zapisania i sprawia, że kod, który zapisujesz mniej podatny na błędy, ułatwia testowanie i ułatwia konserwację.
Obsługa walidacji zapewniana przez MVC i Entity Framework Core Code First jest dobrym przykładem zasady DRY w działaniu. Reguły walidacji można deklaratywne określić w jednym miejscu (w klasie modelu), a reguły są wymuszane wszędzie w aplikacji.
Dodawanie reguł walidacji do modelu filmu
Przestrzeń nazw DataAnnotations udostępnia zestaw wbudowanych atrybutów weryfikacji, które są stosowane deklaratywnie do klasy lub właściwości. DataAnnotations zawiera również atrybuty formatowania, takie jak DataType, które pomagają w formatowaniu i nie zapewniają żadnej walidacji.
Zaktualizuj klasę Movie, aby korzystać z wbudowanych atrybutów walidacji Required, StringLength, RegularExpression i Range.
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 weryfikacji określają zachowanie, które chcesz wymusić na właściwościach modelu, do których są stosowane:
Atrybuty
RequirediMinimumLengthwskazują, że właściwość musi mieć wartość, ale nic nie uniemożliwia użytkownikowi wprowadzania białych znaków w celu spełnienia tej weryfikacji.Atrybut
RegularExpressionsłuży do ograniczania liczby znaków, które mogą być wprowadzane jako dane wejściowe. W poprzednim kodzie w polu „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.
W atrybucie
RegularExpression„Rating” (Klasyfikacja):- Pierwszy znak musi być wielką literą.
- Pozwala na użycie znaków specjalnych i cyfr w kolejnych odstępach. Dla atrybutu "Rating" wartość „PG-13” jest prawidłowa, ale dla atrybutu "Genre" nie.
Atrybut
Rangeogranicza wartość do określonego zakresu.Atrybut
StringLengthumożliwia ustawienie maksymalnej długości właściwości ciągu i opcjonalnie jego minimalnej długości.Typy wartości (takie jak
decimal,int,float,DateTime) są z natury wymagane i nie wymagają atrybutu[Required].
Automatyczne wymuszanie reguł weryfikacji przez platformę ASP.NET Core pomaga zwiększyć niezawodność aplikacji. Gwarantuje to również, że nie zapomnisz o zweryfikowaniu czegoś i nie dopuścisz do przypadkowego wprowadzenia złych danych do bazy danych.
Błąd walidacji interfejsu użytkownika
Uruchom aplikację i przejdź do kontrolera Filmy.
Naciśnij łącze Utwórz nowy, aby dodać nowy film. Wypełnij formularz kilkoma nieprawidłowymi wartościami. Gdy tylko walidacja po stronie klienta jQuery wykryje błąd, zostanie wyświetlony komunikat o błędzie.
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ż anglojęzyczne, które używają przecinka (",") jako separatora dziesiętnego, oraz dla formatów dat spoza USA, należy przeprowadzić globalizację aplikacji. Zobacz ten komentarz usługi GitHub 4076 , aby uzyskać instrukcje dotyczące dodawania przecinka dziesiętnego.
Zwróć uwagę, że formularz automatycznie renderował odpowiedni 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) i po stronie serwera (w przypadku wyłączenia języka JavaScript przez użytkownika).
Ważną korzyścią jest to, że aby włączyć ten interfejs weryfikacji, nie trzeba zmieniać pojedynczego wiersza kodu w klasie MoviesController lub w widoku Create.cshtml. Kontroler i widoki utworzone wcześniej w tym samouczku automatycznie rozpoznały reguły weryfikacji określone przy użyciu atrybutów weryfikacji we właściwościach klasy modelu Movie. Przetestuj walidację przy użyciu metody akcji Edit, a następnie zastosuj tę samą walidację.
Dane formularza nie są wysyłane do serwera, dopóki nie wystąpią żadne błędy weryfikacji po stronie klienta. Możesz to sprawdzić, ustawiając punkt przerwania w metodzie HTTP Post, za pomocą narzędzia Fiddler lub narzędzi programistycznych F12.
Jak działa walidacja
Możesz się zastanawiać, w jaki sposób wygenerowano interfejs weryfikacji użytkownika bez żadnych aktualizacji kodu w kontrolerze lub widokach. Poniższy kod przedstawia dwie Create metody.
// 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);
}
Pierwsza metoda akcji (HTTP GET) Create wyświetla początkowy formularz Utwórz. Druga wersja ([HttpPost]) obsługuje przesyłanie formularzy. Druga Create metoda (wersja [HttpPost] ) wywołuje metodę ModelState.IsValid w celu sprawdzenia, czy film ma jakiekolwiek błędy walidacji. Wywołanie tej metody ocenia wszystkie atrybuty walidacji, które zostały zastosowane do obiektu. Jeśli obiekt zawiera błędy weryfikacji, Create metoda ponownie wyświetli formularz. Jeśli nie ma żadnych błędów, metoda zapisuje nowy film w bazie danych. W naszym przykładzie filmu formularz nie jest publikowany na serwerze, gdy występują błędy walidacji wykryte po stronie klienta; druga Create metoda nigdy nie jest wywoływana, gdy występują błędy weryfikacji po stronie klienta. Jeśli wyłączysz język JavaScript w przeglądarce, walidacja klienta jest wyłączona i możesz przetestować metodę Create HTTP POSTModelState.IsValid, wykrywając błędy walidacji.
Możesz ustawić punkt przerwania w metodzie [HttpPost] Create i sprawdzić, czy metoda nigdy nie jest wywoływana, walidacja po stronie klienta nie będzie przesyłać danych formularza po wykryciu błędów walidacji. Jeśli wyłączysz JavaScript w przeglądarce, a następnie prześlesz formularz z błędami, zostanie osiągnięty punkt przerwania. Nadal uzyskujesz pełną walidację bez języka JavaScript.
Na poniższej ilustracji przedstawiono sposób wyłączania języka JavaScript w przeglądarce Firefox.
Na poniższej ilustracji przedstawiono sposób wyłączania języka JavaScript w przeglądarce Chrome.
Po wyłączeniu języka JavaScript opublikuj nieprawidłowe dane i przejdź przez debuger.
Część szablonu Create.cshtml widoku jest wyświetlana w następującym znaczniku:
<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.*@
Powyższy znacznik jest używany przez metody działania do wyświetlania początkowego formularza i ponownego wyświetlenia go w przypadku błędu.
Naprawdę miło jest to, że ani kontroler, ani Create szablon widoku nie wie nic o rzeczywistych regułach walidacji, które są wymuszane, ani o wyświetlanych konkretnych komunikatach o błędach. Reguły walidacji i ciągi błędów są określone tylko w Movie klasie. Te same reguły sprawdzania poprawności są automatycznie stosowane do Edit widoku i wszystkich innych szablonów widoków, które można utworzyć, aby edytować model.
Jeśli musisz zmienić logikę weryfikacji, możesz to zrobić w dokładnie jednym miejscu, dodając atrybuty weryfikacji do modelu (w tym przykładzie Movie klasa). Nie trzeba martwić się o niespójność różnych części aplikacji ze sposobem wymuszania reguł — cała logika walidacji zostanie zdefiniowana w jednym miejscu i używana wszędzie. Dzięki temu kod jest bardzo czysty i ułatwia konserwację i rozwijanie. Oznacza to, że będziesz w pełni przestrzegać zasady DRY.
Używanie atrybutów Typu danych
Movie.cs Otwórz plik i sprawdź klasęMovie.
System.ComponentModel.DataAnnotations Przestrzeń nazw udostępnia atrybuty formatowania oprócz wbudowanego zestawu atrybutów weryfikacji. Zastosowaliśmy już tę wartość wyliczenia do daty wydania i pól cenowych. Poniższy kod pokazuje właściwości ReleaseDate i Price z atrybutem DataType, który jest odpowiedni.
[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 dostarczają tylko wskazówki dla aparatu wyświetlania, aby sformatować dane, w tym elementy/atrybuty takie jak <a> dla URL i <a href="mailto:EmailAddress.com"> dla e-mail. Możesz użyć 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, nie są atrybutami walidacji. W tym przypadku chcemy śledzić tylko datę, a nie godzinę. Wyliczenie DataType zawiera wiele typów danych, takich jak Data, Godzina, Numer telefonu, Waluta, Adres e-mail i inne. Atrybut DataType może również umożliwić aplikacji automatyczne udostępnianie funkcji specyficznych dla typu. Na przykład można utworzyć link dla elementu mailto:, a selektor dat można zapewnić DataType.EmailAddress w przeglądarkach obsługujących HTML5. Atrybuty DataType emitują atrybuty HTML 5 data- (czytane jako data dash, czyli "kreska danych"), które przeglądarki HTML 5 mogą zrozumieć. Atrybuty DataTypenie zapewniają żadnej walidacji.
DataType.Date nie określa formatu wyświetlanej daty. Domyślnie pole danych jest wyświetlane zgodnie z domyślnie zdefiniowanymi formatami serwera CultureInfo.
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 powinno być również stosowane, gdy wartość jest wyświetlana w polu tekstowym do edycji. (Możesz nie chcieć tego dla niektórych pól — na przykład w przypadku wartości walutowych prawdopodobnie nie chcesz, aby symbol waluty w polu tekstowym był edytowany).
Możesz użyć atrybutu DisplayFormat samodzielnie, ale zazwyczaj warto skorzystać z atrybutu DataType. Atrybut DataType przekazuje semantyka danych, w przeciwieństwie do sposobu renderowania ich na ekranie, i zapewnia następujące korzyści, które nie są uzyskiwane za pomocą elementu 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 będzie renderować dane przy użyciu poprawnego formatu na podstawie ustawień regionalnych.
Atrybut
DataTypemoże umożliwić MVC wybranie odpowiedniego szablonu pola w celu renderowania danych (DisplayFormat, jeśli używany samodzielnie, używa szablonu dla ciągów).
Uwaga
Sprawdzanie poprawności zapytania 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")]
Aby użyć atrybutu Range z DateTime, należy wyłączyć walidację daty jQuery. Zazwyczaj nie jest dobrą praktyką używać konkretnych dat w modelach danych, dlatego odradza się korzystanie z atrybutów Range i DateTime.
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; }
}
W następnej części serii przejrzymy aplikację i wprowadzimy pewne ulepszenia w metodach Details i Delete automatycznie wygenerowanych.