Bagian 8 dari seri tutorial di Razor Pages

Catatan

Ini bukan versi terbaru dari artikel ini. Untuk rilis saat ini, lihat versi .NET 8 dari artikel ini.

Penting

Informasi ini berkaitan dengan produk pra-rilis yang mungkin dimodifikasi secara substansial sebelum dirilis secara komersial. Microsoft tidak memberikan jaminan, tersirat maupun tersurat, sehubungan dengan informasi yang diberikan di sini.

Untuk rilis saat ini, lihat versi .NET 8 dari artikel ini.

Oleh Rick Anderson

Di bagian ini, logika validasi ditambahkan ke Movie model. Aturan validasi diberlakukan setiap kali pengguna membuat atau mengedit film.

Validasi

Tenet kunci pengembangan perangkat lunak disebut DRY ("Don't Repeat Yourself"). Razor Halaman mendorong pengembangan di mana fungsionalitas ditentukan sekali, dan tercermin di seluruh aplikasi. DRY dapat membantu:

  • Kurangi jumlah kode dalam aplikasi.
  • Jadikan kode kurang rawan kesalahan, dan lebih mudah diuji dan dikelola.

Dukungan validasi yang diberikan oleh Razor Pages dan Entity Framework adalah contoh prinsip DRY yang baik:

  • Aturan validasi ditentukan secara deklaratif di satu tempat, di kelas model.
  • Aturan diberlakukan di mana saja di aplikasi.

Menambahkan aturan validasi ke model film

Namespace System.ComponentModel.DataAnnotations layanan menyediakan:

  • Sekumpulan atribut validasi bawaan yang diterapkan secara deklaratif ke kelas atau properti.
  • Memformat atribut seperti [DataType] itu membantu pemformatan dan tidak memberikan validasi apa pun.

Movie Perbarui kelas untuk memanfaatkan atribut validasi bawaan [Required], , [StringLength][RegularExpression], dan [Range] .

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

Atribut validasi menentukan perilaku yang akan diberlakukan pada properti model tempatnya diterapkan:

  • Atribut [Required] dan [MinimumLength] menunjukkan bahwa properti harus memiliki nilai. Tidak ada yang mencegah pengguna memasuki spasi kosong untuk memenuhi validasi ini.

  • Atribut [RegularExpression] digunakan untuk membatasi karakter apa yang dapat dimasukkan. Dalam kode sebelumnya, Genre:

    • Hanya boleh menggunakan huruf.
    • Huruf pertama harus huruf besar. Spasi kosong diperbolehkan, sementara angka dan karakter khusus tidak diizinkan.
  • RegularExpressionRating:

    • Mengharuskan karakter pertama berupa huruf besar.
    • Mengizinkan karakter dan angka khusus di spasi berikutnya. "PG-13" berlaku untuk peringkat, tetapi gagal untuk Genre.
  • Atribut [Range] membatasi nilai dalam rentang yang ditentukan.

  • Atribut [StringLength] dapat mengatur panjang maksimum properti string, dan secara opsional panjang minimumnya.

  • Jenis nilai, seperti decimal, , intfloat, DateTime, secara inheren diperlukan dan tidak memerlukan [Required] atribut .

Aturan validasi sebelumnya digunakan untuk demonstrasi, aturan tersebut tidak optimal untuk sistem produksi. Misalnya, sebelumnya mencegah memasukkan film hanya dengan dua karakter dan tidak mengizinkan karakter khusus di Genre.

Memiliki aturan validasi yang secara otomatis diberlakukan oleh ASP.NET Core membantu:

  • Membuat aplikasi lebih kuat.
  • Mengurangi kemungkinan menyimpan data yang tidak valid ke database.

UI Kesalahan Validasi di Razor Halaman

Jalankan aplikasi dan navigasi ke Halaman/Film.

Pilih tautan Buat Baru . Lengkapi formulir dengan beberapa nilai yang tidak valid. Ketika validasi sisi klien jQuery mendeteksi kesalahan, validasi menampilkan pesan kesalahan.

Formulir tampilan film dengan beberapa kesalahan validasi sisi klien jQuery

Catatan

Anda mungkin tidak dapat memasukkan koma desimal di bidang desimal. Untuk mendukung validasi jQuery untuk lokal non-Bahasa Inggris yang menggunakan koma (",") untuk format tanggal desimal, dan non-Bahasa Inggris AS, Anda harus mengambil langkah-langkah untuk meng globalisasi aplikasi Anda. Lihat komentar GitHub 4076 ini untuk instruksi tentang menambahkan koma desimal.

Perhatikan bagaimana formulir telah secara otomatis merender pesan kesalahan validasi di setiap bidang yang berisi nilai yang tidak valid. Kesalahan diberlakukan baik sisi klien, menggunakan JavaScript dan jQuery, dan sisi server, ketika pengguna menonaktifkan JavaScript.

Manfaat yang signifikan adalah bahwa tidak ada perubahan kode yang diperlukan di halaman Buat atau Edit. Setelah anotasi data diterapkan ke model, UI validasi diaktifkan. Halaman Razor yang dibuat dalam tutorial ini secara otomatis mengambil aturan validasi, menggunakan atribut validasi pada properti Movie kelas model. Uji validasi menggunakan halaman Edit, validasi yang sama diterapkan.

Data formulir tidak diposting ke server sampai tidak ada kesalahan validasi sisi klien. Verifikasi data formulir tidak diposting oleh satu atau beberapa pendekatan berikut:

  • Letakkan titik henti dalam OnPostAsync metode . Kirim formulir dengan memilih Buat atau Simpan. Titik henti tidak pernah tertembak.
  • Gunakan alat Fiddler.
  • Gunakan alat pengembang browser untuk memantau lalu lintas jaringan.

Validasi sisi server

Ketika JavaScript dinonaktifkan di browser, mengirimkan formulir dengan kesalahan akan memposting ke server.

Opsional, uji validasi sisi server:

  1. Nonaktifkan JavaScript di browser. JavaScript dapat dinonaktifkan menggunakan alat pengembang browser. Jika JavaScript tidak dapat dinonaktifkan di browser, coba browser lain.

  2. Atur OnPostAsync titik henti dalam metode halaman Buat atau Edit.

  3. Kirim formulir dengan data yang tidak valid.

  4. Verifikasi bahwa status model tidak valid:

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

