Bagikan melalui


Bagian 3, Halaman perancah Razor di ASP.NET Core

Catatan

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

Peringatan

Versi ASP.NET Core ini tidak lagi didukung. Untuk informasi selengkapnya, lihat Kebijakan Dukungan .NET dan .NET Core. 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

Tutorial ini memeriksa Halaman yang Razor dibuat dengan perancah dalam tutorial sebelumnya.

Halaman Buat, Hapus, Detail, dan Edit

Periksa Pages/Movies/Index.cshtml.cs Model Halaman:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using RazorPagesMovie.Data;
using RazorPagesMovie.Models;
using Microsoft.AspNetCore.Mvc.Rendering;

namespace RazorPagesMovie.Pages.Movies
{
    public class IndexModel : PageModel
    {
        private readonly RazorPagesMovie.Data.RazorPagesMovieContext _context;

        public IndexModel(RazorPagesMovie.Data.RazorPagesMovieContext context)
        {
            _context = context;
        }

        public IList<Movie> Movie { get;set; } = default!;

        public async Task OnGetAsync()
        {
            Movie = await _context.Movie.ToListAsync();
        }
    }
}

Razor Halaman berasal dari PageModel. Menurut konvensi, kelas turunan PageModel diberi nama PageNameModel. Misalnya, halaman Indeks diberi nama IndexModel.

Konstruktor menggunakan injeksi dependensi untuk menambahkan ke RazorPagesMovieContext halaman:

public class IndexModel : PageModel
{
    private readonly RazorPagesMovie.Data.RazorPagesMovieContext _context;

    public IndexModel(RazorPagesMovie.Data.RazorPagesMovieContext context)
    {
        _context = context;
    }

Lihat Kode asinkron untuk informasi selengkapnya tentang pemrograman asinkron dengan Kerangka Kerja Entitas.

GET Saat permintaan dibuat untuk halaman, OnGetAsync metode mengembalikan daftar film ke Razor Halaman. Razor Pada Halaman, OnGetAsync atau OnGet dipanggil untuk menginisialisasi status halaman. Dalam hal ini, OnGetAsync mendapatkan daftar film dan menampilkannya.

Saat OnGet mengembalikan void atau OnGetAsync mengembalikan Task, tidak ada pernyataan pengembalian yang digunakan. Misalnya, periksa Privacy Halaman:

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;

namespace RazorPagesMovie.Pages
{
    public class PrivacyModel : PageModel
    {
        private readonly ILogger<PrivacyModel> _logger;

        public PrivacyModel(ILogger<PrivacyModel> logger)
        {
            _logger = logger;
        }

        public void OnGet()
        {
        }
    }

}

Ketika jenis pengembalian adalah IActionResult atau Task<IActionResult>, pernyataan pengembalian harus disediakan. Misalnya, metode :Pages/Movies/Create.cshtml.cs OnPostAsync

public async Task<IActionResult> OnPostAsync()
{
    if (!ModelState.IsValid)
    {
        return Page();
    }

    _context.Movie.Add(Movie);
    await _context.SaveChangesAsync();

    return RedirectToPage("./Index");
}

Periksa Pages/Movies/Index.cshtmlRazor Halaman:

@page
@model RazorPagesMovie.Pages.Movies.IndexModel

@{
    ViewData["Title"] = "Index";
}

<h1>Index</h1>

<p>
    <a asp-page="Create">Create New</a>
</p>
<table class="table">
    <thead>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.Movie[0].Title)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movie[0].ReleaseDate)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movie[0].Genre)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movie[0].Price)
            </th>
            <th></th>
        </tr>
    </thead>
    <tbody>
@foreach (var item in Model.Movie) {
        <tr>
            <td>
                @Html.DisplayFor(modelItem => item.Title)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.ReleaseDate)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Genre)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Price)
            </td>
            <td>
                <a asp-page="./Edit" asp-route-id="@item.Id">Edit</a> |
                <a asp-page="./Details" asp-route-id="@item.Id">Details</a> |
                <a asp-page="./Delete" asp-route-id="@item.Id">Delete</a>
            </td>
        </tr>
}
    </tbody>
</table>

Razor dapat beralih dari HTML ke C# atau ke Razormarkup -spesifik. @ Ketika simbol diikuti dengan kata kunci yang Razor dipesan, simbol tersebut beralih ke Razormarkup -spesifik, jika tidak, simbol tersebut beralih ke C#.

Petunjuk @page

Direktif @pageRazor menjadikan file sebagai tindakan MVC, yang berarti dapat menangani permintaan. @page harus menjadi arahan Razor pertama di halaman. @page dan @model merupakan contoh transisi ke Razormarkup -spesifik. Lihat Razor sintaks untuk informasi selengkapnya.

Petunjuk @model

@page
@model RazorPagesMovie.Pages.Movies.IndexModel

Direktif @model menentukan jenis model yang diteruskan ke Razor Halaman. Dalam contoh sebelumnya, @model baris membuat PageModel kelas turunan tersedia untuk Razor Halaman. Model ini digunakan di pembantu @Html.DisplayNameFor HTML dan @Html.DisplayFordi halaman.

Periksa ekspresi lambda yang digunakan dalam Pembantu HTML berikut:

@Html.DisplayNameFor(model => model.Movie[0].Title)

Pembantu DisplayNameFor HTML memeriksa properti yang direferensikan Title dalam ekspresi lambda untuk menentukan nama tampilan. Ekspresi lambda diperiksa daripada dievaluasi. Itu berarti tidak ada pelanggaran akses ketika model, , model.Movieatau model.Movie[0]null atau kosong. Saat ekspresi lambda dievaluasi, misalnya, dengan @Html.DisplayFor(modelItem => item.Title), nilai properti model dievaluasi.

Halaman tata letak

Pilih tautan Razormenu PagesMovie, Home, dan Privacy. Setiap halaman memperlihatkan tata letak menu yang sama. Tata letak menu diimplementasikan dalam Pages/Shared/_Layout.cshtml file.

Buka dan periksa Pages/Shared/_Layout.cshtml file.

Templat tata letak memungkinkan tata letak kontainer HTML menjadi:

  • Ditentukan di satu tempat.
  • Diterapkan di beberapa halaman di situs.

Temukan garisnya @RenderBody() . RenderBody adalah tempat penampung di mana semua tampilan khusus halaman muncul, dibungkus di halaman tata letak. Misalnya, pilih Privacy tautan dan Pages/Privacy.cshtml tampilan dirender di RenderBody dalam metode .

TampilkanData dan tata letak

Pertimbangkan markup berikut dari Pages/Movies/Index.cshtml file:

@page
@model RazorPagesMovie.Pages.Movies.IndexModel

@{
    ViewData["Title"] = "Index";
}

Markup yang disorot sebelumnya adalah contoh Razor transisi ke C#. Karakter { dan } mengapit blok kode C#.

Kelas PageModel dasar berisi ViewData properti kamus yang dapat digunakan untuk meneruskan data ke Tampilan. Objek ditambahkan ke ViewData kamus menggunakan pola nilai kunci. Dalam sampel sebelumnya, Title properti ditambahkan ke ViewData kamus.

Properti Title digunakan dalam Pages/Shared/_Layout.cshtml file. Markup berikut menunjukkan beberapa baris _Layout.cshtml pertama file.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>@ViewData["Title"] - RazorPagesMovie</title>
    <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
    <link rel="stylesheet" href="~/css/site.css" asp-append-version="true" />
    <link rel="stylesheet" href="~/RazorPagesMovie.styles.css" asp-append-version="true" />

Memperbarui tata letak

  1. <title> Ubah elemen dalam Pages/Shared/_Layout.cshtml file untuk menampilkan Film daripada RazorPagesMovie.

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>@ViewData["Title"] - Movie</title>
    
  2. Temukan elemen jangkar berikut dalam Pages/Shared/_Layout.cshtml file.

    <a class="navbar-brand" asp-area="" asp-page="/Index">RazorPagesMovie</a>
    
  3. Ganti elemen sebelumnya dengan markup berikut:

    <a class="navbar-brand" asp-page="/Movies/Index">RpMovie</a>
    

    Elemen jangkar sebelumnya adalah Pembantu Tag. Dalam hal ini, ini adalah Pembantu Tag Jangkar. Atribut asp-page="/Movies/Index" dan nilai Tag Helper membuat tautan ke /Movies/IndexRazor Halaman. Nilai asp-area atribut kosong, sehingga area tidak digunakan dalam tautan. Lihat Area untuk informasi selengkapnya.

  4. Simpan perubahan dan uji aplikasi dengan memilih tautan RpMovie . Lihat file _Layout.cshtml di GitHub jika Anda memiliki masalah.

  5. HomeUji tautan , RpMovie, Buat, Edit, dan Hapus. Setiap halaman mengatur judul, yang dapat Anda lihat di tab browser. Saat Anda menandai halaman, judul digunakan untuk bookmark.

