Bagikan melalui


Bagian 6, metode dan tampilan pengontrol 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

Kami memiliki awal yang baik untuk aplikasi film, tetapi presentasinya tidak ideal, misalnya, ReleaseDate harus dua kata.

Tampilan indeks: Tanggal Rilis adalah satu kata (tanpa spasi) dan setiap tanggal rilis film menunjukkan waktu pukul 12.00

Models/Movie.cs Buka file dan tambahkan baris yang disorot yang ditunjukkan di bawah ini:

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

namespace MvcMovie.Models;

public class Movie
{
    public int Id { get; set; }
    public string? Title { get; set; }
    
    [Display(Name = "Release Date")]
    [DataType(DataType.Date)]
    public DateTime ReleaseDate { get; set; }
    public string? Genre { get; set; }
    [Column(TypeName = "decimal(18, 2)")]
    public decimal Price { get; set; }
}

DataAnnotations dijelaskan dalam tutorial berikutnya. Atribut Tampilan menentukan apa yang harus ditampilkan untuk nama bidang (dalam hal ini "Tanggal Rilis" alih-alih "ReleaseDate"). Atribut DataType menentukan jenis data (Tanggal), sehingga informasi waktu yang disimpan di bidang tidak ditampilkan.

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.

Telusuri ke Movies pengontrol dan tahan penunjuk mouse di atas tautan Edit untuk melihat URL target.

Jendela browser dengan mouse di atas tautan Edit dan Url https://localhost:5001/Movies/Edit/5 tautan ditampilkan

Tautan Edit, Detail, dan Hapus dihasilkan oleh Core MVC Anchor Tag Helper dalam Views/Movies/Index.cshtml file.

        <a asp-action="Edit" asp-route-id="@item.Id">Edit</a> |
        <a asp-action="Details" asp-route-id="@item.Id">Details</a> |
        <a asp-action="Delete" asp-route-id="@item.Id">Delete</a>
    </td>
</tr>

Pembantu Tag mengaktifkan kode sisi server untuk berpartisipasi dalam membuat dan merender elemen HTML dalam file Razor. Dalam kode di atas, AnchorTagHelper secara dinamis menghasilkan nilai atribut HTML href dari metode tindakan pengontrol dan id rute. Anda menggunakan Tampilkan Sumber dari browser favorit Anda atau gunakan alat pengembang untuk memeriksa markup yang dihasilkan. Sebagian HTML yang dihasilkan ditunjukkan di bawah ini:

 <td>
    <a href="/Movies/Edit/4"> Edit </a> |
    <a href="/Movies/Details/4"> Details </a> |
    <a href="/Movies/Delete/4"> Delete </a>
</td>

Ingat format untuk set perutean dalam Program.cs file:

app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");

ASP.NET Core diterjemahkan https://localhost:5001/Movies/Edit/4 ke dalam permintaan ke Edit metode Movies tindakan pengontrol dengan parameter Id 4. (Metode pengontrol juga dikenal sebagai metode tindakan.)

Pembantu Tag adalah salah satu fitur baru paling populer di ASP.NET Core. Untuk informasi selengkapnya, lihat Sumber daya tambahan.

Movies Buka pengontrol dan periksa dua Edit metode tindakan. Kode berikut menunjukkan HTTP GET Edit metode , yang mengambil film dan mengisi formulir edit yang dihasilkan oleh Edit.cshtmlRazor file.

// GET: Movies/Edit/5
public async Task<IActionResult> Edit(int? id)
{
    if (id == null)
    {
        return NotFound();
    }

    var movie = await _context.Movie.FindAsync(id);
    if (movie == null)
    {
        return NotFound();
    }
    return View(movie);
}

Kode berikut menunjukkan HTTP POST Edit metode , yang memproses nilai film yang diposting:

// POST: Movies/Edit/5
// To protect from overposting attacks, enable the specific properties you want to bind to.
// For more details, see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id, [Bind("Id,Title,ReleaseDate,Genre,Price,Rating")] Movie movie)
{
    if (id != movie.Id)
    {
        return NotFound();
    }

    if (ModelState.IsValid)
    {
        try
        {
            _context.Update(movie);
            await _context.SaveChangesAsync();
        }
        catch (DbUpdateConcurrencyException)
        {
            if (!MovieExists(movie.Id))
            {
                return NotFound();
            }
            else
            {
                throw;
            }
        }
        return RedirectToAction(nameof(Index));
    }
    return View(movie);
}

Atribut [Bind] adalah salah satu cara untuk melindungi dari posting berlebihan. Anda hanya boleh menyertakan properti dalam [Bind] atribut yang ingin Anda ubah. Untuk informasi selengkapnya, lihat Melindungi pengontrol Anda dari postingan berlebihan. ViewModels menyediakan pendekatan alternatif untuk mencegah pengiriman berlebihan.

Perhatikan metode tindakan kedua Edit didahului oleh [HttpPost] atribut .

// POST: Movies/Edit/5
// To protect from overposting attacks, enable the specific properties you want to bind to.
// For more details, see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id, [Bind("Id,Title,ReleaseDate,Genre,Price,Rating")] Movie movie)
{
    if (id != movie.Id)
    {
        return NotFound();
    }

    if (ModelState.IsValid)
    {
        try
        {
            _context.Update(movie);
            await _context.SaveChangesAsync();
        }
        catch (DbUpdateConcurrencyException)
        {
            if (!MovieExists(movie.Id))
            {
                return NotFound();
            }
            else
            {
                throw;
            }
        }
        return RedirectToAction(nameof(Index));
    }
    return View(movie);
}

Atribut HttpPost menentukan bahwa metode ini Edit hanya dapat dipanggil untuk POST permintaan. Anda dapat menerapkan atribut ke [HttpGet] metode edit pertama, tetapi itu tidak diperlukan karena [HttpGet] merupakan default.

Atribut ValidateAntiForgeryToken ini digunakan untuk mencegah pemalsuan permintaan dan dipasangkan dengan token anti-pemalsuan yang dihasilkan dalam file tampilan edit (Views/Movies/Edit.cshtml). File tampilan edit menghasilkan token anti-pemalsuan dengan Pembantu Tag Formulir.

<form asp-action="Edit">

Pembantu Tag Formulir menghasilkan token anti-pemalsuan tersembunyi yang harus cocok dengan [ValidateAntiForgeryToken] token anti-pemalsuan yang dihasilkan dalam Edit metode pengontrol Film. Untuk informasi selengkapnya, lihat Mencegah serangan Pemalsuan Permintaan Antar Situs (XSRF/CSRF) di ASP.NET Core.

Metode mengambil HttpGet Edit parameter film ID , mencari film menggunakan metode Kerangka Kerja FindAsync Entitas, dan mengembalikan film yang dipilih ke tampilan Edit. Jika film tidak dapat ditemukan, NotFound (HTTP 404) dikembalikan.

// GET: Movies/Edit/5
public async Task<IActionResult> Edit(int? id)
{
    if (id == null)
    {
        return NotFound();
    }

    var movie = await _context.Movie.FindAsync(id);
    if (movie == null)
    {
        return NotFound();
    }
    return View(movie);
}