Atau, Nonaktifkan validasi sisi klien di server.

Kode berikut menunjukkan sebagian halaman yang Create.cshtml di-scaffold sebelumnya dalam tutorial. Ini digunakan oleh halaman Buat dan Edit untuk:

  • Tampilkan formulir awal.
  • Putar ulang formulir jika terjadi kesalahan.
<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>

Pembantu Tag Input menggunakan atribut DataAnnotations dan menghasilkan atribut HTML yang diperlukan untuk Validasi jQuery di sisi klien. Pembantu Tag Validasi menampilkan kesalahan validasi. Lihat Validasi untuk informasi selengkapnya.

Halaman Buat dan Edit tidak memiliki aturan validasi di dalamnya. Aturan validasi dan string kesalahan hanya ditentukan di Movie kelas . Aturan validasi ini secara otomatis diterapkan ke Razor Halaman yang mengedit Movie model.

Ketika logika validasi perlu berubah, itu hanya dilakukan dalam model. Validasi diterapkan secara konsisten di seluruh aplikasi, logika validasi ditentukan di satu tempat. Validasi di satu tempat membantu menjaga kode tetap bersih, dan membuatnya lebih mudah untuk dipertahankan dan diperbarui.

Menggunakan Atribut DataType

Periksa kelas.Movie Namespace System.ComponentModel.DataAnnotations menyediakan atribut pemformatan selain kumpulan atribut validasi bawaan. Atribut [DataType] diterapkan ke ReleaseDate properti dan 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; }

Atribut [DataType] menyediakan:

  • Petunjuk untuk mesin tampilan untuk memformat data.
  • Menyediakan atribut seperti <a> untuk URL dan <a href="mailto:EmailAddress.com"> untuk email.

[RegularExpression] Gunakan atribut untuk memvalidasi format data. Atribut [DataType] digunakan untuk menentukan jenis data yang lebih spesifik daripada jenis intrinsik database. [DataType] atribut bukan atribut validasi. Di aplikasi sampel, hanya tanggal yang ditampilkan, tanpa waktu.

Enumerasi DataType menyediakan banyak jenis data, seperti Date, , Time, PhoneNumberCurrency, EmailAddress, dan banyak lagi.

Atribut [DataType] :

  • Dapat memungkinkan aplikasi untuk secara otomatis menyediakan fitur khusus jenis. Misalnya, mailto: tautan dapat dibuat untuk DataType.EmailAddress.
  • Dapat menyediakan pemilih DataType.Date tanggal di browser yang mendukung HTML5.
  • Keluarkan HTML 5 data-, diucapkan "tanda hubung data", atribut yang digunakan browser HTML 5.
  • Jangan berikan validasi apa pun.

DataType.Date tidak menentukan format tanggal yang ditampilkan. Secara default, bidang data ditampilkan sesuai dengan format default berdasarkan CultureInfoserver .

Anotasi [Column(TypeName = "decimal(18, 2)")] data diperlukan sehingga Entity Framework Core dapat memetakan Price mata uang dengan benar dalam database. Untuk informasi selengkapnya, lihat Jenis Data.

Atribut [DisplayFormat] digunakan untuk secara eksplisit menentukan format tanggal:

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

Pengaturan ApplyFormatInEditMode menentukan bahwa pemformatan akan diterapkan saat nilai ditampilkan untuk pengeditan. Perilaku tersebut mungkin tidak diinginkan untuk beberapa bidang. Misalnya, dalam nilai mata uang, simbol mata uang biasanya tidak diinginkan dalam antarmuka pengguna edit.

Atribut [DisplayFormat] dapat digunakan dengan sendirinya, tetapi umumnya merupakan ide yang baik untuk menggunakan [DataType] atribut . Atribut [DataType] menyampaikan semantik data dibandingkan dengan cara merendernya di layar. Atribut [DataType] memberikan manfaat berikut yang tidak tersedia dengan [DisplayFormat]:

  • Browser dapat mengaktifkan fitur HTML5, misalnya untuk menampilkan kontrol kalender, simbol mata uang yang sesuai dengan lokal, tautan email, dll.
  • Secara default, browser merender data menggunakan format yang benar berdasarkan lokalnya.
  • Atribut [DataType] dapat mengaktifkan kerangka kerja ASP.NET Core untuk memilih templat bidang yang tepat untuk merender data. DisplayFormat, jika digunakan dengan sendirinya, menggunakan templat string.

Catatan: Validasi jQuery tidak berfungsi dengan [Range] atribut dan DateTime. Misalnya, kode berikut akan selalu menampilkan kesalahan validasi sisi klien, bahkan ketika tanggal berada dalam rentang yang ditentukan:

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

Ini adalah praktik terbaik untuk menghindari kompilasi tanggal keras dalam model, jadi menggunakan [Range] atribut dan DateTime tidak dianjurkan. Gunakan Konfigurasi untuk rentang tanggal dan nilai lain yang sering berubah daripada menentukannya dalam kode.

Kode berikut menunjukkan menggabungkan atribut pada satu baris:

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

Mulai menggunakan Razor Pages danEF Coreperlihatkan operasi tingkat lanjut EF Core dengan Razor Pages.

Menerapkan migrasi

DataAnnotations yang diterapkan ke kelas mengubah skema. Misalnya, DataAnnotations diterapkan ke Title bidang :

[StringLength(60, MinimumLength = 3)]
[Required]
public string Title { get; set; } = string.Empty;
  • Membatasi karakter menjadi 60.
  • Tidak mengizinkan null nilai.

Tabel Movie saat ini memiliki skema berikut:

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

Perubahan skema sebelumnya tidak menyebabkan EF melemparkan pengecualian. Namun, buat migrasi sehingga skema konsisten dengan model.

Dari menu Alat , pilih NuGet Package Manager > Package Manager Console. Di PMC, masukkan perintah berikut:

Add-Migration New_DataAnnotations
Update-Database

Update-DatabaseUp menjalankan metode New_DataAnnotations kelas .

Periksa Up metode :

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

Tabel yang diperbarui Movie memiliki skema berikut:

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

Menerbitkan ke Azure