Catatan

Anda mungkin tidak dapat memasukkan koma desimal di Price bidang . 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 mengglolisisasi aplikasi. Lihat masalah GitHub 4076 ini untuk instruksi tentang menambahkan koma desimal.

Properti Layout diatur dalam Pages/_ViewStart.cshtml file:

@{
    Layout = "_Layout";
}

Markup sebelumnya mengatur file tata letak ke Pages/Shared/_Layout.cshtml untuk semua Razor file di bawah folder Halaman . Lihat Tata Letak untuk informasi selengkapnya.

Model buat halaman

Periksa Pages/Movies/Create.cshtml.cs model halaman:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.AspNetCore.Mvc.Rendering;
using RazorPagesMovie.Data;
using RazorPagesMovie.Models;

namespace RazorPagesMovie.Pages.Movies
{
    public class CreateModel : PageModel
    {
        private readonly RazorPagesMovie.Data.RazorPagesMovieContext _context;

        public CreateModel(RazorPagesMovie.Data.RazorPagesMovieContext context)
        {
            _context = context;
        }

        public IActionResult OnGet()
        {
            return Page();
        }

        [BindProperty]
        public Movie Movie { get; set; } = default!;

        // To protect from overposting attacks, see https://aka.ms/RazorPagesCRUD
        public async Task<IActionResult> OnPostAsync()
        {
            if (!ModelState.IsValid)
            {
                return Page();
            }

            _context.Movie.Add(Movie);
            await _context.SaveChangesAsync();

            return RedirectToPage("./Index");
        }
    }
}

Metode ini OnGet menginisialisasi status apa pun yang diperlukan untuk halaman. Halaman Buat tidak memiliki status apa pun untuk diinisialisasi, sehingga Page dikembalikan. Kemudian dalam tutorial, contoh OnGet menginisialisasi status ditampilkan. Metode Page membuat PageResult objek yang merender Create.cshtml halaman.

Properti Movie menggunakan atribut [BindProperty] untuk ikut serta dalam pengikatan model. Saat formulir Buat memposting nilai formulir, runtime ASP.NET Core mengikat nilai yang diposting ke Movie model.

Metode OnPostAsync dijalankan ketika halaman memposting data formulir:

public async Task<IActionResult> OnPostAsync()
{
    if (!ModelState.IsValid)
    {
        return Page();
    }

    _context.Movie.Add(Movie);
    await _context.SaveChangesAsync();

    return RedirectToPage("./Index");
}

Jika ada kesalahan model, formulir diputar ulang, bersama dengan data formulir apa pun yang diposting. Sebagian besar kesalahan model dapat ditangkap di sisi klien sebelum formulir diposting. Contoh kesalahan model adalah memposting nilai untuk bidang tanggal yang tidak dapat dikonversi ke tanggal. Validasi sisi klien dan validasi model dibahas nanti dalam tutorial.

Jika tidak ada kesalahan model:

  • Data disimpan.
  • Browser dialihkan ke halaman Indeks.

Halaman Buat Razor

Periksa Pages/Movies/Create.cshtmlRazor file Halaman:

@page
@model RazorPagesMovie.Pages.Movies.CreateModel

@{
    ViewData["Title"] = "Create";
}

<h1>Create</h1>

<h4>Movie</h4>
<hr />
<div class="row">
    <div class="col-md-4">
        <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>
            <div class="form-group">
                <label asp-for="Movie.ReleaseDate" class="control-label"></label>
                <input asp-for="Movie.ReleaseDate" class="form-control" />
                <span asp-validation-for="Movie.ReleaseDate" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Movie.Genre" class="control-label"></label>
                <input asp-for="Movie.Genre" class="form-control" />
                <span asp-validation-for="Movie.Genre" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Movie.Price" class="control-label"></label>
                <input asp-for="Movie.Price" class="form-control" />
                <span asp-validation-for="Movie.Price" class="text-danger"></span>
            </div>
            <div class="form-group">
                <input type="submit" value="Create" class="btn btn-primary" />
            </div>
        </form>
    </div>
</div>

<div>
    <a asp-page="Index">Back to List</a>
</div>

@section Scripts {
    @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}

Visual Studio menampilkan tag berikut dalam font tebal khas yang digunakan untuk Pembantu Tag:

  • <form method="post">
  • <div asp-validation-summary="ModelOnly" class="text-danger"></div>
  • <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>

Tampilan VS halaman Create.cshtml

Elemen <form method="post"> ini adalah Pembantu Tag Formulir. Pembantu Tag Formulir secara otomatis menyertakan token antiforgery.

Mesin perancah membuat Razor markup untuk setiap bidang dalam model, kecuali ID, mirip dengan yang berikut:

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

Bantuan Tag Validasi (<div asp-validation-summary dan <span asp-validation-for) menampilkan kesalahan validasi. Validasi dibahas secara lebih rinci nanti dalam seri ini.

Label Tag Helper (<label asp-for="Movie.Title" class="control-label"></label>) menghasilkan keterangan label dan [for] atribut untuk Title properti .

Pembantu Tag Input (<input asp-for="Movie.Title" class="form-control">) menggunakan atribut DataAnnotations dan menghasilkan atribut HTML yang diperlukan untuk Validasi jQuery di sisi klien.

Untuk informasi selengkapnya tentang Pembantu Tag seperti <form method="post">, lihat Pembantu Tag di ASP.NET Core.

Langkah berikutnya

Halaman Buat, Hapus, Detail, dan Edit

Periksa Pages/Movies/Index.cshtml.cs Model Halaman:

using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using RazorPagesMovie.Models;

namespace RazorPagesMovie.Pages.Movies;

public class IndexModel : PageModel
{
    private readonly RazorPagesMovie.Data.RazorPagesMovieContext _context;

    public IndexModel(RazorPagesMovie.Data.RazorPagesMovieContext context)
    {
        _context = context;
    }

    public IList<Movie> Movie { get;set; }  = default!;

    public async Task OnGetAsync()
    {
        if (_context.Movie != null)
        {
            Movie = await _context.Movie.ToListAsync();
        }
    }
}

Razor Halaman berasal dari PageModel. Menurut konvensi, kelas turunan PageModel diberi nama PageNameModel. Misalnya, halaman Indeks diberi nama IndexModel.

Konstruktor menggunakan injeksi dependensi untuk menambahkan ke RazorPagesMovieContext halaman:

public class IndexModel : PageModel
{
    private readonly RazorPagesMovie.Data.RazorPagesMovieContext _context;

    public IndexModel(RazorPagesMovie.Data.RazorPagesMovieContext context)
    {
        _context = context;
    }

Lihat Kode asinkron untuk informasi selengkapnya tentang pemrograman asinkron dengan Kerangka Kerja Entitas.

GET Saat permintaan dibuat untuk halaman, OnGetAsync metode mengembalikan daftar film ke Razor Halaman. Razor Pada Halaman, OnGetAsync atau OnGet dipanggil untuk menginisialisasi status halaman. Dalam hal ini, OnGetAsync mendapatkan daftar film dan menampilkannya.

Saat OnGet mengembalikan void atau OnGetAsync mengembalikan Task, tidak ada pernyataan pengembalian yang digunakan. Misalnya, periksa Privacy Halaman:

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;

namespace RazorPagesMovie.Pages
{
    public class PrivacyModel : PageModel
    {
        private readonly ILogger<PrivacyModel> _logger;

        public PrivacyModel(ILogger<PrivacyModel> logger)
        {
            _logger = logger;
        }

        public void OnGet()
        {
        }
    }
}

Ketika jenis pengembalian adalah IActionResult atau Task<IActionResult>, pernyataan pengembalian harus disediakan. Misalnya, metode :Pages/Movies/Create.cshtml.cs OnPostAsync

public async Task<IActionResult> OnPostAsync()
{
  if (!ModelState.IsValid)
    {
        return Page();
    }

    _context.Movie.Add(Movie);
    await _context.SaveChangesAsync();

    return RedirectToPage("./Index");
}

Periksa Pages/Movies/Index.cshtmlRazor Halaman:

@page
@model RazorPagesMovie.Pages.Movies.IndexModel

@{
    ViewData["Title"] = "Index";
}

<h1>Index</h1>

<p>
    <a asp-page="Create">Create New</a>
</p>
<table class="table">
    <thead>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.Movie[0].Title)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movie[0].ReleaseDate)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movie[0].Genre)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movie[0].Price)
            </th>
            <th></th>
        </tr>
    </thead>
    <tbody>