Ketika sistem perancah membuat tampilan Edit, sistem memeriksa Movie kelas dan membuat kode untuk merender <label> dan <input> elemen untuk setiap properti kelas. Contoh berikut menunjukkan tampilan Edit yang dihasilkan oleh sistem perancah Visual Studio:

@model MvcMovie.Models.Movie

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

<h1>Edit</h1>

<h4>Movie</h4>
<hr />
<div class="row">
    <div class="col-md-4">
        <form asp-action="Edit">
            <div asp-validation-summary="ModelOnly" class="text-danger"></div>
            <input type="hidden" asp-for="Id" />
            <div class="form-group">
                <label asp-for="Title" class="control-label"></label>
                <input asp-for="Title" class="form-control" />
                <span asp-validation-for="Title" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="ReleaseDate" class="control-label"></label>
                <input asp-for="ReleaseDate" class="form-control" />
                <span asp-validation-for="ReleaseDate" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Genre" class="control-label"></label>
                <input asp-for="Genre" class="form-control" />
                <span asp-validation-for="Genre" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Price" class="control-label"></label>
                <input asp-for="Price" class="form-control" />
                <span asp-validation-for="Price" class="text-danger"></span>
            </div>
            <div class="form-group">
                <input type="submit" value="Save" class="btn btn-primary" />
            </div>
        </form>
    </div>
</div>

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

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

Perhatikan bagaimana templat tampilan memiliki @model MvcMovie.Models.Movie pernyataan di bagian atas file. @model MvcMovie.Models.Movie menentukan bahwa tampilan mengharapkan model untuk templat tampilan berjenis Movie.

Kode perancah menggunakan beberapa metode Pembantu Tag untuk menyederhanakan markup HTML. Pembantu Tag Label menampilkan nama bidang ("Judul", "ReleaseDate", "Genre", atau "Harga"). Pembantu Tag Input merender elemen HTML<input>. Pembantu Tag Validasi menampilkan pesan validasi apa pun yang terkait dengan properti tersebut.

Jalankan aplikasi dan navigasikan ke /Movies URL. Klik tautan Edit. Di browser, lihat sumber untuk halaman tersebut. HTML yang dihasilkan untuk elemen ditunjukkan <form> di bawah ini.

<form action="/Movies/Edit/7" method="post">
    <div class="form-horizontal">
        <h4>Movie</h4>
        <hr />
        <div class="text-danger" />
        <input type="hidden" data-val="true" data-val-required="The ID field is required." id="ID" name="ID" value="7" />
        <div class="form-group">
            <label class="control-label col-md-2" for="Genre" />
            <div class="col-md-10">
                <input class="form-control" type="text" id="Genre" name="Genre" value="Western" />
                <span class="text-danger field-validation-valid" data-valmsg-for="Genre" data-valmsg-replace="true"></span>
            </div>
        </div>
        <div class="form-group">
            <label class="control-label col-md-2" for="Price" />
            <div class="col-md-10">
                <input class="form-control" type="text" data-val="true" data-val-number="The field Price must be a number." data-val-required="The Price field is required." id="Price" name="Price" value="3.99" />
                <span class="text-danger field-validation-valid" data-valmsg-for="Price" data-valmsg-replace="true"></span>
            </div>
        </div>
        <!-- Markup removed for brevity -->
        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Save" class="btn btn-default" />
            </div>
        </div>
    </div>
    <input name="__RequestVerificationToken" type="hidden" value="CfDJ8Inyxgp63fRFqUePGvuI5jGZsloJu1L7X9le1gy7NCIlSduCRx9jDQClrV9pOTTmqUyXnJBXhmrjcUVDJyDUMm7-MF_9rK8aAZdRdlOri7FmKVkRe_2v5LIHGKFcTjPrWPYnc9AdSbomkiOSaTEg7RU" />
</form>

Elemen <input> berada dalam HTML <form> elemen yang atributnya action diatur untuk memposting ke /Movies/Edit/id URL. Data formulir akan diposting ke server saat tombol Save diklik. Baris terakhir sebelum elemen penutup </form> menunjukkan token XSRF tersembunyi yang dihasilkan oleh Pembantu Tag Formulir.

Memproses Permintaan POST

Daftar berikut menunjukkan [HttpPost] versi Edit metode tindakan.

// POST: Movies/Edit/5
// To protect from overposting attacks, enable the specific properties you want to bind to.
// For more details, see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id, [Bind("Id,Title,ReleaseDate,Genre,Price,Rating")] Movie movie)
{
    if (id != movie.Id)
    {
        return NotFound();
    }

    if (ModelState.IsValid)
    {
        try
        {
            _context.Update(movie);
            await _context.SaveChangesAsync();
        }
        catch (DbUpdateConcurrencyException)
        {
            if (!MovieExists(movie.Id))
            {
                return NotFound();
            }
            else
            {
                throw;
            }
        }
        return RedirectToAction(nameof(Index));
    }
    return View(movie);
}

Atribut [ValidateAntiForgeryToken] memvalidasi token XSRF tersembunyi yang dihasilkan oleh generator token anti-pemalsuan di Form Tag Helper

Sistem pengikatan model mengambil nilai formulir yang diposting dan membuat Movie objek yang diteruskan sebagai movie parameter . Properti ModelState.IsValid memverifikasi bahwa data yang dikirimkan dalam formulir dapat digunakan untuk memodifikasi (mengedit atau memperbarui) Movie objek. Jika data valid, data akan disimpan. Data film yang diperbarui (diedit) disimpan ke database dengan memanggil SaveChangesAsync metode konteks database. Setelah menyimpan data, kode mengalihkan pengguna ke Index metode MoviesController tindakan kelas, yang menampilkan koleksi film, termasuk perubahan yang baru saja dibuat.

Sebelum formulir diposting ke server, validasi sisi klien memeriksa aturan validasi apa pun pada bidang. Jika ada kesalahan validasi, pesan kesalahan ditampilkan dan formulir tidak diposting. Jika JavaScript dinonaktifkan, Anda tidak akan memiliki validasi sisi klien tetapi server akan mendeteksi nilai yang diposting yang tidak valid, dan nilai formulir akan diputar ulang dengan pesan kesalahan. Kemudian dalam tutorial kami memeriksa Validasi Model secara lebih rinci. Pembantu Tag Validasi dalam Views/Movies/Edit.cshtml templat tampilan mengurus menampilkan pesan kesalahan yang sesuai.

Edit tampilan: Pengecualian untuk nilai Harga abc yang salah menyatakan bahwa Bidang Harga harus berupa angka. Pengecualian untuk nilai Tanggal Rilis yang salah dari status xyz Masukkan tanggal yang valid.

HttpGet Semua metode dalam pengontrol film mengikuti pola yang sama. Mereka mendapatkan objek film (atau daftar objek, dalam kasus Index), dan meneruskan objek (model) ke tampilan. Metode Create meneruskan objek film kosong ke Create tampilan. Semua metode yang membuat, mengedit, menghapus, atau memodifikasi data melakukannya dalam [HttpPost] kelebihan beban metode. Memodifikasi data dalam HTTP GET metode adalah risiko keamanan. Memodifikasi data dalam HTTP GET metode juga melanggar praktik terbaik HTTP dan pola arsitektur REST , yang menentukan bahwa permintaan GET tidak boleh mengubah status aplikasi Anda. Dengan kata lain, melakukan operasi GET harus menjadi operasi aman yang tidak memiliki efek samping dan tidak memodifikasi data Anda yang bertahan.