Untuk informasi tentang penyebaran ke Azure, lihat Tutorial: Membuat aplikasi ASP.NET Core di Azure dengan SQL Database.

Terima kasih telah menyelesaikan pengenalan Razor Halaman ini. Mulai menggunakan Razor Pages dan EF Core merupakan tindak lanjut yang sangat baik untuk tutorial ini.

Sumber Daya Tambahan:

Langkah berikutnya

Di bagian ini, logika validasi ditambahkan ke Movie model. Aturan validasi diberlakukan setiap kali pengguna membuat atau mengedit film.

Validasi

Tenet kunci pengembangan perangkat lunak disebut DRY ("Don't Repeat Yourself"). Razor Halaman mendorong pengembangan di mana fungsionalitas ditentukan sekali, dan tercermin di seluruh aplikasi. DRY dapat membantu:

  • Kurangi jumlah kode dalam aplikasi.
  • Jadikan kode kurang rawan kesalahan, dan lebih mudah diuji dan dikelola.

Dukungan validasi yang diberikan oleh Razor Pages dan Entity Framework adalah contoh prinsip DRY yang baik:

  • Aturan validasi ditentukan secara deklaratif di satu tempat, di kelas model.
  • Aturan diberlakukan di mana saja di aplikasi.

Menambahkan aturan validasi ke model film

Namespace System.ComponentModel.DataAnnotations layanan menyediakan:

  • Sekumpulan atribut validasi bawaan yang diterapkan secara deklaratif ke kelas atau properti.
  • Memformat atribut seperti [DataType] itu membantu pemformatan dan tidak memberikan validasi apa pun.

Movie Perbarui kelas untuk memanfaatkan atribut validasi bawaan [Required], , [StringLength][RegularExpression], dan [Range] .

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

Atribut validasi menentukan perilaku yang akan diberlakukan pada properti model tempatnya diterapkan:

  • Atribut [Required] dan [MinimumLength] menunjukkan bahwa properti harus memiliki nilai. Tidak ada yang mencegah pengguna memasuki spasi kosong untuk memenuhi validasi ini.

  • Atribut [RegularExpression] digunakan untuk membatasi karakter apa yang dapat dimasukkan. Dalam kode sebelumnya, Genre:

    • Hanya boleh menggunakan huruf.
    • Huruf pertama harus huruf besar. Spasi kosong diperbolehkan sementara angka, dan karakter khusus tidak diperbolehkan.
  • RegularExpressionRating:

    • Mengharuskan karakter pertama berupa huruf besar.
    • Mengizinkan karakter dan angka khusus di spasi berikutnya. "PG-13" berlaku untuk peringkat, tetapi gagal untuk Genre.
  • Atribut [Range] membatasi nilai dalam rentang yang ditentukan.

  • Atribut [StringLength] dapat mengatur panjang maksimum properti string, dan secara opsional panjang minimumnya.

  • Jenis nilai, seperti decimal, , intfloat, DateTime, secara inheren diperlukan dan tidak memerlukan [Required] atribut .

Aturan validasi sebelumnya digunakan untuk demonstrasi, aturan tersebut tidak optimal untuk sistem produksi. Misalnya, sebelumnya mencegah memasukkan film hanya dengan dua karakter dan tidak mengizinkan karakter khusus di Genre.

Memiliki aturan validasi yang secara otomatis diberlakukan oleh ASP.NET Core membantu:

  • Membuat aplikasi lebih kuat.
  • Mengurangi kemungkinan menyimpan data yang tidak valid ke database.

UI Kesalahan Validasi di Razor Halaman

Jalankan aplikasi dan navigasi ke Halaman/Film.

Pilih tautan Buat Baru . Lengkapi formulir dengan beberapa nilai yang tidak valid. Ketika validasi sisi klien jQuery mendeteksi kesalahan, validasi menampilkan pesan kesalahan.

Formulir tampilan film dengan beberapa kesalahan validasi sisi klien jQuery

Catatan

Anda mungkin tidak dapat memasukkan koma desimal di bidang desimal. Untuk mendukung validasi jQuery untuk lokal non-Bahasa Inggris yang menggunakan koma (",") untuk format tanggal desimal, dan non-Bahasa Inggris AS, Anda harus mengambil langkah-langkah untuk meng globalisasi aplikasi Anda. Lihat komentar GitHub 4076 ini untuk instruksi tentang menambahkan koma desimal.

Perhatikan bagaimana formulir telah secara otomatis merender pesan kesalahan validasi di setiap bidang yang berisi nilai yang tidak valid. Kesalahan diberlakukan baik sisi klien, menggunakan JavaScript dan jQuery, dan sisi server, ketika pengguna menonaktifkan JavaScript.

Manfaat yang signifikan adalah bahwa tidak ada perubahan kode yang diperlukan di halaman Buat atau Edit. Setelah anotasi data diterapkan ke model, UI validasi diaktifkan. Halaman Razor yang dibuat dalam tutorial ini secara otomatis mengambil aturan validasi, menggunakan atribut validasi pada properti Movie kelas model. Uji validasi menggunakan halaman Edit, validasi yang sama diterapkan.

Data formulir tidak diposting ke server sampai tidak ada kesalahan validasi sisi klien. Verifikasi data formulir tidak diposting oleh satu atau beberapa pendekatan berikut:

  • Letakkan titik henti dalam OnPostAsync metode . Kirim formulir dengan memilih Buat atau Simpan. Titik henti tidak pernah tertembak.
  • Gunakan alat Fiddler.
  • Gunakan alat pengembang browser untuk memantau lalu lintas jaringan.

Validasi sisi server

Ketika JavaScript dinonaktifkan di browser, mengirimkan formulir dengan kesalahan akan memposting ke server.

Opsional, uji validasi sisi server:

  1. Nonaktifkan JavaScript di browser. JavaScript dapat dinonaktifkan menggunakan alat pengembang browser. Jika JavaScript tidak dapat dinonaktifkan di browser, coba browser lain.

  2. Atur OnPostAsync titik henti dalam metode halaman Buat atau Edit.

  3. Kirim formulir dengan data yang tidak valid.

  4. Verifikasi bahwa status model tidak valid:

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

Atau, Nonaktifkan validasi sisi klien di server.