@foreach (var item in Model.Movie) {
        <tr>
            <td>
                @Html.DisplayFor(modelItem => item.Title)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.ReleaseDate)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Genre)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Price)
            </td>
            <td>
                <a asp-page="./Edit" asp-route-id="@item.Id">Edit</a> |
                <a asp-page="./Details" asp-route-id="@item.Id">Details</a> |
                <a asp-page="./Delete" asp-route-id="@item.Id">Delete</a>
            </td>
        </tr>
}
    </tbody>
</table>

Razor dapat beralih dari HTML ke C# atau ke Razormarkup -spesifik. @ Ketika simbol diikuti dengan kata kunci yang Razor dipesan, simbol tersebut beralih ke Razormarkup -spesifik, jika tidak, simbol tersebut beralih ke C#.

Petunjuk @page

Direktif @pageRazor menjadikan file sebagai tindakan MVC, yang berarti dapat menangani permintaan. @page harus menjadi arahan Razor pertama di halaman. @page dan @model merupakan contoh transisi ke Razormarkup -spesifik. Lihat Razor sintaks untuk informasi selengkapnya.

Petunjuk @model

@page
@model RazorPagesMovie.Pages.Movies.IndexModel

Direktif @model menentukan jenis model yang diteruskan ke Razor Halaman. Dalam contoh sebelumnya, @model baris membuat PageModel kelas turunan tersedia untuk Razor Halaman. Model ini digunakan di pembantu @Html.DisplayNameFor HTML dan @Html.DisplayFordi halaman.

Periksa ekspresi lambda yang digunakan dalam Pembantu HTML berikut:

@Html.DisplayNameFor(model => model.Movie[0].Title)

Pembantu DisplayNameFor HTML memeriksa properti yang direferensikan Title dalam ekspresi lambda untuk menentukan nama tampilan. Ekspresi lambda diperiksa daripada dievaluasi. Itu berarti tidak ada pelanggaran akses ketika model, , model.Movieatau model.Movie[0]null atau kosong. Saat ekspresi lambda dievaluasi, misalnya, dengan @Html.DisplayFor(modelItem => item.Title), nilai properti model dievaluasi.

Halaman tata letak

Pilih tautan Razormenu PagesMovie, Home, dan Privacy. Setiap halaman memperlihatkan tata letak menu yang sama. Tata letak menu diimplementasikan dalam Pages/Shared/_Layout.cshtml file.

Buka dan periksa Pages/Shared/_Layout.cshtml file.

Templat tata letak memungkinkan tata letak kontainer HTML menjadi:

  • Ditentukan di satu tempat.
  • Diterapkan di beberapa halaman di situs.

Temukan garisnya @RenderBody() . RenderBody adalah tempat penampung di mana semua tampilan khusus halaman muncul, dibungkus di halaman tata letak. Misalnya, pilih Privacy tautan dan Pages/Privacy.cshtml tampilan dirender di RenderBody dalam metode .

TampilkanData dan tata letak

Pertimbangkan markup berikut dari Pages/Movies/Index.cshtml file:

@page
@model RazorPagesMovie.Pages.Movies.IndexModel

@{
    ViewData["Title"] = "Index";
}

Markup yang disorot sebelumnya adalah contoh Razor transisi ke C#. Karakter { dan } mengapit blok kode C#.

Kelas PageModel dasar berisi ViewData properti kamus yang dapat digunakan untuk meneruskan data ke Tampilan. Objek ditambahkan ke ViewData kamus menggunakan pola nilai kunci. Dalam sampel sebelumnya, Title properti ditambahkan ke ViewData kamus.

Properti Title digunakan dalam Pages/Shared/_Layout.cshtml file. Markup berikut menunjukkan beberapa baris _Layout.cshtml pertama file.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>@ViewData["Title"] - RazorPagesMovie</title>
    <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
    <link rel="stylesheet" href="~/css/site.css" asp-append-version="true" />
    <link rel="stylesheet" href="~/RazorPagesMovie.styles.css" asp-append-version="true" />

Memperbarui tata letak

  1. <title> Ubah elemen dalam Pages/Shared/_Layout.cshtml file untuk menampilkan Film daripada RazorPagesMovie.

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>@ViewData["Title"] - Movie</title>
    
  2. Temukan elemen jangkar berikut dalam Pages/Shared/_Layout.cshtml file.

    <a class="navbar-brand" asp-area="" asp-page="/Index">RazorPagesMovie</a>
    
  3. Ganti elemen sebelumnya dengan markup berikut:

    <a class="navbar-brand" asp-page="/Movies/Index">RpMovie</a>
    

    Elemen jangkar sebelumnya adalah Pembantu Tag. Dalam hal ini, ini adalah Pembantu Tag Jangkar. Atribut asp-page="/Movies/Index" dan nilai Tag Helper membuat tautan ke /Movies/IndexRazor Halaman. Nilai asp-area atribut kosong, sehingga area tidak digunakan dalam tautan. Lihat Area untuk informasi selengkapnya.

  4. Simpan perubahan dan uji aplikasi dengan memilih tautan RpMovie . Lihat file _Layout.cshtml di GitHub jika Anda memiliki masalah.

  5. HomeUji tautan , RpMovie, Buat, Edit, dan Hapus. Setiap halaman mengatur judul, yang dapat Anda lihat di tab browser. Saat Anda menandai halaman, judul digunakan untuk bookmark.

Catatan

Anda mungkin tidak dapat memasukkan koma desimal di Price bidang . 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 mengglolisisasi aplikasi. Lihat masalah GitHub 4076 ini untuk instruksi tentang menambahkan koma desimal.

Properti Layout diatur dalam Pages/_ViewStart.cshtml file:

@{
    Layout = "_Layout";
}

Markup sebelumnya mengatur file tata letak ke Pages/Shared/_Layout.cshtml untuk semua Razor file di bawah folder Halaman . Lihat Tata Letak untuk informasi selengkapnya.

Model buat halaman

Periksa Pages/Movies/Create.cshtml.cs model halaman:

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using RazorPagesMovie.Models;

namespace RazorPagesMovie.Pages.Movies
{
    public class CreateModel : PageModel
    {
        private readonly RazorPagesMovie.Data.RazorPagesMovieContext _context;

        public CreateModel(RazorPagesMovie.Data.RazorPagesMovieContext context)
        {
            _context = context;
        }

        public IActionResult OnGet()
        {
            return Page();
        }

        [BindProperty]
        public Movie Movie { get; set; } = default!;
        

        // To protect from overposting attacks, see https://aka.ms/RazorPagesCRUD
        public async Task<IActionResult> OnPostAsync()
        {
          if (!ModelState.IsValid || _context.Movie == null || Movie == null)
            {
                return Page();
            }

            _context.Movie.Add(Movie);
            await _context.SaveChangesAsync();

            return RedirectToPage("./Index");
        }
    }
}

Metode ini OnGet menginisialisasi status apa pun yang diperlukan untuk halaman. Halaman Buat tidak memiliki status apa pun untuk diinisialisasi, sehingga Page dikembalikan. Kemudian dalam tutorial, contoh OnGet menginisialisasi status ditampilkan. Metode Page membuat PageResult objek yang merender Create.cshtml halaman.

Properti Movie menggunakan atribut [BindProperty] untuk ikut serta dalam pengikatan model. Saat formulir Buat memposting nilai formulir, runtime ASP.NET Core mengikat nilai yang diposting ke Movie model.

Metode OnPostAsync dijalankan ketika halaman memposting data formulir:

public async Task<IActionResult> OnPostAsync()
{
  if (!ModelState.IsValid)
    {
        return Page();
    }

    _context.Movie.Add(Movie);
    await _context.SaveChangesAsync();

    return RedirectToPage("./Index");
}

Jika ada kesalahan model, formulir diputar ulang, bersama dengan data formulir apa pun yang diposting. Sebagian besar kesalahan model dapat ditangkap di sisi klien sebelum formulir diposting. Contoh kesalahan model adalah memposting nilai untuk bidang tanggal yang tidak dapat dikonversi ke tanggal. Validasi sisi klien dan validasi model dibahas nanti dalam tutorial.

Jika tidak ada kesalahan model:

  • Data disimpan.
  • Browser dialihkan ke halaman Indeks.

Halaman Buat Razor

Periksa Pages/Movies/Create.cshtmlRazor file Halaman:

@page
@model RazorPagesMovie.Pages.Movies.CreateModel

@{
    ViewData["Title"] = "Create";
}

<h1>Create</h1>