Sumber Daya Tambahan:

Kami memiliki awal yang baik untuk aplikasi film, tetapi presentasinya tidak ideal, misalnya, ReleaseDate harus dua kata.

Tampilan indeks: Tanggal Rilis adalah satu kata (tanpa spasi) dan setiap tanggal rilis film menunjukkan waktu pukul 12.00

Models/Movie.cs Buka file dan tambahkan baris yang disorot yang ditunjukkan di bawah ini:

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

namespace MvcMovie.Models;

public class Movie
{
    public int Id { get; set; }
    public string? Title { get; set; }
    
    [Display(Name = "Release Date")]
    [DataType(DataType.Date)]
    public DateTime ReleaseDate { get; set; }
    public string? Genre { get; set; }
    [Column(TypeName = "decimal(18, 2)")]
    public decimal Price { get; set; }
}

DataAnnotations dijelaskan dalam tutorial berikutnya. Atribut Tampilan menentukan apa yang harus ditampilkan untuk nama bidang (dalam hal ini "Tanggal Rilis" alih-alih "ReleaseDate"). Atribut DataType menentukan jenis data (Tanggal), sehingga informasi waktu yang disimpan di bidang tidak ditampilkan.

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.

Telusuri ke Movies pengontrol dan tahan penunjuk mouse di atas tautan Edit untuk melihat URL target.

Jendela browser dengan mouse di atas tautan Edit dan Url https://localhost:5001/Movies/Edit/5 tautan ditampilkan

Tautan Edit, Detail, dan Hapus dihasilkan oleh Core MVC Anchor Tag Helper dalam Views/Movies/Index.cshtml file.

        <a asp-action="Edit" asp-route-id="@item.Id">Edit</a> |
        <a asp-action="Details" asp-route-id="@item.Id">Details</a> |
        <a asp-action="Delete" asp-route-id="@item.Id">Delete</a>
    </td>
</tr>

Pembantu Tag mengaktifkan kode sisi server untuk berpartisipasi dalam membuat dan merender elemen HTML dalam file Razor. Dalam kode di atas, AnchorTagHelper secara dinamis menghasilkan nilai atribut HTML href dari metode tindakan pengontrol dan id rute. Anda menggunakan Tampilkan Sumber dari browser favorit Anda atau gunakan alat pengembang untuk memeriksa markup yang dihasilkan. Sebagian HTML yang dihasilkan ditunjukkan di bawah ini:

 <td>
    <a href="/Movies/Edit/4"> Edit </a> |
    <a href="/Movies/Details/4"> Details </a> |
    <a href="/Movies/Delete/4"> Delete </a>
</td>

Ingat format untuk set perutean dalam Program.cs file:

app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");

ASP.NET Core diterjemahkan https://localhost:5001/Movies/Edit/4 ke dalam permintaan ke Edit metode Movies tindakan pengontrol dengan parameter Id 4. (Metode pengontrol juga dikenal sebagai metode tindakan.)

Pembantu Tag adalah salah satu fitur baru paling populer di ASP.NET Core. Untuk informasi selengkapnya, lihat Sumber daya tambahan.

Movies Buka pengontrol dan periksa dua Edit metode tindakan. Kode berikut menunjukkan HTTP GET Edit metode , yang mengambil film dan mengisi formulir edit yang dihasilkan oleh Edit.cshtmlRazor file.

// GET: Movies/Edit/5
public async Task<IActionResult> Edit(int? id)
{
    if (id == null)
    {
        return NotFound();
    }

    var movie = await _context.Movie.FindAsync(id);
    if (movie == null)
    {
        return NotFound();
    }
    return View(movie);
}

Kode berikut menunjukkan HTTP POST Edit metode , yang memproses nilai film yang diposting:

// POST: Movies/Edit/5
// To protect from overposting attacks, enable the specific properties you want to bind to.
// For more details, see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id, [Bind("Id,Title,ReleaseDate,Genre,Price,Rating")] Movie movie)
{
    if (id != movie.Id)
    {
        return NotFound();
    }

    if (ModelState.IsValid)
    {
        try
        {
            _context.Update(movie);
            await _context.SaveChangesAsync();
        }
        catch (DbUpdateConcurrencyException)
        {
            if (!MovieExists(movie.Id))
            {
                return NotFound();
            }
            else
            {
                throw;
            }
        }
        return RedirectToAction(nameof(Index));
    }
    return View(movie);
}

Atribut [Bind] adalah salah satu cara untuk melindungi dari posting berlebihan. Anda hanya boleh menyertakan properti dalam [Bind] atribut yang ingin Anda ubah. Untuk informasi selengkapnya, lihat Melindungi pengontrol Anda dari postingan berlebihan. ViewModels menyediakan pendekatan alternatif untuk mencegah pengiriman berlebihan.

Perhatikan metode tindakan kedua Edit didahului oleh [HttpPost] atribut .

// POST: Movies/Edit/5
// To protect from overposting attacks, enable the specific properties you want to bind to.
// For more details, see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id, [Bind("Id,Title,ReleaseDate,Genre,Price,Rating")] Movie movie)
{
    if (id != movie.Id)
    {
        return NotFound();
    }

    if (ModelState.IsValid)
    {
        try
        {
            _context.Update(movie);
            await _context.SaveChangesAsync();
        }
        catch (DbUpdateConcurrencyException)
        {
            if (!MovieExists(movie.Id))
            {
                return NotFound();
            }
            else
            {
                throw;
            }
        }
        return RedirectToAction(nameof(Index));
    }
    return View(movie);
}

Atribut HttpPost menentukan bahwa metode ini Edit hanya dapat dipanggil untuk POST permintaan. Anda dapat menerapkan atribut ke [HttpGet] metode edit pertama, tetapi itu tidak diperlukan karena [HttpGet] merupakan default.

Atribut ValidateAntiForgeryToken ini digunakan untuk mencegah pemalsuan permintaan dan dipasangkan dengan token anti-pemalsuan yang dihasilkan dalam file tampilan edit (Views/Movies/Edit.cshtml). File tampilan edit menghasilkan token anti-pemalsuan dengan Pembantu Tag Formulir.

<form asp-action="Edit">

Pembantu Tag Formulir menghasilkan token anti-pemalsuan tersembunyi yang harus cocok dengan [ValidateAntiForgeryToken] token anti-pemalsuan yang dihasilkan dalam Edit metode pengontrol Film. Untuk informasi selengkapnya, lihat Mencegah serangan Pemalsuan Permintaan Antar Situs (XSRF/CSRF) di ASP.NET Core.

Metode mengambil HttpGet Edit parameter film ID , mencari film menggunakan metode Kerangka Kerja FindAsync Entitas, dan mengembalikan film yang dipilih ke tampilan Edit. Jika film tidak dapat ditemukan, NotFound (HTTP 404) dikembalikan.

// GET: Movies/Edit/5
public async Task<IActionResult> Edit(int? id)
{
    if (id == null)
    {
        return NotFound();
    }

    var movie = await _context.Movie.FindAsync(id);
    if (movie == null)
    {
        return NotFound();
    }
    return View(movie);
}