Kode berikut menunjukkan sebagian halaman yang Create.cshtml di-scaffold sebelumnya dalam tutorial. Ini digunakan oleh halaman Buat dan Edit untuk:

  • Tampilkan formulir awal.
  • Putar ulang formulir jika terjadi kesalahan.
<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>

Pembantu Tag Input menggunakan atribut DataAnnotations dan menghasilkan atribut HTML yang diperlukan untuk Validasi jQuery di sisi klien. Pembantu Tag Validasi menampilkan kesalahan validasi. Lihat Validasi untuk informasi selengkapnya.

Halaman Buat dan Edit tidak memiliki aturan validasi di dalamnya. Aturan validasi dan string kesalahan hanya ditentukan di Movie kelas . Aturan validasi ini secara otomatis diterapkan ke Razor Halaman yang mengedit Movie model.

Ketika logika validasi perlu berubah, itu hanya dilakukan dalam model. Validasi diterapkan secara konsisten di seluruh aplikasi, logika validasi ditentukan di satu tempat. Validasi di satu tempat membantu menjaga kode tetap bersih, dan membuatnya lebih mudah untuk dipertahankan dan diperbarui.

Menggunakan Atribut DataType

Periksa kelas.Movie Namespace System.ComponentModel.DataAnnotations menyediakan atribut pemformatan selain kumpulan atribut validasi bawaan. Atribut [DataType] diterapkan ke ReleaseDate properti dan 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; }

Atribut [DataType] menyediakan:

  • Petunjuk untuk mesin tampilan untuk memformat data.
  • Menyediakan atribut seperti <a> untuk URL dan <a href="mailto:EmailAddress.com"> untuk email.

[RegularExpression] Gunakan atribut untuk memvalidasi format data. Atribut [DataType] digunakan untuk menentukan jenis data yang lebih spesifik daripada jenis intrinsik database. [DataType] atribut bukan atribut validasi. Di aplikasi sampel, hanya tanggal yang ditampilkan, tanpa waktu.

Enumerasi DataType menyediakan banyak jenis data, seperti Date, , Time, PhoneNumberCurrency, EmailAddress, dan banyak lagi.

Atribut [DataType] :

  • Dapat memungkinkan aplikasi untuk secara otomatis menyediakan fitur khusus jenis. Misalnya, mailto: tautan dapat dibuat untuk DataType.EmailAddress.
  • Dapat menyediakan pemilih DataType.Date tanggal di browser yang mendukung HTML5.
  • Keluarkan HTML 5 data-, diucapkan "tanda hubung data", atribut yang digunakan browser HTML 5.
  • Jangan berikan validasi apa pun.

DataType.Date tidak menentukan format tanggal yang ditampilkan. Secara default, bidang data ditampilkan sesuai dengan format default berdasarkan CultureInfoserver .

Anotasi [Column(TypeName = "decimal(18, 2)")] data diperlukan sehingga Entity Framework Core dapat memetakan Price mata uang dengan benar dalam database. Untuk informasi selengkapnya, lihat Jenis Data.

Atribut [DisplayFormat] digunakan untuk secara eksplisit menentukan format tanggal:

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

Pengaturan ApplyFormatInEditMode menentukan bahwa pemformatan akan diterapkan saat nilai ditampilkan untuk pengeditan. Perilaku tersebut mungkin tidak diinginkan untuk beberapa bidang. Misalnya, dalam nilai mata uang, simbol mata uang biasanya tidak diinginkan dalam antarmuka pengguna edit.

Atribut [DisplayFormat] dapat digunakan dengan sendirinya, tetapi umumnya merupakan ide yang baik untuk menggunakan [DataType] atribut . Atribut [DataType] menyampaikan semantik data dibandingkan dengan cara merendernya di layar. Atribut [DataType] memberikan manfaat berikut yang tidak tersedia dengan [DisplayFormat]:

  • Browser dapat mengaktifkan fitur HTML5, misalnya untuk menampilkan kontrol kalender, simbol mata uang yang sesuai dengan lokal, tautan email, dll.
  • Secara default, browser merender data menggunakan format yang benar berdasarkan lokalnya.
  • Atribut [DataType] dapat mengaktifkan kerangka kerja ASP.NET Core untuk memilih templat bidang yang tepat untuk merender data. DisplayFormat, jika digunakan dengan sendirinya, menggunakan templat string.

Catatan: Validasi jQuery tidak berfungsi dengan [Range] atribut dan DateTime. Misalnya, kode berikut akan selalu menampilkan kesalahan validasi sisi klien, bahkan ketika tanggal berada dalam rentang yang ditentukan:

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

Ini adalah praktik terbaik untuk menghindari kompilasi tanggal keras dalam model, jadi menggunakan [Range] atribut dan DateTime tidak dianjurkan. Gunakan Konfigurasi untuk rentang tanggal dan nilai lain yang sering berubah daripada menentukannya dalam kode.

Kode berikut menunjukkan menggabungkan atribut pada satu baris:

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

Mulai menggunakan Razor Pages danEF Coreperlihatkan operasi tingkat lanjut EF Core dengan Razor Pages.

Menerapkan migrasi

DataAnnotations yang diterapkan ke kelas mengubah skema. Misalnya, DataAnnotations diterapkan ke Title bidang :

[StringLength(60, MinimumLength = 3)]
[Required]
public string Title { get; set; } = string.Empty;
  • Membatasi karakter menjadi 60.
  • Tidak mengizinkan null nilai.

Tabel Movie saat ini memiliki skema berikut:

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

Perubahan skema sebelumnya tidak menyebabkan EF melemparkan pengecualian. Namun, buat migrasi sehingga skema konsisten dengan model.

Dari menu Alat , pilih NuGet Package Manager > Package Manager Console. Di PMC, masukkan perintah berikut:

Add-Migration New_DataAnnotations
Update-Database

Update-DatabaseUp menjalankan metode New_DataAnnotations kelas .

Periksa Up metode :

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

Tabel yang diperbarui Movie memiliki skema berikut:

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

Menerbitkan ke Azure

Untuk informasi tentang penyebaran ke Azure, lihat Tutorial: Membuat aplikasi ASP.NET Core di Azure dengan SQL Database.

Terima kasih telah menyelesaikan pengenalan Razor Halaman ini. Mulai menggunakan Razor Pages dan EF Core merupakan tindak lanjut yang sangat baik untuk tutorial ini.