<h4>Movie</h4>
<hr />
<div class="row">
    <div class="col-md-4">
        <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>
            <div class="form-group">
                <label asp-for="Movie.ReleaseDate" class="control-label"></label>
                <input asp-for="Movie.ReleaseDate" class="form-control" />
                <span asp-validation-for="Movie.ReleaseDate" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Movie.Genre" class="control-label"></label>
                <input asp-for="Movie.Genre" class="form-control" />
                <span asp-validation-for="Movie.Genre" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Movie.Price" class="control-label"></label>
                <input asp-for="Movie.Price" class="form-control" />
                <span asp-validation-for="Movie.Price" class="text-danger"></span>
            </div>
            <div class="form-group">
                <input type="submit" value="Create" class="btn btn-primary" />
            </div>
        </form>
    </div>
</div>

<div>
    <a asp-page="Index">Back to List</a>
</div>

@section Scripts {
    @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}

Visual Studio menampilkan tag berikut dalam font tebal khas yang digunakan untuk Pembantu Tag:

  • <form method="post">
  • <div asp-validation-summary="ModelOnly" class="text-danger"></div>
  • <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>

Tampilan VS17 halaman Create.cshtml

Elemen <form method="post"> ini adalah Pembantu Tag Formulir. Pembantu Tag Formulir secara otomatis menyertakan token antiforgery.

Mesin perancah membuat Razor markup untuk setiap bidang dalam model, kecuali ID, mirip dengan yang berikut:

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

Bantuan Tag Validasi (<div asp-validation-summary dan <span asp-validation-for) menampilkan kesalahan validasi. Validasi dibahas secara lebih rinci nanti dalam seri ini.

Label Tag Helper (<label asp-for="Movie.Title" class="control-label"></label>) menghasilkan keterangan label dan [for] atribut untuk Title properti .

Pembantu Tag Input (<input asp-for="Movie.Title" class="form-control">) menggunakan atribut DataAnnotations dan menghasilkan atribut HTML yang diperlukan untuk Validasi jQuery di sisi klien.

Untuk informasi selengkapnya tentang Pembantu Tag seperti <form method="post">, lihat Pembantu Tag di ASP.NET Core.

Langkah berikutnya

Halaman Buat, Hapus, Detail, dan Edit

Periksa Pages/Movies/Index.cshtml.cs Model Halaman:

using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using RazorPagesMovie.Models;

namespace RazorPagesMovie.Pages.Movies;

public class IndexModel : PageModel
{
    private readonly RazorPagesMovie.Data.RazorPagesMovieContext _context;

    public IndexModel(RazorPagesMovie.Data.RazorPagesMovieContext context)
    {
        _context = context;
    }

    public IList<Movie> Movie { get;set; }  = default!;

    public async Task OnGetAsync()
    {
        if (_context.Movie != null)
        {
            Movie = await _context.Movie.ToListAsync();
        }
    }
}

Razor Halaman berasal dari PageModel. Menurut konvensi, kelas turunan PageModel diberi nama PageNameModel. Misalnya, halaman Indeks diberi nama IndexModel.

Konstruktor menggunakan injeksi dependensi untuk menambahkan ke RazorPagesMovieContext halaman:

public class IndexModel : PageModel
{
    private readonly RazorPagesMovie.Data.RazorPagesMovieContext _context;

    public IndexModel(RazorPagesMovie.Data.RazorPagesMovieContext context)
    {
        _context = context;
    }

Lihat Kode asinkron untuk informasi selengkapnya tentang pemrograman asinkron dengan Kerangka Kerja Entitas.

GET Saat permintaan dibuat untuk halaman, OnGetAsync metode mengembalikan daftar film ke Razor Halaman. Razor Pada Halaman, OnGetAsync atau OnGet dipanggil untuk menginisialisasi status halaman. Dalam hal ini, OnGetAsync mendapatkan daftar film dan menampilkannya.

Saat OnGet mengembalikan void atau OnGetAsync mengembalikan Task, tidak ada pernyataan pengembalian yang digunakan. Misalnya, periksa Privacy Halaman:

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;

namespace RazorPagesMovie.Pages
{
    public class PrivacyModel : PageModel
    {
        private readonly ILogger<PrivacyModel> _logger;

        public PrivacyModel(ILogger<PrivacyModel> logger)
        {
            _logger = logger;
        }

        public void OnGet()
        {
        }
    }
}

Ketika jenis pengembalian adalah IActionResult atau Task<IActionResult>, pernyataan pengembalian harus disediakan. Misalnya, metode :Pages/Movies/Create.cshtml.cs OnPostAsync

public async Task<IActionResult> OnPostAsync()
{
  if (!ModelState.IsValid)
    {
        return Page();
    }

    _context.Movie.Add(Movie);
    await _context.SaveChangesAsync();

    return RedirectToPage("./Index");
}

Periksa Pages/Movies/Index.cshtmlRazor Halaman:

@page
@model RazorPagesMovie.Pages.Movies.IndexModel

@{
    ViewData["Title"] = "Index";
}

<h1>Index</h1>

<p>
    <a asp-page="Create">Create New</a>
</p>
<table class="table">
    <thead>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.Movie[0].Title)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movie[0].ReleaseDate)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movie[0].Genre)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movie[0].Price)
            </th>
            <th></th>
        </tr>
    </thead>
    <tbody>
@foreach (var item in Model.Movie) {
        <tr>
            <td>
                @Html.DisplayFor(modelItem => item.Title)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.ReleaseDate)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Genre)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Price)
            </td>
            <td>
                <a asp-page="./Edit" asp-route-id="@item.Id">Edit</a> |
                <a asp-page="./Details" asp-route-id="@item.Id">Details</a> |
                <a asp-page="./Delete" asp-route-id="@item.Id">Delete</a>
            </td>
        </tr>
}
    </tbody>
</table>

Razor dapat beralih dari HTML ke C# atau ke Razormarkup -spesifik. @ Ketika simbol diikuti dengan kata kunci yang Razor dipesan, simbol tersebut beralih ke Razormarkup -spesifik, jika tidak, simbol tersebut beralih ke C#.

Petunjuk @page

Direktif @pageRazor menjadikan file sebagai tindakan MVC, yang berarti dapat menangani permintaan. @page harus menjadi arahan Razor pertama di halaman. @page dan @model merupakan contoh transisi ke Razormarkup -spesifik. Lihat Razor sintaks untuk informasi selengkapnya.

Petunjuk @model

@page
@model RazorPagesMovie.Pages.Movies.IndexModel

Direktif @model menentukan jenis model yang diteruskan ke Razor Halaman. Dalam contoh sebelumnya, @model baris membuat PageModel kelas turunan tersedia untuk Razor Halaman. Model ini digunakan di pembantu @Html.DisplayNameFor HTML dan @Html.DisplayFordi halaman.

Periksa ekspresi lambda yang digunakan dalam Pembantu HTML berikut:

@Html.DisplayNameFor(model => model.Movie[0].Title)

Pembantu DisplayNameFor HTML memeriksa properti yang direferensikan Title dalam ekspresi lambda untuk menentukan nama tampilan. Ekspresi lambda diperiksa daripada dievaluasi. Itu berarti tidak ada pelanggaran akses ketika model, , model.Movieatau model.Movie[0]null atau kosong. Saat ekspresi lambda dievaluasi, misalnya, dengan @Html.DisplayFor(modelItem => item.Title), nilai properti model dievaluasi.

Halaman tata letak

Pilih tautan Razormenu PagesMovie, Home, dan Privacy. Setiap halaman memperlihatkan tata letak menu yang sama. Tata letak menu diimplementasikan dalam Pages/Shared/_Layout.cshtml file.

Buka dan periksa Pages/Shared/_Layout.cshtml file.

Templat tata letak memungkinkan tata letak kontainer HTML menjadi:

  • Ditentukan di satu tempat.
  • Diterapkan di beberapa halaman di situs.

Temukan garisnya @RenderBody() . RenderBody adalah tempat penampung di mana semua tampilan khusus halaman muncul, dibungkus di halaman tata letak. Misalnya, pilih Privacy tautan dan Pages/Privacy.cshtml tampilan dirender di RenderBody dalam metode .

TampilkanData dan tata letak

Pertimbangkan markup berikut dari Pages/Movies/Index.cshtml file:

@page
@model RazorPagesMovie.Pages.Movies.IndexModel

@{
    ViewData["Title"] = "Index";
}

Markup yang disorot sebelumnya adalah contoh Razor transisi ke C#. Karakter { dan } mengapit blok kode C#.

Kelas PageModel dasar berisi ViewData properti kamus yang dapat digunakan untuk meneruskan data ke Tampilan. Objek ditambahkan ke ViewData kamus menggunakan pola nilai kunci. Dalam sampel sebelumnya, Title properti ditambahkan ke ViewData kamus.