Ketika sistem perancah membuat tampilan Edit, sistem memeriksa Movie kelas dan membuat kode untuk merender <label> dan <input> elemen untuk setiap properti kelas. Contoh berikut menunjukkan tampilan Edit yang dihasilkan oleh sistem perancah Visual Studio:

@model MvcMovie.Models.Movie

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

<h1>Edit</h1>

<h4>Movie</h4>
<hr />
<div class="row">
    <div class="col-md-4">
        <form asp-action="Edit">
            <div asp-validation-summary="ModelOnly" class="text-danger"></div>
            <input type="hidden" asp-for="Id" />
            <div class="form-group">
                <label asp-for="Title" class="control-label"></label>
                <input asp-for="Title" class="form-control" />
                <span asp-validation-for="Title" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="ReleaseDate" class="control-label"></label>
                <input asp-for="ReleaseDate" class="form-control" />
                <span asp-validation-for="ReleaseDate" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Genre" class="control-label"></label>
                <input asp-for="Genre" class="form-control" />
                <span asp-validation-for="Genre" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Price" class="control-label"></label>
                <input asp-for="Price" class="form-control" />
                <span asp-validation-for="Price" class="text-danger"></span>
            </div>
            <div class="form-group">
                <input type="submit" value="Save" class="btn btn-primary" />
            </div>
        </form>
    </div>
</div>

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

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

Perhatikan bagaimana templat tampilan memiliki @model MvcMovie.Models.Movie pernyataan di bagian atas file. @model MvcMovie.Models.Movie menentukan bahwa tampilan mengharapkan model untuk templat tampilan berjenis Movie.

Kode perancah menggunakan beberapa metode Pembantu Tag untuk menyederhanakan markup HTML. Pembantu Tag Label menampilkan nama bidang ("Judul", "ReleaseDate", "Genre", atau "Harga"). Pembantu Tag Input merender elemen HTML<input>. Pembantu Tag Validasi menampilkan pesan validasi apa pun yang terkait dengan properti tersebut.

Jalankan aplikasi dan navigasikan ke /Movies URL. Klik tautan Edit. Di browser, lihat sumber untuk halaman tersebut. HTML yang dihasilkan untuk elemen ditunjukkan <form> di bawah ini.

<form action="/Movies/Edit/7" method="post">
    <div class="form-horizontal">
        <h4>Movie</h4>
        <hr />
        <div class="text-danger" />
        <input type="hidden" data-val="true" data-val-required="The ID field is required." id="ID" name="ID" value="7" />
        <div class="form-group">
            <label class="control-label col-md-2" for="Genre" />
            <div class="col-md-10">
                <input class="form-control" type="text" id="Genre" name="Genre" value="Western" />
                <span class="text-danger field-validation-valid" data-valmsg-for="Genre" data-valmsg-replace="true"></span>
            </div>
        </div>
        <div class="form-group">
            <label class="control-label col-md-2" for="Price" />
            <div class="col-md-10">
                <input class="form-control" type="text" data-val="true" data-val-number="The field Price must be a number." data-val-required="The Price field is required." id="Price" name="Price" value="3.99" />
                <span class="text-danger field-validation-valid" data-valmsg-for="Price" data-valmsg-replace="true"></span>
            </div>
        </div>
        <!-- Markup removed for brevity -->
        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Save" class="btn btn-default" />
            </div>
        </div>
    </div>
    <input name="__RequestVerificationToken" type="hidden" value="CfDJ8Inyxgp63fRFqUePGvuI5jGZsloJu1L7X9le1gy7NCIlSduCRx9jDQClrV9pOTTmqUyXnJBXhmrjcUVDJyDUMm7-MF_9rK8aAZdRdlOri7FmKVkRe_2v5LIHGKFcTjPrWPYnc9AdSbomkiOSaTEg7RU" />
</form>

Elemen <input> berada dalam HTML <form> elemen yang atributnya action diatur untuk memposting ke /Movies/Edit/id URL. Data formulir akan diposting ke server saat tombol Save diklik. Baris terakhir sebelum elemen penutup </form> menunjukkan token XSRF tersembunyi yang dihasilkan oleh Pembantu Tag Formulir.

Memproses Permintaan POST

Daftar berikut menunjukkan [HttpPost] versi Edit metode tindakan.

// POST: Movies/Edit/5
// To protect from overposting attacks, enable the specific properties you want to bind to.
// For more details, see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id, [Bind("Id,Title,ReleaseDate,Genre,Price,Rating")] Movie movie)
{
    if (id != movie.Id)
    {
        return NotFound();
    }

    if (ModelState.IsValid)
    {
        try
        {
            _context.Update(movie);
            await _context.SaveChangesAsync();
        }
        catch (DbUpdateConcurrencyException)
        {
            if (!MovieExists(movie.Id))
            {
                return NotFound();
            }
            else
            {
                throw;
            }
        }
        return RedirectToAction(nameof(Index));
    }
    return View(movie);
}

Atribut [ValidateAntiForgeryToken] memvalidasi token XSRF tersembunyi yang dihasilkan oleh generator token anti-pemalsuan di Form Tag Helper

Sistem pengikatan model mengambil nilai formulir yang diposting dan membuat Movie objek yang diteruskan sebagai movie parameter . Properti ModelState.IsValid memverifikasi bahwa data yang dikirimkan dalam formulir dapat digunakan untuk memodifikasi (mengedit atau memperbarui) Movie objek. Jika data valid, data akan disimpan. Data film yang diperbarui (diedit) disimpan ke database dengan memanggil SaveChangesAsync metode konteks database. Setelah menyimpan data, kode mengalihkan pengguna ke Index metode MoviesController tindakan kelas, yang menampilkan koleksi film, termasuk perubahan yang baru saja dibuat.

Sebelum formulir diposting ke server, validasi sisi klien memeriksa aturan validasi apa pun pada bidang. Jika ada kesalahan validasi, pesan kesalahan ditampilkan dan formulir tidak diposting. Jika JavaScript dinonaktifkan, Anda tidak akan memiliki validasi sisi klien tetapi server akan mendeteksi nilai yang diposting yang tidak valid, dan nilai formulir akan diputar ulang dengan pesan kesalahan. Kemudian dalam tutorial kami memeriksa Validasi Model secara lebih rinci. Pembantu Tag Validasi dalam Views/Movies/Edit.cshtml templat tampilan mengurus menampilkan pesan kesalahan yang sesuai.

Edit tampilan: Pengecualian untuk nilai Harga abc yang salah menyatakan bahwa Bidang Harga harus berupa angka. Pengecualian untuk nilai Tanggal Rilis yang salah dari status xyz Masukkan tanggal yang valid.

HttpGet Semua metode dalam pengontrol film mengikuti pola yang sama. Mereka mendapatkan objek film (atau daftar objek, dalam kasus Index), dan meneruskan objek (model) ke tampilan. Metode Create meneruskan objek film kosong ke Create tampilan. Semua metode yang membuat, mengedit, menghapus, atau memodifikasi data melakukannya dalam [HttpPost] kelebihan beban metode. Memodifikasi data dalam HTTP GET metode adalah risiko keamanan. Memodifikasi data dalam HTTP GET metode juga melanggar praktik terbaik HTTP dan pola arsitektur REST , yang menentukan bahwa permintaan GET tidak boleh mengubah status aplikasi Anda. Dengan kata lain, melakukan operasi GET harus menjadi operasi aman yang tidak memiliki efek samping dan tidak memodifikasi data Anda yang bertahan.