Sumber Daya Tambahan:

Langkah berikutnya

Di bagian ini, logika validasi ditambahkan ke Movie model. Aturan validasi diberlakukan setiap kali pengguna membuat atau mengedit film.

Validasi

Tenet kunci pengembangan perangkat lunak disebut DRY ("Don't Repeat Yourself"). Razor Halaman mendorong pengembangan di mana fungsionalitas ditentukan sekali, dan tercermin di seluruh aplikasi. DRY dapat membantu:

  • Kurangi jumlah kode dalam aplikasi.
  • Jadikan kode kurang rawan kesalahan, dan lebih mudah diuji dan dikelola.

Dukungan validasi yang diberikan oleh Razor Pages dan Entity Framework adalah contoh prinsip DRY yang baik:

  • Aturan validasi ditentukan secara deklaratif di satu tempat, di kelas model.
  • Aturan diberlakukan di mana saja di aplikasi.

Menambahkan aturan validasi ke model film

Namespace System.ComponentModel.DataAnnotations layanan menyediakan:

  • Sekumpulan atribut validasi bawaan yang diterapkan secara deklaratif ke kelas atau properti.
  • Memformat atribut seperti [DataType] itu membantu pemformatan dan tidak memberikan validasi apa pun.

Movie Perbarui kelas untuk memanfaatkan atribut validasi bawaan [Required], , [StringLength][RegularExpression], dan [Range] .

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

Atribut validasi menentukan perilaku yang akan diberlakukan pada properti model tempatnya diterapkan:

  • Atribut [Required] dan [MinimumLength] menunjukkan bahwa properti harus memiliki nilai. Tidak ada yang mencegah pengguna memasuki spasi kosong untuk memenuhi validasi ini.

  • Atribut [RegularExpression] digunakan untuk membatasi karakter apa yang dapat dimasukkan. Dalam kode sebelumnya, Genre:

    • Hanya boleh menggunakan huruf.
    • Huruf pertama harus huruf besar. Spasi kosong diperbolehkan sementara angka, dan karakter khusus tidak diperbolehkan.
  • RegularExpressionRating:

    • Mengharuskan karakter pertama berupa huruf besar.
    • Mengizinkan karakter dan angka khusus di spasi berikutnya. "PG-13" berlaku untuk peringkat, tetapi gagal untuk Genre.
  • Atribut [Range] membatasi nilai dalam rentang yang ditentukan.

  • Atribut [StringLength] dapat mengatur panjang maksimum properti string, dan secara opsional panjang minimumnya.

  • Jenis nilai, seperti decimal, , intfloat, DateTime, secara inheren diperlukan dan tidak memerlukan [Required] atribut .

Aturan validasi sebelumnya digunakan untuk demonstrasi, aturan tersebut tidak optimal untuk sistem produksi. Misalnya, sebelumnya mencegah memasukkan film hanya dengan dua karakter dan tidak mengizinkan karakter khusus di Genre.

Memiliki aturan validasi yang secara otomatis diberlakukan oleh ASP.NET Core membantu:

  • Membuat aplikasi lebih kuat.
  • Mengurangi kemungkinan menyimpan data yang tidak valid ke database.

UI Kesalahan Validasi di Razor Halaman

Jalankan aplikasi dan navigasi ke Halaman/Film.

Pilih tautan Buat Baru . Lengkapi formulir dengan beberapa nilai yang tidak valid. Ketika validasi sisi klien jQuery mendeteksi kesalahan, validasi menampilkan pesan kesalahan.

Formulir tampilan film dengan beberapa kesalahan validasi sisi klien jQuery

Catatan

Anda mungkin tidak dapat memasukkan koma desimal di bidang desimal. Untuk mendukung validasi jQuery untuk lokal non-Bahasa Inggris yang menggunakan koma (",") untuk format tanggal desimal, dan non-Bahasa Inggris AS, Anda harus mengambil langkah-langkah untuk meng globalisasi aplikasi Anda. Lihat komentar GitHub 4076 ini untuk instruksi tentang menambahkan koma desimal.

Perhatikan bagaimana formulir telah secara otomatis merender pesan kesalahan validasi di setiap bidang yang berisi nilai yang tidak valid. Kesalahan diberlakukan baik sisi klien, menggunakan JavaScript dan jQuery, dan sisi server, ketika pengguna menonaktifkan JavaScript.

Manfaat yang signifikan adalah bahwa tidak ada perubahan kode yang diperlukan di halaman Buat atau Edit. Setelah anotasi data diterapkan ke model, UI validasi diaktifkan. Halaman Razor yang dibuat dalam tutorial ini secara otomatis mengambil aturan validasi, menggunakan atribut validasi pada properti Movie kelas model. Uji validasi menggunakan halaman Edit, validasi yang sama diterapkan.

Data formulir tidak diposting ke server sampai tidak ada kesalahan validasi sisi klien. Verifikasi data formulir tidak diposting oleh satu atau beberapa pendekatan berikut:

  • Letakkan titik henti dalam OnPostAsync metode . Kirim formulir dengan memilih Buat atau Simpan. Titik henti tidak pernah tertembak.
  • Gunakan alat Fiddler.
  • Gunakan alat pengembang browser untuk memantau lalu lintas jaringan.

Validasi sisi server

Ketika JavaScript dinonaktifkan di browser, mengirimkan formulir dengan kesalahan akan memposting ke server.

Opsional, uji validasi sisi server:

  1. Nonaktifkan JavaScript di browser. JavaScript dapat dinonaktifkan menggunakan alat pengembang browser. Jika Anda tidak dapat menonaktifkan JavaScript di browser, coba browser lain.

  2. Atur OnPostAsync titik henti dalam metode halaman Buat atau Edit.

  3. Kirim formulir dengan data yang tidak valid.

  4. Verifikasi bahwa status model tidak valid:

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

Atau, Nonaktifkan validasi sisi klien di server.

Kode berikut menunjukkan sebagian halaman yang Create.cshtml di-scaffold sebelumnya dalam tutorial. Ini digunakan oleh halaman Buat dan Edit untuk:

  • Tampilkan formulir awal.
  • Putar ulang formulir jika terjadi kesalahan.