Properti Title digunakan dalam Pages/Shared/_Layout.cshtml file. Markup berikut menunjukkan beberapa baris _Layout.cshtml pertama file.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>@ViewData["Title"] - RazorPagesMovie</title>
    <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
    <link rel="stylesheet" href="~/css/site.css" asp-append-version="true" />
    <link rel="stylesheet" href="~/RazorPagesMovie.styles.css" asp-append-version="true" />

Baris @*Markup removed for brevity.*@ adalah Razor komentar. Tidak seperti komentar <!-- -->HTML , Razor komentar tidak dikirim ke klien. Lihat dokumen web MDN: Mulai menggunakan HTML untuk informasi selengkapnya.

Memperbarui tata letak

  1. <title> Ubah elemen dalam Pages/Shared/_Layout.cshtml file untuk menampilkan Film daripada RazorPagesMovie.

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>@ViewData["Title"] - Movie</title>
    
  2. Temukan elemen jangkar berikut dalam Pages/Shared/_Layout.cshtml file.

    <a class="navbar-brand" asp-area="" asp-page="/Index">RazorPagesMovie</a>
    
  3. Ganti elemen sebelumnya dengan markup berikut:

    <a class="navbar-brand" asp-page="/Movies/Index">RpMovie</a>
    

    Elemen jangkar sebelumnya adalah Pembantu Tag. Dalam hal ini, ini adalah Pembantu Tag Jangkar. Atribut asp-page="/Movies/Index" dan nilai Tag Helper membuat tautan ke /Movies/IndexRazor Halaman. Nilai asp-area atribut kosong, sehingga area tidak digunakan dalam tautan. Lihat Area untuk informasi selengkapnya.

  4. Simpan perubahan dan uji aplikasi dengan memilih tautan RpMovie . Lihat file _Layout.cshtml di GitHub jika Anda memiliki masalah.

  5. HomeUji tautan , RpMovie, Buat, Edit, dan Hapus. Setiap halaman mengatur judul, yang dapat Anda lihat di tab browser. Saat Anda menandai halaman, judul digunakan untuk bookmark.

Catatan

Anda mungkin tidak dapat memasukkan koma desimal di Price bidang . 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 mengglolisisasi aplikasi. Lihat masalah GitHub 4076 ini untuk instruksi tentang menambahkan koma desimal.

Properti Layout diatur dalam Pages/_ViewStart.cshtml file:

@{
    Layout = "_Layout";
}

Markup sebelumnya mengatur file tata letak ke Pages/Shared/_Layout.cshtml untuk semua Razor file di bawah folder Halaman . Lihat Tata Letak untuk informasi selengkapnya.

Model buat halaman

Periksa Pages/Movies/Create.cshtml.cs model halaman:

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using RazorPagesMovie.Models;

namespace RazorPagesMovie.Pages.Movies
{
    public class CreateModel : PageModel
    {
        private readonly RazorPagesMovie.Data.RazorPagesMovieContext _context;

        public CreateModel(RazorPagesMovie.Data.RazorPagesMovieContext context)
        {
            _context = context;
        }

        public IActionResult OnGet()
        {
            return Page();
        }

        [BindProperty]
        public Movie Movie { get; set; } = default!;
        

        // To protect from overposting attacks, see https://aka.ms/RazorPagesCRUD
        public async Task<IActionResult> OnPostAsync()
        {
          if (!ModelState.IsValid || _context.Movie == null || Movie == null)
            {
                return Page();
            }

            _context.Movie.Add(Movie);
            await _context.SaveChangesAsync();

            return RedirectToPage("./Index");
        }
    }
}

Metode ini OnGet menginisialisasi status apa pun yang diperlukan untuk halaman. Halaman Buat tidak memiliki status apa pun untuk diinisialisasi, sehingga Page dikembalikan. Kemudian dalam tutorial, contoh OnGet menginisialisasi status ditampilkan. Metode Page membuat PageResult objek yang merender Create.cshtml halaman.

Properti Movie menggunakan atribut [BindProperty] untuk ikut serta dalam pengikatan model. Saat formulir Buat memposting nilai formulir, runtime ASP.NET Core mengikat nilai yang diposting ke Movie model.

Metode OnPostAsync dijalankan ketika halaman memposting data formulir:

public async Task<IActionResult> OnPostAsync()
{
  if (!ModelState.IsValid)
    {
        return Page();
    }

    _context.Movie.Add(Movie);
    await _context.SaveChangesAsync();

    return RedirectToPage("./Index");
}

Jika ada kesalahan model, formulir diputar ulang, bersama dengan data formulir apa pun yang diposting. Sebagian besar kesalahan model dapat ditangkap di sisi klien sebelum formulir diposting. Contoh kesalahan model adalah memposting nilai untuk bidang tanggal yang tidak dapat dikonversi ke tanggal. Validasi sisi klien dan validasi model dibahas nanti dalam tutorial.

Jika tidak ada kesalahan model:

  • Data disimpan.
  • Browser dialihkan ke halaman Indeks.

Halaman Buat Razor

Periksa Pages/Movies/Create.cshtmlRazor file Halaman:

@page
@model RazorPagesMovie.Pages.Movies.CreateModel

@{
    ViewData["Title"] = "Create";
}

<h1>Create</h1>

<h4>Movie</h4>
<hr />
<div class="row">
    <div class="col-md-4">
        <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>
            <div class="form-group">
                <label asp-for="Movie.ReleaseDate" class="control-label"></label>
                <input asp-for="Movie.ReleaseDate" class="form-control" />
                <span asp-validation-for="Movie.ReleaseDate" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Movie.Genre" class="control-label"></label>
                <input asp-for="Movie.Genre" class="form-control" />
                <span asp-validation-for="Movie.Genre" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Movie.Price" class="control-label"></label>
                <input asp-for="Movie.Price" class="form-control" />
                <span asp-validation-for="Movie.Price" class="text-danger"></span>
            </div>
            <div class="form-group">
                <input type="submit" value="Create" class="btn btn-primary" />
            </div>
        </form>
    </div>
</div>

<div>
    <a asp-page="Index">Back to List</a>
</div>

@section Scripts {
    @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}

Visual Studio menampilkan tag berikut dalam font tebal khas yang digunakan untuk Pembantu Tag:

  • <form method="post">
  • <div asp-validation-summary="ModelOnly" class="text-danger"></div>
  • <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>

Tampilan VS17 halaman Create.cshtml

Elemen <form method="post"> ini adalah Pembantu Tag Formulir. Pembantu Tag Formulir secara otomatis menyertakan token antiforgery.

Mesin perancah membuat Razor markup untuk setiap bidang dalam model, kecuali ID, mirip dengan yang berikut:

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

Bantuan Tag Validasi (<div asp-validation-summary dan <span asp-validation-for) menampilkan kesalahan validasi. Validasi dibahas secara lebih rinci nanti dalam seri ini.

Label Tag Helper (<label asp-for="Movie.Title" class="control-label"></label>) menghasilkan keterangan label dan [for] atribut untuk Title properti .

Pembantu Tag Input (<input asp-for="Movie.Title" class="form-control">) menggunakan atribut DataAnnotations dan menghasilkan atribut HTML yang diperlukan untuk Validasi jQuery di sisi klien.

Untuk informasi selengkapnya tentang Pembantu Tag seperti <form method="post">, lihat Pembantu Tag di ASP.NET Core.

Langkah berikutnya

Halaman Buat, Hapus, Detail, dan Edit

Periksa Pages/Movies/Index.cshtml.cs Model Halaman:

using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using RazorPagesMovie.Models;

namespace RazorPagesMovie.Pages.Movies
{
    public class IndexModel : PageModel
    {
        private readonly RazorPagesMovie.Data.RazorPagesMovieContext _context;

        public IndexModel(RazorPagesMovie.Data.RazorPagesMovieContext context)
        {
            _context = context;
        }

        public IList<Movie> Movie { get;set; } = default!;

        public async Task OnGetAsync()
        {
            if (_context.Movie != null)
            {
                Movie = await _context.Movie.ToListAsync();
            }
        }
    }
}

Razor Halaman berasal dari PageModel. Menurut konvensi, kelas turunan PageModel diberi nama PageNameModel. Misalnya, halaman Indeks diberi nama IndexModel.

Konstruktor menggunakan injeksi dependensi untuk menambahkan ke RazorPagesMovieContext halaman:

public class IndexModel : PageModel
{
    private readonly RazorPagesMovie.Data.RazorPagesMovieContext _context;