Sumber Daya Tambahan:

Kami memiliki awal yang baik untuk aplikasi film, tetapi presentasinya tidak ideal, misalnya, ReleaseDate harus dua kata.

Tampilan indeks: Tanggal Rilis adalah satu kata (tanpa spasi) dan setiap tanggal rilis film menunjukkan waktu pukul 12.00

Models/Movie.cs Buka file dan tambahkan baris yang disorot yang ditunjukkan di bawah ini:

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

namespace MvcMovie.Models
{
    public class Movie
    {
        public int Id { get; set; }
        public string? Title { get; set; }

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

        [Column(TypeName = "decimal(18, 2)")]
        public decimal Price { get; set; }
    }
}

DataAnnotations dijelaskan dalam tutorial berikutnya. Atribut Tampilan menentukan apa yang harus ditampilkan untuk nama bidang (dalam hal ini "Tanggal Rilis" alih-alih "ReleaseDate"). Atribut DataType menentukan jenis data (Tanggal), sehingga informasi waktu yang disimpan di bidang tidak ditampilkan.

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.

Telusuri ke Movies pengontrol dan tahan penunjuk mouse di atas tautan Edit untuk melihat URL target.

Jendela browser dengan mouse di atas tautan Edit dan Url https://localhost:5001/Movies/Edit/5 tautan ditampilkan

Tautan Edit, Detail, dan Hapus dihasilkan oleh Core MVC Anchor Tag Helper dalam Views/Movies/Index.cshtml file.

        <a asp-action="Edit" asp-route-id="@item.Id">Edit</a> |
        <a asp-action="Details" asp-route-id="@item.Id">Details</a> |
        <a asp-action="Delete" asp-route-id="@item.Id">Delete</a>
    </td>
</tr>

Pembantu Tag mengaktifkan kode sisi server untuk berpartisipasi dalam membuat dan merender elemen HTML dalam file Razor. Dalam kode di atas, AnchorTagHelper secara dinamis menghasilkan nilai atribut HTML href dari metode tindakan pengontrol dan id rute. Anda menggunakan Tampilkan Sumber dari browser favorit Anda atau gunakan alat pengembang untuk memeriksa markup yang dihasilkan. Sebagian HTML yang dihasilkan ditunjukkan di bawah ini:

 <td>
    <a href="/Movies/Edit/4"> Edit </a> |
    <a href="/Movies/Details/4"> Details </a> |
    <a href="/Movies/Delete/4"> Delete </a>
</td>

Ingat format untuk set perutean dalam Program.cs file:

app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");

ASP.NET Core diterjemahkan https://localhost:5001/Movies/Edit/4 ke dalam permintaan ke Edit metode Movies tindakan pengontrol dengan parameter Id 4. (Metode pengontrol juga dikenal sebagai metode tindakan.)

Pembantu Tag adalah fitur populer di ASP.NET Core. Untuk informasi selengkapnya tentang sumber daya tersebut, lihat Sumber daya tambahan.

Movies Buka pengontrol dan periksa dua Edit metode tindakan. Kode berikut menunjukkan HTTP GET Edit metode , yang mengambil film dan mengisi formulir edit yang dihasilkan oleh Edit.cshtmlRazor file.

// GET: Movies/Edit/5
public async Task<IActionResult> Edit(int? id)
{
    if (id == null)
    {
        return NotFound();
    }

    var movie = await _context.Movie.FindAsync(id);
    if (movie == null)
    {
        return NotFound();
    }
    return View(movie);
}

Kode berikut menunjukkan HTTP POST Edit metode , yang memproses nilai film yang diposting:

// POST: Movies/Edit/5
// To protect from overposting attacks, enable the specific properties you want to bind to.
// For more details, see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id, [Bind("Id,Title,ReleaseDate,Genre,Price,Rating")] Movie movie)
{
    if (id != movie.Id)
    {
        return NotFound();
    }

    if (ModelState.IsValid)
    {
        try
        {
            _context.Update(movie);
            await _context.SaveChangesAsync();
        }
        catch (DbUpdateConcurrencyException)
        {
            if (!MovieExists(movie.Id))
            {
                return NotFound();
            }
            else
            {
                throw;
            }
        }
        return RedirectToAction(nameof(Index));
    }
    return View(movie);
}

Atribut [Bind] adalah salah satu cara untuk melindungi dari posting berlebihan. Anda hanya boleh menyertakan properti dalam [Bind] atribut yang ingin Anda ubah. Untuk informasi selengkapnya, lihat Melindungi pengontrol Anda dari postingan berlebihan. ViewModels menyediakan pendekatan alternatif untuk mencegah pengiriman berlebihan.

Perhatikan metode tindakan kedua Edit didahului oleh [HttpPost] atribut .

// POST: Movies/Edit/5
// To protect from overposting attacks, enable the specific properties you want to bind to.
// For more details, see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id, [Bind("Id,Title,ReleaseDate,Genre,Price,Rating")] Movie movie)
{
    if (id != movie.Id)
    {
        return NotFound();
    }

    if (ModelState.IsValid)
    {
        try
        {
            _context.Update(movie);
            await _context.SaveChangesAsync();
        }
        catch (DbUpdateConcurrencyException)
        {
            if (!MovieExists(movie.Id))
            {
                return NotFound();
            }
            else
            {
                throw;
            }
        }
        return RedirectToAction(nameof(Index));
    }
    return View(movie);
}

Atribut HttpPost menentukan bahwa metode ini Edit hanya dapat dipanggil untuk POST permintaan. Anda dapat menerapkan atribut ke [HttpGet] metode edit pertama, tetapi itu tidak diperlukan karena [HttpGet] merupakan default.

Atribut ValidateAntiForgeryToken ini digunakan untuk mencegah pemalsuan permintaan dan dipasangkan dengan token anti-pemalsuan yang dihasilkan dalam file tampilan edit (Views/Movies/Edit.cshtml). File tampilan edit menghasilkan token anti-pemalsuan dengan Pembantu Tag Formulir.

<form asp-action="Edit">

Pembantu Tag Formulir menghasilkan token anti-pemalsuan tersembunyi yang harus cocok dengan [ValidateAntiForgeryToken] token anti-pemalsuan yang dihasilkan dalam Edit metode pengontrol Film. Untuk informasi selengkapnya, lihat Mencegah serangan Pemalsuan Permintaan Antar Situs (XSRF/CSRF) di ASP.NET Core.

Metode mengambil HttpGet Edit parameter film ID , mencari film menggunakan metode Kerangka Kerja FindAsync Entitas, dan mengembalikan film yang dipilih ke tampilan Edit. Jika film tidak dapat ditemukan, NotFound (HTTP 404) dikembalikan.

// GET: Movies/Edit/5
public async Task<IActionResult> Edit(int? id)
{
    if (id == null)
    {
        return NotFound();
    }

    var movie = await _context.Movie.FindAsync(id);
    if (movie == null)
    {
        return NotFound();
    }
    return View(movie);
}