<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>

Pembantu Tag Input menggunakan atribut DataAnnotations dan menghasilkan atribut HTML yang diperlukan untuk Validasi jQuery di sisi klien. Pembantu Tag Validasi menampilkan kesalahan validasi. Lihat Validasi untuk informasi selengkapnya.

Halaman Buat dan Edit tidak memiliki aturan validasi di dalamnya. Aturan validasi dan string kesalahan hanya ditentukan di Movie kelas . Aturan validasi ini secara otomatis diterapkan ke Razor Halaman yang mengedit Movie model.

Ketika logika validasi perlu berubah, itu hanya dilakukan dalam model. Validasi diterapkan secara konsisten di seluruh aplikasi, logika validasi didefinisikan di satu tempat. Validasi di satu tempat membantu menjaga kode tetap bersih, dan membuatnya lebih mudah untuk dipertahankan dan diperbarui.

Menggunakan Atribut DataType

Periksa kelas.Movie Namespace System.ComponentModel.DataAnnotations menyediakan atribut pemformatan selain kumpulan atribut validasi bawaan. Atribut [DataType] diterapkan ke ReleaseDate properti dan 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; }

Atribut [DataType] menyediakan:

  • Petunjuk untuk mesin tampilan untuk memformat data.
  • Menyediakan atribut seperti <a> untuk URL dan <a href="mailto:EmailAddress.com"> untuk email.

[RegularExpression] Gunakan atribut untuk memvalidasi format data. Atribut [DataType] digunakan untuk menentukan jenis data yang lebih spesifik daripada jenis intrinsik database. [DataType] atribut bukan atribut validasi. Dalam aplikasi sampel, hanya tanggal yang ditampilkan, tanpa waktu.

Enumerasi DataType menyediakan banyak jenis data, seperti Date, , Time, PhoneNumberCurrency, EmailAddress, dan banyak lagi.

Atribut [DataType] :

  • Dapat memungkinkan aplikasi untuk secara otomatis menyediakan fitur khusus jenis. Misalnya, mailto: tautan dapat dibuat untuk DataType.EmailAddress.
  • Dapat menyediakan pemilih DataType.Date tanggal di browser yang mendukung HTML5.
  • Keluarkan HTML 5 data-, diucapkan "tanda hubung data", atribut yang digunakan browser HTML 5.
  • Jangan berikan validasi apa pun.

DataType.Date tidak menentukan format tanggal yang ditampilkan. Secara default, bidang data ditampilkan sesuai dengan format default berdasarkan CultureInfoserver .

Anotasi [Column(TypeName = "decimal(18, 2)")] data diperlukan sehingga Entity Framework Core dapat memetakan Price mata uang dengan benar dalam database. Untuk informasi selengkapnya, lihat Jenis Data.

Atribut [DisplayFormat] digunakan untuk secara eksplisit menentukan format tanggal:

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

Pengaturan ApplyFormatInEditMode menentukan bahwa pemformatan akan diterapkan saat nilai ditampilkan untuk pengeditan. Perilaku tersebut mungkin tidak diinginkan untuk beberapa bidang. Misalnya, dalam nilai mata uang, simbol mata uang biasanya tidak diinginkan dalam antarmuka pengguna edit.

Atribut [DisplayFormat] dapat digunakan dengan sendirinya, tetapi umumnya merupakan ide yang baik untuk menggunakan [DataType] atribut . Atribut [DataType] menyampaikan semantik data dibandingkan dengan cara merendernya di layar. Atribut [DataType] memberikan manfaat berikut yang tidak tersedia dengan [DisplayFormat]:

  • Browser dapat mengaktifkan fitur HTML5, misalnya untuk menampilkan kontrol kalender, simbol mata uang yang sesuai dengan lokal, tautan email, dll.
  • Secara default, browser merender data menggunakan format yang benar berdasarkan lokalnya.
  • Atribut [DataType] dapat mengaktifkan kerangka kerja ASP.NET Core untuk memilih templat bidang yang tepat untuk merender data. DisplayFormat, jika digunakan dengan sendirinya, menggunakan templat string.

Catatan: Validasi jQuery tidak berfungsi dengan [Range] atribut dan DateTime. Misalnya, kode berikut akan selalu menampilkan kesalahan validasi sisi klien, bahkan ketika tanggal berada dalam rentang yang ditentukan:

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

Ini adalah praktik terbaik untuk menghindari kompilasi tanggal keras dalam model, jadi menggunakan [Range] atribut dan DateTime tidak dianjurkan. Gunakan Konfigurasi untuk rentang tanggal dan nilai lain yang sering berubah daripada menentukannya dalam kode.

Kode berikut menunjukkan menggabungkan atribut pada satu baris:

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

Mulai menggunakan Razor Pages danEF Coreperlihatkan operasi tingkat lanjut EF Core dengan Razor Pages.

Menerapkan migrasi

DataAnnotations yang diterapkan ke kelas mengubah skema. Misalnya, DataAnnotations diterapkan ke Title bidang :

[StringLength(60, MinimumLength = 3)]
[Required]
public string Title { get; set; } = string.Empty;
  • Membatasi karakter menjadi 60.
  • Tidak mengizinkan null nilai.

Tabel Movie saat ini memiliki skema berikut:

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

Perubahan skema sebelumnya tidak menyebabkan EF melemparkan pengecualian. Namun, buat migrasi sehingga skema konsisten dengan model.

Dari menu Alat , pilih NuGet Package Manager > Package Manager Console. Di PMC, masukkan perintah berikut:

Add-Migration New_DataAnnotations
Update-Database

Update-DatabaseUp menjalankan metode New_DataAnnotations kelas .

Periksa Up metode :

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

Tabel yang diperbarui Movie memiliki skema berikut:

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

Menerbitkan ke Azure

Untuk informasi tentang penyebaran ke Azure, lihat Tutorial: Membuat aplikasi ASP.NET Core di Azure dengan SQL Database.

Terima kasih telah menyelesaikan pengenalan Razor Halaman ini. Mulai menggunakan Razor Pages dan EF Core merupakan tindak lanjut yang sangat baik untuk tutorial ini.

Sumber Daya Tambahan:

Langkah berikutnya