    public IndexModel(RazorPagesMovie.Data.RazorPagesMovieContext context)
    {
        _context = context;
    }

Lihat Kode asinkron untuk informasi selengkapnya tentang pemrograman asinkron dengan Kerangka Kerja Entitas.

Saat permintaan dibuat untuk halaman, OnGetAsync metode mengembalikan daftar film ke Razor Halaman. Razor Pada Halaman, OnGetAsync atau OnGet dipanggil untuk menginisialisasi status halaman. Dalam hal ini, OnGetAsync mendapatkan daftar film dan menampilkannya.

Saat OnGet mengembalikan void atau OnGetAsync mengembalikan Task, tidak ada pernyataan pengembalian yang digunakan. Misalnya, periksa Privacy Halaman:

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;

namespace RazorPagesMovie.Pages
{
    public class PrivacyModel : PageModel
    {
        private readonly ILogger<PrivacyModel> _logger;

        public PrivacyModel(ILogger<PrivacyModel> logger)
        {
            _logger = logger;
        }

        public void OnGet()
        {
        }
    }
}

Ketika jenis pengembalian adalah IActionResult atau Task<IActionResult>, pernyataan pengembalian harus disediakan. Misalnya, metode :Pages/Movies/Create.cshtml.csOnPostAsync

public async Task<IActionResult> OnPostAsync()
{
  if (!ModelState.IsValid || _context.Movie == null || Movie == null)
    {
        return Page();
    }

    _context.Movie.Add(Movie);
    await _context.SaveChangesAsync();

    return RedirectToPage("./Index");
}

Periksa Pages/Movies/Index.cshtmlRazor Halaman:

@page
@model RazorPagesMovie.Pages.Movies.IndexModel

@{
    ViewData["Title"] = "Index";
}

<h1>Index</h1>

<p>
    <a asp-page="Create">Create New</a>
</p>
<table class="table">
    <thead>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.Movie[0].Title)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movie[0].ReleaseDate)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movie[0].Genre)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movie[0].Price)
            </th>
            <th></th>
        </tr>
    </thead>
    <tbody>
@foreach (var item in Model.Movie) {
        <tr>
            <td>
                @Html.DisplayFor(modelItem => item.Title)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.ReleaseDate)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Genre)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Price)
            </td>
            <td>
                <a asp-page="./Edit" asp-route-id="@item.ID">Edit</a> |
                <a asp-page="./Details" asp-route-id="@item.ID">Details</a> |
                <a asp-page="./Delete" asp-route-id="@item.ID">Delete</a>
            </td>
        </tr>
}
    </tbody>
</table>

Razor dapat beralih dari HTML ke C# atau ke Razormarkup -spesifik. @ Ketika simbol diikuti dengan kata kunci yang Razor dipesan, simbol tersebut beralih ke Razormarkup -spesifik, jika tidak, simbol tersebut beralih ke C#.

Petunjuk @page

Direktif @pageRazor menjadikan file sebagai tindakan MVC, yang berarti dapat menangani permintaan. @page harus menjadi arahan Razor pertama di halaman. @page dan @model merupakan contoh transisi ke Razormarkup -spesifik. Lihat Razor sintaks untuk informasi selengkapnya.

Petunjuk @model

@page
@model RazorPagesMovie.Pages.Movies.IndexModel

Direktif @model menentukan jenis model yang diteruskan ke Razor Halaman. Dalam contoh sebelumnya, @model baris membuat PageModel kelas turunan tersedia untuk Razor Halaman. Model ini digunakan di pembantu @Html.DisplayNameFor HTML dan @Html.DisplayFordi halaman.

Periksa ekspresi lambda yang digunakan dalam Pembantu HTML berikut:

@Html.DisplayNameFor(model => model.Movie[0].Title)

Pembantu DisplayNameFor HTML memeriksa properti yang direferensikan Title dalam ekspresi lambda untuk menentukan nama tampilan. Ekspresi lambda diperiksa daripada dievaluasi. Itu berarti tidak ada pelanggaran akses ketika model, , model.Movieatau model.Movie[0]null atau kosong. Saat ekspresi lambda dievaluasi, misalnya, dengan @Html.DisplayFor(modelItem => item.Title), nilai properti model dievaluasi.

Halaman tata letak

Pilih tautan Razormenu PagesMovie, Home, dan Privacy. Setiap halaman memperlihatkan tata letak menu yang sama. Tata letak menu diimplementasikan dalam Pages/Shared/_Layout.cshtml file.

Buka dan periksa Pages/Shared/_Layout.cshtml file.

Templat tata letak memungkinkan tata letak kontainer HTML menjadi:

  • Ditentukan di satu tempat.
  • Diterapkan di beberapa halaman di situs.

Temukan garisnya @RenderBody() . RenderBody adalah tempat penampung di mana semua tampilan khusus halaman muncul, dibungkus di halaman tata letak. Misalnya, pilih Privacy tautan dan Pages/Privacy.cshtml tampilan dirender di RenderBody dalam metode .

TampilkanData dan tata letak

Pertimbangkan markup berikut dari Pages/Movies/Index.cshtml file:

@page
@model RazorPagesMovie.Pages.Movies.IndexModel

@{
    ViewData["Title"] = "Index";
}

Markup yang disorot sebelumnya adalah contoh Razor transisi ke C#. Karakter { dan } mengapit blok kode C#.

Kelas PageModel dasar berisi ViewData properti kamus yang dapat digunakan untuk meneruskan data ke Tampilan. Objek ditambahkan ke ViewData kamus menggunakan pola nilai kunci. Dalam sampel sebelumnya, Title properti ditambahkan ke ViewData kamus.

Properti Title digunakan dalam Pages/Shared/_Layout.cshtml file. Markup berikut menunjukkan beberapa baris _Layout.cshtml pertama file.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>@ViewData["Title"] - RazorPagesMovie</title>

     @*Markup removed for brevity.*@
    <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />

Baris @*Markup removed for brevity.*@ adalah Razor komentar. Tidak seperti komentar <!-- -->HTML , Razor komentar tidak dikirim ke klien. Lihat dokumen web MDN: Mulai menggunakan HTML untuk informasi selengkapnya.

Memperbarui tata letak

  1. <title> Ubah elemen dalam Pages/Shared/_Layout.cshtml file untuk menampilkan Film daripada RazorPagesMovie.

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>@ViewData["Title"] - Movie</title>
    
  2. Temukan elemen jangkar berikut dalam Pages/Shared/_Layout.cshtml file.

    <a class="navbar-brand" asp-area="" asp-page="/Index">RazorPagesMovie</a>
    
  3. Ganti elemen sebelumnya dengan markup berikut:

    <a class="navbar-brand" asp-page="/Movies/Index">RpMovie</a>
    

    Elemen jangkar sebelumnya adalah Pembantu Tag. Dalam hal ini, ini adalah Pembantu Tag Jangkar. Atribut asp-page="/Movies/Index" dan nilai Tag Helper membuat tautan ke /Movies/IndexRazor Halaman. Nilai asp-area atribut kosong, sehingga area tidak digunakan dalam tautan. Lihat Area untuk informasi selengkapnya.

  4. Simpan perubahan dan uji aplikasi dengan memilih tautan RpMovie . Lihat file _Layout.cshtml di GitHub jika Anda memiliki masalah.

  5. HomeUji tautan , RpMovie, Buat, Edit, dan Hapus. Setiap halaman mengatur judul, yang dapat Anda lihat di tab browser. Saat Anda menandai halaman, judul digunakan untuk bookmark.

Catatan

Anda mungkin tidak dapat memasukkan koma desimal di Price bidang . 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 mengglolisisasi aplikasi. Lihat masalah GitHub 4076 ini untuk instruksi tentang menambahkan koma desimal.

Properti Layout diatur dalam Pages/_ViewStart.cshtml file:

@{
    Layout = "_Layout";
}

Markup sebelumnya mengatur file tata letak ke Pages/Shared/_Layout.cshtml untuk semua Razor file di bawah folder Halaman . Lihat Tata Letak untuk informasi selengkapnya.

Model buat halaman

Periksa Pages/Movies/Create.cshtml.cs model halaman:

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using RazorPagesMovie.Models;

namespace RazorPagesMovie.Pages.Movies
{
    public class CreateModel : PageModel
    {
        private readonly RazorPagesMovie.Data.RazorPagesMovieContext _context;

        public CreateModel(RazorPagesMovie.Data.RazorPagesMovieContext context)
        {
            _context = context;
        }

        public IActionResult OnGet()
        {
            return Page();
        }

        [BindProperty]
        public Movie Movie { get; set; } = default!;
        

        // To protect from overposting attacks, see https://aka.ms/RazorPagesCRUD
        public async Task<IActionResult> OnPostAsync()
        {
          if (!ModelState.IsValid || _context.Movie == null || Movie == null)
            {
                return Page();
            }

            _context.Movie.Add(Movie);
            await _context.SaveChangesAsync();

            return RedirectToPage("./Index");
        }
    }
}