Ketika sistem perancah membuat tampilan Edit, sistem memeriksa Movie kelas dan membuat kode untuk merender <label> dan <input> elemen untuk setiap properti kelas. Contoh berikut menunjukkan tampilan Edit yang dihasilkan oleh sistem perancah Visual Studio:

@model MvcMovie.Models.Movie

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

<h1>Edit</h1>

<h4>Movie</h4>
<hr />
<div class="row">
    <div class="col-md-4">
        <form asp-action="Edit">
            <div asp-validation-summary="ModelOnly" class="text-danger"></div>
            <input type="hidden" asp-for="Id" />
            <div class="form-group">
                <label asp-for="Title" class="control-label"></label>
                <input asp-for="Title" class="form-control" />
                <span asp-validation-for="Title" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="ReleaseDate" class="control-label"></label>
                <input asp-for="ReleaseDate" class="form-control" />
                <span asp-validation-for="ReleaseDate" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Genre" class="control-label"></label>
                <input asp-for="Genre" class="form-control" />
                <span asp-validation-for="Genre" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Price" class="control-label"></label>
                <input asp-for="Price" class="form-control" />
                <span asp-validation-for="Price" class="text-danger"></span>
            </div>
            <div class="form-group">
                <input type="submit" value="Save" class="btn btn-primary" />
            </div>
        </form>
    </div>
</div>

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

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

Perhatikan bagaimana templat tampilan memiliki @model MvcMovie.Models.Movie pernyataan di bagian atas file. @model MvcMovie.Models.Movie menentukan bahwa tampilan mengharapkan model untuk templat tampilan berjenis Movie.

Kode perancah menggunakan beberapa metode Pembantu Tag untuk menyederhanakan markup HTML. Pembantu Tag Label menampilkan nama bidang ("Judul", "ReleaseDate", "Genre", atau "Harga"). Pembantu Tag Input merender elemen HTML<input>. Pembantu Tag Validasi menampilkan pesan validasi apa pun yang terkait dengan properti tersebut.

Jalankan aplikasi dan navigasikan ke /Movies URL. Klik tautan Edit. Di browser, lihat sumber untuk halaman tersebut. HTML yang dihasilkan untuk elemen ditunjukkan <form> di bawah ini.

<form action="/Movies/Edit/7" method="post">
    <div class="form-horizontal">
        <h4>Movie</h4>
        <hr />
        <div class="text-danger" />
        <input type="hidden" data-val="true" data-val-required="The ID field is required." id="ID" name="ID" value="7" />
        <div class="form-group">
            <label class="control-label col-md-2" for="Genre" />
            <div class="col-md-10">
                <input class="form-control" type="text" id="Genre" name="Genre" value="Western" />
                <span class="text-danger field-validation-valid" data-valmsg-for="Genre" data-valmsg-replace="true"></span>
            </div>
        </div>
        <div class="form-group">
            <label class="control-label col-md-2" for="Price" />
            <div class="col-md-10">
                <input class="form-control" type="text" data-val="true" data-val-number="The field Price must be a number." data-val-required="The Price field is required." id="Price" name="Price" value="3.99" />
                <span class="text-danger field-validation-valid" data-valmsg-for="Price" data-valmsg-replace="true"></span>
            </div>
        </div>
        <!-- Markup removed for brevity -->
        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Save" class="btn btn-default" />
            </div>
        </div>
    </div>
    <input name="__RequestVerificationToken" type="hidden" value="CfDJ8Inyxgp63fRFqUePGvuI5jGZsloJu1L7X9le1gy7NCIlSduCRx9jDQClrV9pOTTmqUyXnJBXhmrjcUVDJyDUMm7-MF_9rK8aAZdRdlOri7FmKVkRe_2v5LIHGKFcTjPrWPYnc9AdSbomkiOSaTEg7RU" />
</form>

Elemen <input> berada dalam HTML <form> elemen yang atributnya action diatur untuk memposting ke /Movies/Edit/id URL. Data formulir akan diposting ke server saat tombol Save diklik. Baris terakhir sebelum elemen penutup </form> menunjukkan token XSRF tersembunyi yang dihasilkan oleh Pembantu Tag Formulir.

Memproses Permintaan POST

Daftar berikut menunjukkan [HttpPost] versi Edit metode tindakan.

// POST: Movies/Edit/5
// To protect from overposting attacks, enable the specific properties you want to bind to.
// For more details, see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id, [Bind("Id,Title,ReleaseDate,Genre,Price,Rating")] Movie movie)
{
    if (id != movie.Id)
    {
        return NotFound();
    }

    if (ModelState.IsValid)
    {
        try
        {
            _context.Update(movie);
            await _context.SaveChangesAsync();
        }
        catch (DbUpdateConcurrencyException)
        {
            if (!MovieExists(movie.Id))
            {
                return NotFound();
            }
            else
            {
                throw;
            }
        }
        return RedirectToAction(nameof(Index));
    }
    return View(movie);
}

Atribut [ValidateAntiForgeryToken] memvalidasi token XSRF tersembunyi yang dihasilkan oleh generator token anti-pemalsuan di Form Tag Helper

Sistem pengikatan model mengambil nilai formulir yang diposting dan membuat Movie objek yang diteruskan sebagai movie parameter . Properti ModelState.IsValid memverifikasi bahwa data yang dikirimkan dalam formulir dapat digunakan untuk memodifikasi (mengedit atau memperbarui) Movie objek. Jika data valid, data akan disimpan. Data film yang diperbarui (diedit) disimpan ke database dengan memanggil SaveChangesAsync metode konteks database. Setelah menyimpan data, kode mengalihkan pengguna ke Index metode MoviesController tindakan kelas, yang menampilkan koleksi film, termasuk perubahan yang baru saja dibuat.

Sebelum formulir diposting ke server, validasi sisi klien memeriksa aturan validasi apa pun pada bidang. Jika ada kesalahan validasi, pesan kesalahan ditampilkan dan formulir tidak diposting. Jika JavaScript dinonaktifkan, Anda tidak akan memiliki validasi sisi klien tetapi server akan mendeteksi nilai yang diposting yang tidak valid, dan nilai formulir akan diputar ulang dengan pesan kesalahan. Kemudian dalam tutorial kami memeriksa Validasi Model secara lebih rinci. Pembantu Tag Validasi dalam Views/Movies/Edit.cshtml templat tampilan mengurus menampilkan pesan kesalahan yang sesuai.

Edit tampilan: Pengecualian untuk nilai Harga abc yang salah menyatakan bahwa Bidang Harga harus berupa angka. Pengecualian untuk nilai Tanggal Rilis yang salah dari status xyz Masukkan tanggal yang valid.

HttpGet Semua metode dalam pengontrol film mengikuti pola yang sama. Mereka mendapatkan objek film (atau daftar objek, dalam kasus Index), dan meneruskan objek (model) ke tampilan. Metode Create meneruskan objek film kosong ke Create tampilan. Semua metode yang membuat, mengedit, menghapus, atau memodifikasi data melakukannya dalam [HttpPost] kelebihan beban metode. Memodifikasi data dalam HTTP GET metode adalah risiko keamanan. Memodifikasi data dalam HTTP GET metode juga melanggar praktik terbaik HTTP dan pola arsitektur REST , yang menentukan bahwa permintaan GET tidak boleh mengubah status aplikasi Anda. Dengan kata lain, melakukan operasi GET harus menjadi operasi aman yang tidak memiliki efek samping dan tidak memodifikasi data Anda yang bertahan.