Di bagian ini, logika validasi ditambahkan ke Movie model. Aturan validasi diberlakukan setiap kali pengguna membuat atau mengedit film.

Validasi

Tenet kunci pengembangan perangkat lunak disebut DRY ("Don't Repeat Yourself"). Razor Halaman mendorong pengembangan di mana fungsionalitas ditentukan sekali, dan tercermin di seluruh aplikasi. DRY dapat membantu:

  • Kurangi jumlah kode dalam aplikasi.
  • Jadikan kode kurang rawan kesalahan, dan lebih mudah diuji dan dikelola.

Dukungan validasi yang diberikan oleh Razor Pages dan Entity Framework adalah contoh prinsip DRY yang baik:

  • Aturan validasi ditentukan secara deklaratif di satu tempat, di kelas model.
  • Aturan diberlakukan di mana saja di aplikasi.

Menambahkan aturan validasi ke model film

Namespace DataAnnotations layanan menyediakan:

  • Sekumpulan atribut validasi bawaan yang diterapkan secara deklaratif ke kelas atau properti.
  • Memformat atribut seperti [DataType] itu membantu pemformatan dan tidak memberikan validasi apa pun.

Movie Perbarui kelas untuk memanfaatkan atribut validasi bawaan [Required], , [StringLength][RegularExpression], dan [Range] .

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

Atribut validasi menentukan perilaku yang akan diberlakukan pada properti model tempatnya diterapkan:

  • Atribut [Required] dan [MinimumLength] menunjukkan bahwa properti harus memiliki nilai. Tidak ada yang mencegah pengguna memasuki spasi kosong untuk memenuhi validasi ini.

  • Atribut [RegularExpression] digunakan untuk membatasi karakter apa yang dapat dimasukkan. Dalam kode sebelumnya, Genre:

    • Hanya boleh menggunakan huruf.
    • Huruf pertama harus huruf besar. Spasi kosong diperbolehkan sementara angka, dan karakter khusus tidak diperbolehkan.
  • RegularExpressionRating:

    • Mengharuskan karakter pertama berupa huruf besar.
    • Mengizinkan karakter dan angka khusus di spasi berikutnya. "PG-13" berlaku untuk peringkat, tetapi gagal untuk Genre.
  • Atribut [Range] membatasi nilai dalam rentang yang ditentukan.

  • Atribut [StringLength] dapat mengatur panjang maksimum properti string, dan secara opsional panjang minimumnya.

  • Jenis nilai, seperti decimal, , intfloat, DateTime, secara inheren diperlukan dan tidak memerlukan [Required] atribut .

Aturan validasi sebelumnya digunakan untuk demonstrasi, aturan tersebut tidak optimal untuk sistem produksi. Misalnya, sebelumnya mencegah memasukkan film hanya dengan dua karakter dan tidak mengizinkan karakter khusus di Genre.

Memiliki aturan validasi yang secara otomatis diberlakukan oleh ASP.NET Core membantu:

  • Membuat aplikasi lebih kuat.
  • Mengurangi kemungkinan menyimpan data yang tidak valid ke database.

UI Kesalahan Validasi di Razor Halaman

Jalankan aplikasi dan navigasi ke Halaman/Film.

Pilih tautan Buat Baru . Lengkapi formulir dengan beberapa nilai yang tidak valid. Ketika validasi sisi klien jQuery mendeteksi kesalahan, validasi menampilkan pesan kesalahan.

Formulir tampilan film dengan beberapa kesalahan validasi sisi klien jQuery

Catatan

Anda mungkin tidak dapat memasukkan koma desimal di bidang desimal. Untuk mendukung validasi jQuery untuk lokal non-Bahasa Inggris yang menggunakan koma (",") untuk format tanggal desimal, dan non-Bahasa Inggris AS, Anda harus mengambil langkah-langkah untuk meng globalisasi aplikasi Anda. Lihat komentar GitHub 4076 ini untuk instruksi tentang menambahkan koma desimal.

Perhatikan bagaimana formulir telah secara otomatis merender pesan kesalahan validasi di setiap bidang yang berisi nilai yang tidak valid. Kesalahan diberlakukan baik sisi klien, menggunakan JavaScript dan jQuery, dan sisi server, ketika pengguna menonaktifkan JavaScript.

Manfaat yang signifikan adalah bahwa tidak ada perubahan kode yang diperlukan di halaman Buat atau Edit. Setelah anotasi data diterapkan ke model, UI validasi diaktifkan. Halaman Razor yang dibuat dalam tutorial ini secara otomatis mengambil aturan validasi, menggunakan atribut validasi pada properti Movie kelas model. Uji validasi menggunakan halaman Edit, validasi yang sama diterapkan.

Data formulir tidak diposting ke server sampai tidak ada kesalahan validasi sisi klien. Verifikasi data formulir tidak diposting oleh satu atau beberapa pendekatan berikut:

  • Letakkan titik henti dalam OnPostAsync metode . Kirim formulir dengan memilih Buat atau Simpan. Titik henti tidak pernah tertembak.
  • Gunakan alat Fiddler.
  • Gunakan alat pengembang browser untuk memantau lalu lintas jaringan.

Validasi sisi server

Ketika JavaScript dinonaktifkan di browser, mengirimkan formulir dengan kesalahan akan memposting ke server.

Opsional, uji validasi sisi server:

  1. Nonaktifkan JavaScript di browser. JavaScript dapat dinonaktifkan menggunakan alat pengembang browser. Jika JavaScript tidak dapat dinonaktifkan di browser, coba browser lain.

  2. Atur OnPostAsync titik henti dalam metode halaman Buat atau Edit.

  3. Kirim formulir dengan data yang tidak valid.

  4. Verifikasi bahwa status model tidak valid:

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

Atau, Nonaktifkan validasi sisi klien di server.

Kode berikut menunjukkan sebagian halaman yang Create.cshtml di-scaffold sebelumnya dalam tutorial. Ini digunakan oleh halaman Buat dan Edit untuk:

  • Tampilkan formulir awal.
  • Putar ulang formulir jika terjadi kesalahan.
<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>

Pembantu Tag Input menggunakan atribut DataAnnotations dan menghasilkan atribut HTML yang diperlukan untuk Validasi jQuery di sisi klien. Pembantu Tag Validasi menampilkan kesalahan validasi. Lihat Validasi untuk informasi selengkapnya.

Halaman Buat dan Edit tidak memiliki aturan validasi di dalamnya. Aturan validasi dan string kesalahan hanya ditentukan di Movie kelas . Aturan validasi ini secara otomatis diterapkan ke Razor Halaman yang mengedit Movie model.

Ketika logika validasi perlu berubah, itu hanya dilakukan dalam model. Validasi diterapkan secara konsisten di seluruh aplikasi, logika validasi didefinisikan di satu tempat. Validasi di satu tempat membantu menjaga kode tetap bersih, dan membuatnya lebih mudah untuk dipertahankan dan diperbarui.

Menggunakan Atribut DataType

Periksa kelas.Movie Namespace System.ComponentModel.DataAnnotations menyediakan atribut pemformatan selain kumpulan atribut validasi bawaan. Atribut [DataType] diterapkan ke ReleaseDate properti dan Price .

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

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

Atribut [DataType] menyediakan:

  • Petunjuk untuk mesin tampilan untuk memformat data.
  • Menyediakan atribut seperti <a> untuk URL dan <a href="mailto:EmailAddress.com"> untuk email.

[RegularExpression] Gunakan atribut untuk memvalidasi format data. Atribut [DataType] digunakan untuk menentukan jenis data yang lebih spesifik daripada jenis intrinsik database. [DataType] atribut bukan atribut validasi. Dalam aplikasi sampel, hanya tanggal yang ditampilkan, tanpa waktu.

Enumerasi DataType menyediakan banyak jenis data, seperti Date, , Time, PhoneNumberCurrency, EmailAddress, dan banyak lagi.

Atribut [DataType] :

  • Dapat memungkinkan aplikasi untuk secara otomatis menyediakan fitur khusus jenis. Misalnya, mailto: tautan dapat dibuat untuk DataType.EmailAddress.
  • Dapat menyediakan pemilih DataType.Date tanggal di browser yang mendukung HTML5.
  • Keluarkan HTML 5 data-, diucapkan "tanda hubung data", atribut yang digunakan browser HTML 5.
  • Jangan berikan validasi apa pun.

DataType.Date tidak menentukan format tanggal yang ditampilkan. Secara default, bidang data ditampilkan sesuai dengan format default berdasarkan CultureInfoserver .

Anotasi [Column(TypeName = "decimal(18, 2)")] data diperlukan sehingga Entity Framework Core dapat memetakan Price mata uang dengan benar dalam database. Untuk informasi selengkapnya, lihat Jenis Data.

Atribut [DisplayFormat] digunakan untuk secara eksplisit menentukan format tanggal:

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

Pengaturan ApplyFormatInEditMode menentukan bahwa pemformatan akan diterapkan saat nilai ditampilkan untuk pengeditan. Perilaku tersebut mungkin tidak diinginkan untuk beberapa bidang. Misalnya, dalam nilai mata uang, simbol mata uang biasanya tidak diinginkan dalam antarmuka pengguna edit.

Atribut [DisplayFormat] dapat digunakan dengan sendirinya, tetapi umumnya merupakan ide yang baik untuk menggunakan [DataType] atribut . Atribut [DataType] menyampaikan semantik data dibandingkan dengan cara merendernya di layar. Atribut [DataType] memberikan manfaat berikut yang tidak tersedia dengan [DisplayFormat]:

  • Browser dapat mengaktifkan fitur HTML5, misalnya untuk menampilkan kontrol kalender, simbol mata uang yang sesuai dengan lokal, tautan email, dll.
  • Secara default, browser merender data menggunakan format yang benar berdasarkan lokalnya.
  • Atribut [DataType] dapat mengaktifkan kerangka kerja ASP.NET Core untuk memilih templat bidang yang tepat untuk merender data. DisplayFormat, jika digunakan dengan sendirinya, menggunakan templat string.

Catatan: Validasi jQuery tidak berfungsi dengan [Range] atribut dan DateTime. Misalnya, kode berikut akan selalu menampilkan kesalahan validasi sisi klien, bahkan ketika tanggal berada dalam rentang yang ditentukan:

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

Ini adalah praktik terbaik untuk menghindari kompilasi tanggal keras dalam model, jadi menggunakan [Range] atribut dan DateTime tidak dianjurkan. Gunakan Konfigurasi untuk rentang tanggal dan nilai lain yang sering berubah daripada menentukannya dalam kode.

Kode berikut menunjukkan menggabungkan atribut pada satu baris:

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

Mulai menggunakan Razor Pages danEF Coreperlihatkan operasi tingkat lanjut EF Core dengan Razor Pages.

Menerapkan migrasi

DataAnnotations yang diterapkan ke kelas mengubah skema. Misalnya, DataAnnotations diterapkan ke Title bidang :

[StringLength(60, MinimumLength = 3)]
[Required]
public string Title { get; set; }
  • Membatasi karakter menjadi 60.
  • Tidak mengizinkan null nilai.

Tabel Movie saat ini memiliki skema berikut:

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

Perubahan skema sebelumnya tidak menyebabkan EF melemparkan pengecualian. Namun, buat migrasi sehingga skema konsisten dengan model.

Dari menu Alat , pilih NuGet Package Manager > Package Manager Console. Di PMC, masukkan perintah berikut:

Add-Migration New_DataAnnotations
Update-Database

Update-DatabaseUp menjalankan metode New_DataAnnotations kelas. Periksa Up metode :

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

Tabel yang diperbarui Movie memiliki skema berikut:

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

Menerbitkan ke Azure

Untuk informasi tentang penyebaran ke Azure, lihat Tutorial: Membuat aplikasi ASP.NET Core di Azure dengan SQL Database.

Terima kasih telah menyelesaikan pengenalan Razor Halaman ini. Mulai menggunakan Razor Pages dan EF Core merupakan tindak lanjut yang sangat baik untuk tutorial ini.

Pola aplikasi web yang andal

Lihat video dan artikel Reliable Web App Pattern for.NETYouTube untuk panduan tentang membuat aplikasi modern, andal, berkinerja, dapat diuji, hemat biaya, dan dapat diskalakan ASP.NET Core, baik dari awal atau refaktor aplikasi yang ada.

Sumber Daya Tambahan:

Langkah berikutnya