Metode ini OnGet menginisialisasi status apa pun yang diperlukan untuk halaman. Halaman Buat tidak memiliki status apa pun untuk diinisialisasi, sehingga Page dikembalikan. Kemudian dalam tutorial, contoh OnGet menginisialisasi status ditampilkan. Metode Page membuat PageResult objek yang merender Create.cshtml halaman.

Properti Movie menggunakan atribut [BindProperty] untuk ikut serta dalam pengikatan model. Saat formulir Buat memposting nilai formulir, runtime ASP.NET Core mengikat nilai yang diposting ke Movie model.

Metode OnPostAsync dijalankan ketika halaman memposting data formulir:

public async Task<IActionResult> OnPostAsync()
{
  if (!ModelState.IsValid || _context.Movie == null || Movie == null)
    {
        return Page();
    }

    _context.Movie.Add(Movie);
    await _context.SaveChangesAsync();

    return RedirectToPage("./Index");
}

Jika ada kesalahan model, formulir diputar ulang, bersama dengan data formulir apa pun yang diposting. Sebagian besar kesalahan model dapat ditangkap di sisi klien sebelum formulir diposting. Contoh kesalahan model adalah memposting nilai untuk bidang tanggal yang tidak dapat dikonversi ke tanggal. Validasi sisi klien dan validasi model dibahas nanti dalam tutorial.

Jika tidak ada kesalahan model:

  • Data disimpan.
  • Browser dialihkan ke halaman Indeks.

Halaman Buat Razor

Periksa Pages/Movies/Create.cshtmlRazor file Halaman:

@page
@model RazorPagesMovie.Pages.Movies.CreateModel

@{
    ViewData["Title"] = "Create";
}

<h1>Create</h1>

<h4>Movie</h4>
<hr />
<div class="row">
    <div class="col-md-4">
        <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>
            <div class="form-group">
                <label asp-for="Movie.ReleaseDate" class="control-label"></label>
                <input asp-for="Movie.ReleaseDate" class="form-control" />
                <span asp-validation-for="Movie.ReleaseDate" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Movie.Genre" class="control-label"></label>
                <input asp-for="Movie.Genre" class="form-control" />
                <span asp-validation-for="Movie.Genre" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Movie.Price" class="control-label"></label>
                <input asp-for="Movie.Price" class="form-control" />
                <span asp-validation-for="Movie.Price" class="text-danger"></span>
            </div>
            <div class="form-group">
                <input type="submit" value="Create" class="btn btn-primary" />
            </div>
        </form>
    </div>
</div>

<div>
    <a asp-page="Index">Back to List</a>
</div>

@section Scripts {
    @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}

Visual Studio menampilkan tag berikut dalam font tebal khas yang digunakan untuk Pembantu Tag:

  • <form method="post">
  • <div asp-validation-summary="ModelOnly" class="text-danger"></div>
  • <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>

Tampilan VS17 halaman Create.cshtml

Elemen <form method="post"> ini adalah Pembantu Tag Formulir. Pembantu Tag Formulir secara otomatis menyertakan token antiforgery.

Mesin perancah membuat Razor markup untuk setiap bidang dalam model, kecuali ID, mirip dengan yang berikut:

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

Bantuan Tag Validasi (<div asp-validation-summary dan <span asp-validation-for) menampilkan kesalahan validasi. Validasi dibahas secara lebih rinci nanti dalam seri ini.

Label Tag Helper (<label asp-for="Movie.Title" class="control-label"></label>) menghasilkan keterangan label dan [for] atribut untuk Title properti .

Pembantu Tag Input (<input asp-for="Movie.Title" class="form-control">) menggunakan atribut DataAnnotations dan menghasilkan atribut HTML yang diperlukan untuk Validasi jQuery di sisi klien.

Untuk informasi selengkapnya tentang Pembantu Tag seperti <form method="post">, lihat Pembantu Tag di ASP.NET Core.

Langkah berikutnya

Halaman Buat, Hapus, Detail, dan Edit

Periksa Pages/Movies/Index.cshtml.cs Model Halaman:

// Unused usings removed.
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using RazorPagesMovie.Models;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace RazorPagesMovie.Pages.Movies
{
    public class IndexModel : PageModel
    {
        private readonly RazorPagesMovie.Data.RazorPagesMovieContext _context;

        public IndexModel(RazorPagesMovie.Data.RazorPagesMovieContext context)
        {
            _context = context;
        }
        public IList<Movie> Movie { get;set; }

        public async Task OnGetAsync()
        {
            Movie = await _context.Movie.ToListAsync();
        }
    }
}

Razor Halaman berasal dari PageModel. Menurut konvensi, PageModelkelas -turunan diberi nama <PageName>Model. Konstruktor menggunakan injeksi dependensi untuk menambahkan ke RazorPagesMovieContext halaman:

public class IndexModel : PageModel
{
    private readonly RazorPagesMovie.Data.RazorPagesMovieContext _context;

    public IndexModel(RazorPagesMovie.Data.RazorPagesMovieContext context)
    {
        _context = context;
    }

Lihat Kode asinkron untuk informasi selengkapnya tentang pemrograman asinkron dengan Kerangka Kerja Entitas.

Saat permintaan dibuat untuk halaman, OnGetAsync metode mengembalikan daftar film ke Razor Halaman. Razor Pada Halaman, OnGetAsync atau OnGet dipanggil untuk menginisialisasi status halaman. Dalam hal ini, OnGetAsync mendapatkan daftar film dan menampilkannya.

Saat OnGet mengembalikan void atau OnGetAsync mengembalikan Task, tidak ada pernyataan pengembalian yang digunakan. Misalnya Privacy Halaman:

public class PrivacyModel : PageModel
{
    private readonly ILogger<PrivacyModel> _logger;

    public PrivacyModel(ILogger<PrivacyModel> logger)
    {
        _logger = logger;
    }

    public void OnGet()
    {
    }
}

Ketika jenis pengembalian adalah IActionResult atau Task<IActionResult>, pernyataan pengembalian harus disediakan. Misalnya, metode :Pages/Movies/Create.cshtml.csOnPostAsync

    public async Task<IActionResult> OnPostAsync()
    {
        if (!ModelState.IsValid)
        {
            return Page();
        }

        _context.Movie.Add(Movie);
        await _context.SaveChangesAsync();

        return RedirectToPage("./Index");
    }
}

Periksa Pages/Movies/Index.cshtmlRazor Halaman:

@page
@model RazorPagesMovie.Pages.Movies.IndexModel

@{
    ViewData["Title"] = "Index";
}

<h1>Index</h1>

<p>
    <a asp-page="Create">Create New</a>
</p>
<table class="table">
    <thead>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.Movie[0].Title)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movie[0].ReleaseDate)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movie[0].Genre)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movie[0].Price)
            </th>
            <th></th>
        </tr>
    </thead>
    <tbody>
@foreach (var item in Model.Movie) {
        <tr>
            <td>
                @Html.DisplayFor(modelItem => item.Title)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.ReleaseDate)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Genre)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Price)
            </td>
            <td>
                <a asp-page="./Edit" asp-route-id="@item.ID">Edit</a> |
                <a asp-page="./Details" asp-route-id="@item.ID">Details</a> |
                <a asp-page="./Delete" asp-route-id="@item.ID">Delete</a>
            </td>
        </tr>
}
    </tbody>
</table>

Razor dapat beralih dari HTML ke C# atau ke Razormarkup -spesifik. @ Ketika simbol diikuti dengan kata kunci yang Razor dipesan, simbol tersebut beralih ke Razormarkup -spesifik, jika tidak, simbol tersebut beralih ke C#.

Petunjuk @page

Direktif @pageRazor menjadikan file sebagai tindakan MVC, yang berarti dapat menangani permintaan. @page harus menjadi arahan Razor pertama di halaman. @page dan @model merupakan contoh transisi ke Razormarkup -spesifik. Lihat Razor sintaks untuk informasi selengkapnya.

Petunjuk @model

@page
@model RazorPagesMovie.Pages.Movies.IndexModel

Direktif @model menentukan jenis model yang diteruskan ke Razor Halaman. Dalam contoh sebelumnya, @model baris membuat PageModelkelas -turunan tersedia untuk Razor Halaman. Model ini digunakan di pembantu @Html.DisplayNameFor HTML dan @Html.DisplayFordi halaman.

Periksa ekspresi lambda yang digunakan dalam Pembantu HTML berikut:

@Html.DisplayNameFor(model => model.Movie[0].Title)

Pembantu DisplayNameFor HTML memeriksa properti yang direferensikan Title dalam ekspresi lambda untuk menentukan nama tampilan. Ekspresi lambda diperiksa daripada dievaluasi. Itu berarti tidak ada pelanggaran akses ketika model, , model.Movieatau model.Movie[0]null atau kosong. Saat ekspresi lambda dievaluasi, misalnya, dengan @Html.DisplayFor(modelItem => item.Title), nilai properti model dievaluasi.

Halaman tata letak

Pilih tautan Razormenu PagesMovie, Home, dan Privacy. Setiap halaman memperlihatkan tata letak menu yang sama. Tata letak menu diimplementasikan dalam Pages/Shared/_Layout.cshtml file.

Buka dan periksa Pages/Shared/_Layout.cshtml file.

Templat tata letak memungkinkan tata letak kontainer HTML menjadi:

  • Ditentukan di satu tempat.
  • Diterapkan di beberapa halaman di situs.

Temukan garisnya @RenderBody() . RenderBody adalah tempat penampung di mana semua tampilan khusus halaman muncul, dibungkus di halaman tata letak. Misalnya, pilih Privacy tautan dan Pages/Privacy.cshtml tampilan dirender di RenderBody dalam metode .

TampilkanData dan tata letak

Pertimbangkan markup berikut dari Pages/Movies/Index.cshtml file:

@page
@model RazorPagesMovie.Pages.Movies.IndexModel

@{
    ViewData["Title"] = "Index";
}

Markup yang disorot sebelumnya adalah contoh Razor transisi ke C#. Karakter { dan } mengapit blok kode C#.

Kelas PageModel dasar berisi ViewData properti kamus yang dapat digunakan untuk meneruskan data ke Tampilan. Objek ditambahkan ke ViewData kamus menggunakan pola nilai kunci. Dalam sampel sebelumnya, Title properti ditambahkan ke ViewData kamus.

Properti Title digunakan dalam Pages/Shared/_Layout.cshtml file. Markup berikut menunjukkan beberapa baris _Layout.cshtml pertama file.

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>@ViewData["Title"] - RazorPagesMovie</title>

    @*Markup removed for brevity.*@

Baris @*Markup removed for brevity.*@ adalah Razor komentar. Tidak seperti komentar <!-- -->HTML , Razor komentar tidak dikirim ke klien. Lihat dokumen web MDN: Mulai menggunakan HTML untuk informasi selengkapnya.

Memperbarui tata letak

  1. <title> Ubah elemen dalam Pages/Shared/_Layout.cshtml file untuk menampilkan Film daripada RazorPagesMovie.

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>@ViewData["Title"] - Movie</title>
    
  2. Temukan elemen jangkar berikut dalam Pages/Shared/_Layout.cshtml file.

    <a class="navbar-brand" asp-area="" asp-page="/Index">RazorPagesMovie</a>
    
  3. Ganti elemen sebelumnya dengan markup berikut:

    <a class="navbar-brand" asp-page="/Movies/Index">RpMovie</a>
    

    Elemen jangkar sebelumnya adalah Pembantu Tag. Dalam hal ini, ini adalah Pembantu Tag Jangkar. Atribut asp-page="/Movies/Index" dan nilai Tag Helper membuat tautan ke /Movies/IndexRazor Halaman. Nilai asp-area atribut kosong, sehingga area tidak digunakan dalam tautan. Lihat Area untuk informasi selengkapnya.

  4. Simpan perubahan dan uji aplikasi dengan memilih tautan RpMovie . Lihat file _Layout.cshtml di GitHub jika Anda memiliki masalah.

  5. HomeUji tautan , RpMovie, Buat, Edit, dan Hapus. Setiap halaman mengatur judul, yang dapat Anda lihat di tab browser. Saat Anda menandai halaman, judul digunakan untuk bookmark.

Catatan

Anda mungkin tidak dapat memasukkan koma desimal di Price bidang . 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 mengglolisisasi aplikasi. Lihat masalah GitHub 4076 ini untuk instruksi tentang menambahkan koma desimal.

Properti Layout diatur dalam Pages/_ViewStart.cshtml file:

@{
    Layout = "_Layout";
}

Markup sebelumnya mengatur file tata letak ke Pages/Shared/_Layout.cshtml untuk semua Razor file di bawah folder Halaman . Lihat Tata Letak untuk informasi selengkapnya.

Model buat halaman

Periksa Pages/Movies/Create.cshtml.cs model halaman:

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using RazorPagesMovie.Models;
using System;
using System.Threading.Tasks;

namespace RazorPagesMovie.Pages.Movies
{
    public class CreateModel : PageModel
    {
        private readonly RazorPagesMovie.Data.RazorPagesMovieContext _context;

        public CreateModel(RazorPagesMovie.Data.RazorPagesMovieContext context)
        {
            _context = context;
        }

        public IActionResult OnGet()
        {
            return Page();
        }

        [BindProperty]
        public Movie Movie { get; set; }

        public async Task<IActionResult> OnPostAsync()
        {
            if (!ModelState.IsValid)
            {
                return Page();
            }

            _context.Movie.Add(Movie);
            await _context.SaveChangesAsync();

            return RedirectToPage("./Index");
        }
    }
}

Metode ini OnGet menginisialisasi status apa pun yang diperlukan untuk halaman. Halaman Buat tidak memiliki status apa pun untuk diinisialisasi, sehingga Page dikembalikan. Kemudian dalam tutorial, contoh OnGet menginisialisasi status ditampilkan. Metode Page membuat PageResult objek yang merender Create.cshtml halaman.

Properti Movie menggunakan atribut [BindProperty] untuk ikut serta dalam pengikatan model. Saat formulir Buat memposting nilai formulir, runtime ASP.NET Core mengikat nilai yang diposting ke Movie model.

Metode OnPostAsync dijalankan ketika halaman memposting data formulir:

public async Task<IActionResult> OnPostAsync()
{
    if (!ModelState.IsValid)
    {
        return Page();
    }

    _context.Movie.Add(Movie);
    await _context.SaveChangesAsync();

    return RedirectToPage("./Index");
}

Jika ada kesalahan model, formulir diputar ulang, bersama dengan data formulir apa pun yang diposting. Sebagian besar kesalahan model dapat ditangkap di sisi klien sebelum formulir diposting. Contoh kesalahan model adalah memposting nilai untuk bidang tanggal yang tidak dapat dikonversi ke tanggal. Validasi sisi klien dan validasi model dibahas nanti dalam tutorial.

Jika tidak ada kesalahan model:

  • Data disimpan.
  • Browser dialihkan ke halaman Indeks.

Halaman Buat Razor

Periksa Pages/Movies/Create.cshtmlRazor file Halaman:

@page
@model RazorPagesMovie.Pages.Movies.CreateModel

@{
    ViewData["Title"] = "Create";
}

<h1>Create</h1>

<h4>Movie</h4>
<hr />
<div class="row">
    <div class="col-md-4">
        <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>
            <div class="form-group">
                <label asp-for="Movie.ReleaseDate" class="control-label"></label>
                <input asp-for="Movie.ReleaseDate" class="form-control" />
                <span asp-validation-for="Movie.ReleaseDate" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Movie.Genre" class="control-label"></label>
                <input asp-for="Movie.Genre" class="form-control" />
                <span asp-validation-for="Movie.Genre" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Movie.Price" class="control-label"></label>
                <input asp-for="Movie.Price" class="form-control" />
                <span asp-validation-for="Movie.Price" class="text-danger"></span>
            </div>
            <div class="form-group">
                <input type="submit" value="Create" class="btn btn-primary" />
            </div>
        </form>
    </div>
</div>

<div>
    <a asp-page="Index">Back to List</a>
</div>

@section Scripts {
    @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}

Visual Studio menampilkan tag berikut dalam font tebal khas yang digunakan untuk Pembantu Tag:

  • <form method="post">
  • <div asp-validation-summary="ModelOnly" class="text-danger"></div>
  • <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>

Tampilan VS17 halaman Create.cshtml

Elemen <form method="post"> ini adalah Pembantu Tag Formulir. Pembantu Tag Formulir secara otomatis menyertakan token antiforgery.

Mesin perancah membuat Razor markup untuk setiap bidang dalam model, kecuali ID, mirip dengan yang berikut:

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

Bantuan Tag Validasi (<div asp-validation-summary dan <span asp-validation-for) menampilkan kesalahan validasi. Validasi dibahas secara lebih rinci nanti dalam seri ini.

Label Tag Helper (<label asp-for="Movie.Title" class="control-label"></label>) menghasilkan keterangan label dan [for] atribut untuk Title properti .

Pembantu Tag Input (<input asp-for="Movie.Title" class="form-control">) menggunakan atribut DataAnnotations dan menghasilkan atribut HTML yang diperlukan untuk Validasi jQuery di sisi klien.

Untuk informasi selengkapnya tentang Pembantu Tag seperti <form method="post">, lihat Pembantu Tag di ASP.NET Core.

Langkah berikutnya