Sumber Daya Tambahan:

Kami memiliki awal yang baik untuk aplikasi film, tetapi presentasinya tidak ideal, misalnya, ReleaseDate harus dua kata.

Tampilan indeks: Tanggal Rilis adalah satu kata (tanpa spasi) dan setiap tanggal rilis film menunjukkan waktu pukul 12.00

Models/Movie.cs Buka file dan tambahkan baris yang disorot yang ditunjukkan di bawah ini:

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

namespace MvcMovie.Models
{
    public class Movie
    {
        public int Id { get; set; }
        public string Title { get; set; }

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

        [Column(TypeName = "decimal(18, 2)")]
        public decimal Price { get; set; }
    }
}

Kami membahas DataAnnotations dalam tutorial berikutnya. Atribut Tampilan menentukan apa yang harus ditampilkan untuk nama bidang (dalam hal ini "Tanggal Rilis" alih-alih "ReleaseDate"). Atribut DataType menentukan jenis data (Tanggal), sehingga informasi waktu yang disimpan di bidang tidak ditampilkan.

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.

Telusuri ke Movies pengontrol dan tahan penunjuk mouse di atas tautan Edit untuk melihat URL target.

Jendela browser dengan mouse di atas tautan Edit dan Url https://localhost:5001/Movies/Edit/5 tautan ditampilkan

Tautan Edit, Detail, dan Hapus dihasilkan oleh Core MVC Anchor Tag Helper dalam Views/Movies/Index.cshtml file.

        <a asp-action="Edit" asp-route-id="@item.ID">Edit</a> |
        <a asp-action="Details" asp-route-id="@item.ID">Details</a> |
        <a asp-action="Delete" asp-route-id="@item.ID">Delete</a>
    </td>
</tr>

Pembantu Tag mengaktifkan kode sisi server untuk berpartisipasi dalam membuat dan merender elemen HTML dalam file Razor. Dalam kode di atas, AnchorTagHelper secara dinamis menghasilkan nilai atribut HTML href dari metode tindakan pengontrol dan id rute. Anda menggunakan Tampilkan Sumber dari browser favorit Anda atau gunakan alat pengembang untuk memeriksa markup yang dihasilkan. Sebagian HTML yang dihasilkan ditunjukkan di bawah ini:

 <td>
    <a href="/Movies/Edit/4"> Edit </a> |
    <a href="/Movies/Details/4"> Details </a> |
    <a href="/Movies/Delete/4"> Delete </a>
</td>

Ingat format untuk set perutean dalam Startup.cs file:

app.UseEndpoints(endpoints =>
{
    endpoints.MapControllerRoute(
        name: "default",
        pattern: "{controller=Home}/{action=Index}/{id?}");
});

ASP.NET Core diterjemahkan https://localhost:5001/Movies/Edit/4 ke dalam permintaan ke Edit metode Movies tindakan pengontrol dengan parameter Id 4. (Metode pengontrol juga dikenal sebagai metode tindakan.)

Untuk informasi selengkapnya tentang Pembantu Tag, lihat Sumber daya tambahan.

Movies Buka pengontrol dan periksa dua Edit metode tindakan. Kode berikut menunjukkan HTTP GET Edit metode , yang mengambil film dan mengisi formulir edit yang dihasilkan oleh Edit.cshtmlRazor file.

// GET: Movies/Edit/5
public async Task<IActionResult> Edit(int? id)
{
    if (id == null)
    {
        return NotFound();
    }

    var movie = await _context.Movie.FindAsync(id);
    if (movie == null)
    {
        return NotFound();
    }
    return View(movie);
}

Kode berikut menunjukkan HTTP POST Edit metode , yang memproses nilai film yang diposting:

// POST: Movies/Edit/5
// To protect from overposting attacks, please enable the specific properties you want to bind to, for 
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id, [Bind("ID,Title,ReleaseDate,Genre,Price")] Movie movie)
{
    if (id != movie.ID)
    {
        return NotFound();
    }

    if (ModelState.IsValid)
    {
        try
        {
            _context.Update(movie);
            await _context.SaveChangesAsync();
        }
        catch (DbUpdateConcurrencyException)
        {
            if (!MovieExists(movie.ID))
            {
                return NotFound();
            }
            else
            {
                throw;
            }
        }
        return RedirectToAction("Index");
    }
    return View(movie);
}

Atribut [Bind] adalah salah satu cara untuk melindungi dari posting berlebihan. Anda hanya boleh menyertakan properti dalam [Bind] atribut yang ingin Anda ubah. Untuk informasi selengkapnya, lihat Melindungi pengontrol Anda dari postingan berlebihan. ViewModels menyediakan pendekatan alternatif untuk mencegah pengiriman berlebihan.

Perhatikan metode tindakan kedua Edit didahului oleh [HttpPost] atribut .

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id, [Bind("ID,Title,ReleaseDate,Genre,Price")] Movie movie)
{
    if (id != movie.ID)
    {
        return NotFound();
    }

    if (ModelState.IsValid)
    {
        try
        {
            _context.Update(movie);
            await _context.SaveChangesAsync();
        }
        catch (DbUpdateConcurrencyException)
        {
            if (!MovieExists(movie.ID))
            {
                return NotFound();
            }
            else
            {
                throw;
            }
        }
        return RedirectToAction(nameof(Index));
    }
    return View(movie);
}

Atribut HttpPost menentukan bahwa metode ini Edit hanya dapat dipanggil untuk POST permintaan. Anda dapat menerapkan atribut ke [HttpGet] metode edit pertama, tetapi itu tidak diperlukan karena [HttpGet] merupakan default.

Atribut ValidateAntiForgeryToken ini digunakan untuk mencegah pemalsuan permintaan dan dipasangkan dengan token anti-pemalsuan yang dihasilkan dalam file tampilan edit (Views/Movies/Edit.cshtml). File tampilan edit menghasilkan token anti-pemalsuan dengan Pembantu Tag Formulir.

<form asp-action="Edit">

Pembantu Tag Formulir menghasilkan token anti-pemalsuan tersembunyi yang harus cocok dengan [ValidateAntiForgeryToken] token anti-pemalsuan yang dihasilkan dalam Edit metode pengontrol Film. Untuk informasi selengkapnya, lihat Mencegah serangan Pemalsuan Permintaan Antar Situs (XSRF/CSRF) di ASP.NET Core.

Metode mengambil HttpGet Edit parameter film ID , mencari film menggunakan metode Kerangka Kerja FindAsync Entitas, dan mengembalikan film yang dipilih ke tampilan Edit. Jika film tidak dapat ditemukan, NotFound (HTTP 404) dikembalikan.

// GET: Movies/Edit/5
public async Task<IActionResult> Edit(int? id)
{
    if (id == null)
    {
        return NotFound();
    }

    var movie = await _context.Movie.FindAsync(id);
    if (movie == null)
    {
        return NotFound();
    }
    return View(movie);
}

Ketika sistem perancah membuat tampilan Edit, sistem memeriksa Movie kelas dan membuat kode untuk merender <label> dan <input> elemen untuk setiap properti kelas. Contoh berikut menunjukkan tampilan Edit yang dihasilkan oleh sistem perancah Visual Studio:

@model MvcMovie.Models.Movie

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

<h1>Edit</h1>

<h4>Movie</h4>
<hr />
<div class="row">
    <div class="col-md-4">
        <form asp-action="Edit">
            <div asp-validation-summary="ModelOnly" class="text-danger"></div>
            <input type="hidden" asp-for="Id" />
            <div class="form-group">
                <label asp-for="Title" class="control-label"></label>
                <input asp-for="Title" class="form-control" />
                <span asp-validation-for="Title" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="ReleaseDate" class="control-label"></label>
                <input asp-for="ReleaseDate" class="form-control" />
                <span asp-validation-for="ReleaseDate" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Genre" class="control-label"></label>
                <input asp-for="Genre" class="form-control" />
                <span asp-validation-for="Genre" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Price" class="control-label"></label>
                <input asp-for="Price" class="form-control" />
                <span asp-validation-for="Price" class="text-danger"></span>
            </div>
            <div class="form-group">
                <input type="submit" value="Save" class="btn btn-primary" />
            </div>
        </form>
    </div>
</div>

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

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

Perhatikan bagaimana templat tampilan memiliki @model MvcMovie.Models.Movie pernyataan di bagian atas file. @model MvcMovie.Models.Movie menentukan bahwa tampilan mengharapkan model untuk templat tampilan berjenis Movie.

Kode perancah menggunakan beberapa metode Pembantu Tag untuk menyederhanakan markup HTML. Pembantu Tag Label menampilkan nama bidang ("Judul", "ReleaseDate", "Genre", atau "Harga"). Pembantu Tag Input merender elemen HTML<input>. Pembantu Tag Validasi menampilkan pesan validasi apa pun yang terkait dengan properti tersebut.

Jalankan aplikasi dan navigasikan ke /Movies URL. Klik tautan Edit. Di browser, lihat sumber untuk halaman tersebut. HTML yang dihasilkan untuk elemen ditunjukkan <form> di bawah ini.

<form action="/Movies/Edit/7" method="post">
    <div class="form-horizontal">
        <h4>Movie</h4>
        <hr />
        <div class="text-danger" />
        <input type="hidden" data-val="true" data-val-required="The ID field is required." id="ID" name="ID" value="7" />
        <div class="form-group">
            <label class="control-label col-md-2" for="Genre" />
            <div class="col-md-10">
                <input class="form-control" type="text" id="Genre" name="Genre" value="Western" />
                <span class="text-danger field-validation-valid" data-valmsg-for="Genre" data-valmsg-replace="true"></span>
            </div>
        </div>
        <div class="form-group">
            <label class="control-label col-md-2" for="Price" />
            <div class="col-md-10">
                <input class="form-control" type="text" data-val="true" data-val-number="The field Price must be a number." data-val-required="The Price field is required." id="Price" name="Price" value="3.99" />
                <span class="text-danger field-validation-valid" data-valmsg-for="Price" data-valmsg-replace="true"></span>
            </div>
        </div>
        <!-- Markup removed for brevity -->
        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Save" class="btn btn-default" />
            </div>
        </div>
    </div>
    <input name="__RequestVerificationToken" type="hidden" value="CfDJ8Inyxgp63fRFqUePGvuI5jGZsloJu1L7X9le1gy7NCIlSduCRx9jDQClrV9pOTTmqUyXnJBXhmrjcUVDJyDUMm7-MF_9rK8aAZdRdlOri7FmKVkRe_2v5LIHGKFcTjPrWPYnc9AdSbomkiOSaTEg7RU" />
</form>

Elemen <input> berada dalam HTML <form> elemen yang atributnya action diatur untuk memposting ke /Movies/Edit/id URL. Data formulir akan diposting ke server saat tombol Save diklik. Baris terakhir sebelum elemen penutup </form> menunjukkan token XSRF tersembunyi yang dihasilkan oleh Pembantu Tag Formulir.

Memproses Permintaan POST

Daftar berikut menunjukkan [HttpPost] versi Edit metode tindakan.

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id, [Bind("ID,Title,ReleaseDate,Genre,Price")] Movie movie)
{
    if (id != movie.ID)
    {
        return NotFound();
    }

    if (ModelState.IsValid)
    {
        try
        {
            _context.Update(movie);
            await _context.SaveChangesAsync();
        }
        catch (DbUpdateConcurrencyException)
        {
            if (!MovieExists(movie.ID))
            {
                return NotFound();
            }
            else
            {
                throw;
            }
        }
        return RedirectToAction(nameof(Index));
    }
    return View(movie);
}

Atribut [ValidateAntiForgeryToken] memvalidasi token XSRF tersembunyi yang dihasilkan oleh generator token anti-pemalsuan di Form Tag Helper

Sistem pengikatan model mengambil nilai formulir yang diposting dan membuat Movie objek yang diteruskan sebagai movie parameter . Properti ModelState.IsValid memverifikasi bahwa data yang dikirimkan dalam formulir dapat digunakan untuk memodifikasi (mengedit atau memperbarui) Movie objek. Jika data valid, data akan disimpan. Data film yang diperbarui (diedit) disimpan ke database dengan memanggil SaveChangesAsync metode konteks database. Setelah menyimpan data, kode mengalihkan pengguna ke Index metode MoviesController tindakan kelas, yang menampilkan koleksi film, termasuk perubahan yang baru saja dibuat.

Sebelum formulir diposting ke server, validasi sisi klien memeriksa aturan validasi apa pun pada bidang. Jika ada kesalahan validasi, pesan kesalahan ditampilkan dan formulir tidak diposting. Jika JavaScript dinonaktifkan, Anda tidak akan memiliki validasi sisi klien tetapi server akan mendeteksi nilai yang diposting yang tidak valid, dan nilai formulir akan diputar ulang dengan pesan kesalahan. Kemudian dalam tutorial kami memeriksa Validasi Model secara lebih rinci. Pembantu Tag Validasi dalam Views/Movies/Edit.cshtml templat tampilan mengurus menampilkan pesan kesalahan yang sesuai.

Edit tampilan: Pengecualian untuk nilai Harga abc yang salah menyatakan bahwa Bidang Harga harus berupa angka. Pengecualian untuk nilai Tanggal Rilis yang salah dari status xyz Masukkan tanggal yang valid.

HttpGet Semua metode dalam pengontrol film mengikuti pola yang sama. Mereka mendapatkan objek film (atau daftar objek, dalam kasus Index), dan meneruskan objek (model) ke tampilan. Metode Create meneruskan objek film kosong ke Create tampilan. Semua metode yang membuat, mengedit, menghapus, atau memodifikasi data melakukannya dalam [HttpPost] kelebihan beban metode. Memodifikasi data dalam HTTP GET metode adalah risiko keamanan. Memodifikasi data dalam HTTP GET metode juga melanggar praktik terbaik HTTP dan pola arsitektur REST , yang menentukan bahwa permintaan GET tidak boleh mengubah status aplikasi Anda. Dengan kata lain, melakukan operasi GET harus menjadi operasi aman yang tidak memiliki efek samping dan tidak memodifikasi data Anda yang bertahan.

Sumber Daya Tambahan: