Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
oleh Tom FitzMacken
Tutorial ini menunjukkan kepada Anda cara memperbarui (mengubah) entri database yang ada saat Anda menggunakan ASP.NET Web Pages (Razor). Ini mengasumsikan Anda telah menyelesaikan seri melalui Memasukkan Data dengan Menggunakan Formulir Menggunakan halaman web ASP.NET.
Yang akan Anda pelajari:
- Cara memilih catatan individual di pembantu
WebGrid
.- Cara membaca satu rekaman dari database.
- Cara memuat formulir dengan nilai dari rekaman database.
- Cara memperbarui rekaman yang sudah ada dalam database.
- Cara menyimpan informasi di halaman tanpa menampilkannya.
- Cara menggunakan bidang tersembunyi untuk menyimpan informasi.
Fitur/teknologi yang dibahas:
- Pembantunya
WebGrid
.- Perintah SQL
Update
.- Metode
Database.Execute
.- Bidang tersembunyi (
<input type="hidden">
).
Apa yang akan Anda Bangun
Dalam tutorial sebelumnya, Anda mempelajari cara menambahkan rekaman ke database. Di sini, Anda akan mempelajari cara menampilkan rekaman untuk pengeditan. Di halaman Film , Anda akan memperbarui pembantu WebGrid
sehingga menampilkan tautan Edit di samping setiap film:
Saat Anda mengklik tautan Edit , tautan akan membawa Anda ke halaman lain, di mana informasi film sudah dalam formulir:
Anda dapat mengubah salah satu nilai. Saat Anda mengirimkan perubahan, kode di halaman memperbarui database dan membawa Anda kembali ke daftar film.
Bagian dari proses ini bekerja hampir persis seperti halaman AddMovie.cshtml yang Anda buat di tutorial sebelumnya, sehingga banyak tutorial ini akan akrab.
Ada beberapa cara untuk mengimplementasikan cara mengedit masing-masing film. Pendekatan yang ditunjukkan dipilih karena mudah diterapkan dan mudah dipahami.
Menambahkan Tautan Edit ke Daftar Film
Untuk memulai, Anda akan memperbarui halaman Film sehingga setiap daftar film juga berisi tautan Edit .
Buka file Movies.cshtml .
Di isi halaman, ubah WebGrid
markup dengan menambahkan kolom. Berikut markup yang dimodifikasi:
@grid.GetHtml(
tableStyle: "grid",
headerStyle: "head",
alternatingRowStyle: "alt",
columns: grid.Columns(
grid.Column(format: @<a href="~/EditMovie?id=@item.ID">Edit</a>),
grid.Column("Title"),
grid.Column("Genre"),
grid.Column("Year")
)
)
Kolom baru adalah kolom ini:
grid.Column(format: @<a href="~/EditMovie?id=@item.ID)">Edit</a>)
Titik kolom ini adalah untuk menampilkan tautan (<a>
elemen) yang teksnya bertuliskan "Edit". Apa yang kita cari adalah membuat tautan yang terlihat seperti berikut ini saat halaman berjalan, dengan id
nilai yang berbeda untuk setiap film:
http://localhost:43097/EditMovie?id=7
Tautan ini akan memanggil halaman bernama EditMovie, dan akan meneruskan string ?id=7
kueri ke halaman tersebut.
Sintaks untuk kolom baru mungkin terlihat sedikit kompleks, tetapi itu hanya karena menyatukan beberapa elemen. Setiap elemen individu sangat mudah. Jika Anda hanya berkonsentrasi pada <a>
elemen , Anda akan melihat markup ini:
<a href="~/EditMovie?id=@item.ID)">Edit</a>
Beberapa latar belakang tentang cara kerja kisi: kisi menampilkan baris, satu untuk setiap rekaman database, dan menampilkan kolom untuk setiap bidang dalam rekaman database. Saat setiap baris kisi sedang dibangun, objek berisi rekaman database (item) untuk baris tersebut item
. Pengaturan ini memberi Anda cara dalam kode untuk mendapatkan data untuk baris tersebut. Itulah yang Anda lihat di sini: ekspresi item.ID
mendapatkan nilai ID dari item database saat ini. Anda bisa mendapatkan salah satu nilai database (judul, genre, atau tahun) dengan cara yang sama dengan menggunakan item.Title
, , item.Genre
atau item.Year
.
Ekspresi "~/EditMovie?id=@item.ID
menggabungkan bagian yang dikodekan secara permanen dari URL target (~/EditMovie?id=
) dengan ID turunan dinamis ini. (Anda melihat ~
operator dalam tutorial sebelumnya; ini adalah operator ASP.NET yang mewakili akar situs web saat ini.)
Hasilnya adalah bahwa bagian markup di kolom ini hanya menghasilkan sesuatu seperti markup berikut pada durasi:
href="/EditMovie?id=2"
Secara alami, nilai id
aktual akan berbeda untuk setiap baris.
Membuat Tampilan Kustom untuk Kolom Kisi
Sekarang kembali ke kolom kisi. Tiga kolom yang awalnya Anda miliki di kisi hanya menampilkan nilai data (judul, genre, dan tahun). Anda menentukan tampilan ini dengan meneruskan nama kolom database — misalnya, grid.Column("Title")
.
Kolom tautan Edit baru ini berbeda. Alih-alih menentukan nama kolom, Anda meneruskan format
parameter. Parameter ini memungkinkan Anda menentukan markup yang akan dirender pembantu WebGrid
bersama dengan item
nilai untuk menampilkan data kolom sebagai tebal atau hijau atau dalam format apa pun yang Anda inginkan. Misalnya, jika Anda ingin judul tampak tebal, Anda dapat membuat kolom seperti contoh ini:
grid.Column(format:@<strong>@item.Title</strong>)
(Berbagai @
karakter yang format
Anda lihat di properti menandai transisi antara markup dan nilai kode.)
Setelah Anda mengetahui tentang format
properti , lebih mudah untuk memahami bagaimana kolom tautan Edit baru disatukan:
grid.Column(format: @<a href="~/EditMovie?id=@item.ID">Edit</a>),
Kolom hanya terdiri dari markup yang merender tautan, ditambah beberapa informasi (ID) yang diekstrak dari rekaman database untuk baris tersebut.
Tip
Parameter Bernama dan Parameter Posisi untuk Metode
Sering kali ketika Anda telah memanggil metode dan meneruskan parameter ke metode tersebut, Anda hanya mencantumkan nilai parameter yang dipisahkan oleh koma. Berikut adalah beberapa contohnya:
db.Execute(insertCommand, title, genre, year)
Validation.RequireField("title", "You must enter a title")
Kami tidak menyebutkan masalah ketika Anda pertama kali melihat kode ini, tetapi dalam setiap kasus, Anda meneruskan parameter ke metode dalam urutan tertentu — yaitu, urutan di mana parameter didefinisikan dalam metode tersebut. Untuk db.Execute
dan Validation.RequireFields
, jika Anda mencampur urutan nilai yang Anda lewati, Anda akan mendapatkan pesan kesalahan saat halaman berjalan, atau setidaknya beberapa hasil yang aneh. Jelas, Anda harus tahu urutan untuk meneruskan parameter. (Di WebMatrix, IntelliSense dapat membantu Anda mempelajari cara mengetahui nama, jenis, dan urutan parameter.)
Sebagai alternatif untuk meneruskan nilai secara berurutan, Anda dapat menggunakan parameter bernama. (Meneruskan parameter secara berurutan dikenal sebagai menggunakan parameter posisi.) Untuk parameter bernama, Anda secara eksplisit menyertakan nama parameter saat meneruskan nilainya. Anda telah menggunakan parameter bernama sudah beberapa kali dalam tutorial ini. Contohnya:
var grid = new WebGrid(source: selectedData, defaultSort: "Genre", rowsPerPage:3)
dan
@grid.GetHtml(
tableStyle: "grid",
headerStyle: "head",
alternatingRowStyle: "alt",
columns: grid.Columns(
grid.Column("Title"),
grid.Column("Genre"),
grid.Column("Year")
)
)
Parameter bernama berguna untuk beberapa situasi, terutama ketika metode mengambil banyak parameter. Salah satunya adalah ketika Anda hanya ingin meneruskan satu atau dua parameter, tetapi nilai yang ingin Anda lewati tidak berada di antara posisi pertama dalam daftar parameter. Situasi lain adalah ketika Anda ingin membuat kode Anda lebih mudah dibaca dengan meneruskan parameter dalam urutan yang paling masuk akal untuk Anda.
Jelas, untuk menggunakan parameter bernama, Anda harus mengetahui nama parameter. WebMatrix IntelliSense dapat menunjukkan nama,tetapi saat ini tidak dapat mengisinya untuk Anda.
Membuat Halaman Edit
Sekarang Anda dapat membuat halaman EditMovie . Saat pengguna mengklik tautan Edit , mereka akan berakhir di halaman ini.
Buat halaman bernama EditMovie.cshtml dan ganti apa yang ada di file dengan markup berikut:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Edit a Movie</title>
<style>
.validation-summary-errors{
border:2px dashed red;
color:red;
font-weight:bold;
margin:12px;
}
</style>
</head>
<body>
<h1>Edit a Movie</h1>
@Html.ValidationSummary()
<form method="post">
<fieldset>
<legend>Movie Information</legend>
<p><label for="title">Title:</label>
<input type="text" name="title" value="@title" /></p>
<p><label for="genre">Genre:</label>
<input type="text" name="genre" value="@genre" /></p>
<p><label for="year">Year:</label>
<input type="text" name="year" value="@year" /></p>
<input type="hidden" name="movieid" value="@movieId" />
<p><input type="submit" name="buttonSubmit" value="Submit Changes" /></p>
</fieldset>
</form>
</body>
</html>
Markup dan kode ini mirip dengan apa yang Anda miliki di halaman AddMovie . Ada perbedaan kecil dalam teks untuk tombol kirim. Seperti halnya halaman AddMovie , ada Html.ValidationSummary
panggilan yang akan menampilkan kesalahan validasi jika ada. Kali ini kami meninggalkan panggilan ke Validation.Message
, karena kesalahan akan ditampilkan dalam ringkasan validasi. Seperti yang disebutkan dalam tutorial sebelumnya, Anda dapat menggunakan ringkasan validasi dan pesan kesalahan individual dalam berbagai kombinasi.
Perhatikan lagi bahwa method
atribut <form>
elemen diatur ke post
. Seperti halnya halaman AddMovie.cshtml , halaman ini membuat perubahan pada database. Oleh karena itu, formulir ini harus melakukan POST
operasi. (Untuk informasi selengkapnya tentang perbedaan antara GET
operasi dan POST
, lihat sidebar GET, POST, dan HTTP Verb Safety dalam tutorial tentang formulir HTML.)
Seperti yang Anda lihat dalam tutorial sebelumnya, value
atribut kotak teks sedang diatur dengan kode Razor untuk memuatnya sebelumnya. Namun kali ini, Anda menggunakan variabel seperti title
dan genre
untuk tugas tersebut alih-alih Request.Form["title"]
:
<input type="text" name="title" value="@title" />
Seperti sebelumnya, markup ini akan memuat nilai kotak teks sebelumnya dengan nilai film. Anda akan melihat sejenak mengapa berguna untuk menggunakan variabel kali ini alih-alih menggunakan Request
objek .
Ada juga <input type="hidden">
elemen di halaman ini. Elemen ini menyimpan ID film tanpa membuatnya terlihat pada halaman. ID awalnya diteruskan ke halaman dengan menggunakan nilai string kueri (?id=7
atau serupa di URL). Dengan memasukkan nilai ID ke dalam bidang tersembunyi, Anda dapat memastikan bahwa nilai tersebut tersedia saat formulir dikirimkan, bahkan jika Anda tidak lagi memiliki akses ke URL asli tempat halaman dipanggil.
Tidak seperti halaman AddMovie , kode untuk halaman EditMovie memiliki dua fungsi yang berbeda. Fungsi pertama adalah bahwa ketika halaman ditampilkan untuk pertama kalinya (dan baru kemudian), kode mendapatkan ID film dari string kueri. Kode kemudian menggunakan ID untuk membaca film yang sesuai dari database dan menampilkan (pramuat) dalam kotak teks.
Fungsi kedua adalah ketika pengguna mengklik tombol Kirim Perubahan , kode harus membaca nilai kotak teks dan memvalidasinya. Kode juga harus memperbarui item database dengan nilai baru. Teknik ini mirip dengan menambahkan rekaman, seperti yang Anda lihat di AddMovie.
Menambahkan Kode untuk Membaca Satu Film
Untuk melakukan fungsi pertama, tambahkan kode ini ke bagian atas halaman:
@{
var title = "";
var genre = "";
var year = "";
var movieId = "";
if(!IsPost){
if(!Request.QueryString["ID"].IsEmpty()){
movieId = Request.QueryString["ID"];
var db = Database.Open("WebPagesMovies");
var dbCommand = "SELECT * FROM Movies WHERE ID = @0";
var row = db.QuerySingle(dbCommand, movieId);
title = row.Title;
genre = row.Genre;
year = row.Year;
}
else{
Validation.AddFormError("No movie was selected.");
}
}
}
Sebagian besar kode ini berada di dalam blok yang dimulai if(!IsPost)
. Operator !
berarti "tidak," sehingga ekspresi berarti jika permintaan ini bukan pengiriman pos, yang merupakan cara tidak langsung untuk mengatakan apakah permintaan ini adalah pertama kalinya halaman ini dijalankan. Seperti disebutkan sebelumnya, kode ini harus berjalan hanya saat pertama kali halaman berjalan. Jika Anda tidak mengapit kode di if(!IsPost)
, kode tersebut akan berjalan setiap kali halaman dipanggil, baik pertama kali atau sebagai respons terhadap klik tombol.
Perhatikan bahwa kode menyertakan else
blok kali ini. Seperti yang kami katakan ketika kami memperkenalkan if
blok, kadang-kadang Anda ingin menjalankan kode alternatif jika kondisi yang Anda uji tidak benar. Itulah kasusnya di sini. Jika kondisi lolos (yaitu, jika ID yang diteruskan ke halaman tidak masalah), Anda membaca baris dari database. Namun, jika kondisi tidak lolos, else
blok berjalan dan kode menetapkan pesan kesalahan.
Memvalidasi Nilai yang Diteruskan ke Halaman
Kode menggunakan Request.QueryString["id"]
untuk mendapatkan ID yang diteruskan ke halaman. Kode memastikan bahwa nilai benar-benar diteruskan untuk ID. Jika tidak ada nilai yang diteruskan, kode akan menetapkan kesalahan validasi.
Kode ini menunjukkan cara yang berbeda untuk memvalidasi informasi. Dalam tutorial sebelumnya, Anda bekerja dengan pembantu Validation
. Anda mendaftarkan bidang untuk divalidasi, dan ASP.NET secara otomatis melakukan validasi dan menampilkan kesalahan dengan menggunakan Html.ValidationMessage
dan Html.ValidationSummary
. Namun, dalam hal ini, Anda tidak benar-benar memvalidasi input pengguna. Sebagai gantinya, Anda memvalidasi nilai yang diteruskan ke halaman dari tempat lain. Pembantu Validation
tidak melakukan itu untuk Anda.
Oleh karena itu, Anda memeriksa nilainya sendiri, dengan mengujinya dengan if(!Request.QueryString["ID"].IsEmpty()
). Jika ada masalah, Anda dapat menampilkan kesalahan dengan menggunakan Html.ValidationSummary
, seperti yang Anda lakukan dengan pembantu Validation
. Untuk melakukannya, Anda memanggil Validation.AddFormError
dan meneruskannya pesan untuk ditampilkan.
Validation.AddFormError
adalah metode bawaan yang memungkinkan Anda menentukan pesan kustom yang mengikat dengan sistem validasi yang sudah Anda kenal. (Nanti dalam tutorial ini kita akan berbicara tentang cara membuat proses validasi ini sedikit lebih kuat.)
Setelah memastikan bahwa ada ID untuk film, kode membaca database, hanya mencari satu item database. (Anda mungkin telah memperhatikan pola umum untuk operasi database: buka database, tentukan pernyataan SQL, dan jalankan pernyataan.) Kali ini, pernyataan SQL Select
mencakup WHERE ID = @0
. Karena ID unik, hanya satu rekaman yang dapat dikembalikan.
Kueri dilakukan dengan menggunakan db.QuerySingle
(bukan db.Query
, seperti yang Anda gunakan untuk daftar film), dan kode menempatkan hasilnya ke row
dalam variabel. Nama row
ini bersifat arbitrer; Anda dapat memberi nama variabel apa pun yang Anda suka. Variabel yang diinisialisasi di bagian atas kemudian diisi dengan detail film sehingga nilai-nilai ini dapat ditampilkan dalam kotak teks.
Menguji Halaman Edit (Sejauh Ini)
Jika Anda ingin menguji halaman, jalankan halaman Film sekarang dan klik tautan Edit di samping film apa pun. Anda akan melihat halaman EditMovie dengan detail yang diisi untuk film yang Anda pilih:
Perhatikan bahwa URL halaman menyertakan sesuatu seperti ?id=10
(atau beberapa nomor lainnya). Sejauh ini Anda telah menguji bahwa tautan Edit di halaman Film berfungsi, bahwa halaman Anda membaca ID dari string kueri, dan bahwa kueri database untuk mendapatkan satu rekaman film berfungsi.
Anda bisa mengubah informasi film, tetapi tidak ada yang terjadi ketika Anda mengklik Kirim Perubahan.
Menambahkan Kode untuk Memperbarui Film dengan Perubahan Pengguna
Dalam file EditMovie.cshtml , untuk mengimplementasikan fungsi kedua (menyimpan perubahan), tambahkan kode berikut tepat di dalam kurung kurawal @
penutup blok. (Jika Anda tidak yakin dengan tepat di mana memasukkan kode, Anda dapat melihat daftar kode lengkap untuk halaman Edit Film yang muncul di akhir tutorial ini.)
if(IsPost){
Validation.RequireField("title", "You must enter a title");
Validation.RequireField("genre", "Genre is required");
Validation.RequireField("year", "You haven't entered a year");
Validation.RequireField("movieid", "No movie ID was submitted!");
title = Request.Form["title"];
genre = Request.Form["genre"];
year = Request.Form["year"];
movieId = Request.Form["movieId"];
if(Validation.IsValid()){
var db = Database.Open("WebPagesMovies");
var updateCommand = "UPDATE Movies SET Title=@0, Genre=@1, Year=@2 WHERE Id=@3";
db.Execute(updateCommand, title, genre, year, movieId);
Response.Redirect("~/Movies");
}
}
Sekali lagi, markup dan kode ini mirip dengan kode di AddMovie. Kode berada dalam if(IsPost)
blok, karena kode ini hanya berjalan ketika pengguna mengklik tombol Kirim Perubahan — yaitu, ketika (dan hanya ketika) formulir telah diposting. Dalam hal ini, Anda tidak menggunakan pengujian seperti if(IsPost && Validation.IsValid())
— yaitu, Anda tidak menggabungkan kedua pengujian dengan menggunakan AND. Di halaman ini, Pertama-tama Anda menentukan apakah ada pengiriman formulir (if(IsPost)
), lalu mendaftarkan bidang untuk validasi. Kemudian Anda dapat menguji hasil validasi (if(Validation.IsValid()
). Alurnya sedikit berbeda dari di halaman AddMovie.cshtml , tetapi efeknya sama.
Anda mendapatkan nilai kotak teks dengan menggunakan Request.Form["title"]
dan kode serupa untuk elemen lainnya <input>
. Perhatikan bahwa kali ini, kode mendapatkan ID film dari bidang tersembunyi (<input type="hidden">
). Saat halaman dijalankan pertama kali, kode mengeluarkan ID dari string kueri. Anda mendapatkan nilai dari bidang tersembunyi untuk memastikan bahwa Anda mendapatkan ID film yang awalnya ditampilkan, jika string kueri entah bagaimana diubah sejak saat itu.
Perbedaan yang sangat penting antara kode AddMovie dan kode ini adalah bahwa dalam kode ini Anda menggunakan pernyataan SQL Update
alih-alih Insert Into
pernyataan . Contoh berikut menunjukkan sintaks pernyataan SQL Update
:
UPDATE table SET col1="value", col2="value", col3="value" ... WHERE ID = value
Anda dapat menentukan kolom apa pun dalam urutan apa pun, dan Anda tidak perlu memperbarui setiap kolom selama Update
operasi. (Anda tidak dapat memperbarui ID itu sendiri, karena itu akan berlaku menyimpan rekaman sebagai rekaman baru, dan itu tidak diizinkan untuk Update
operasi.)
Catatan
Penting Klausa Where
dengan ID sangat penting, karena itulah cara database mengetahui rekaman database mana yang ingin Anda perbarui. Jika Anda meninggalkan Where
klausa, database akan memperbarui setiap rekaman dalam database. Dalam kebanyakan kasus, itu akan menjadi bencana.
Dalam kode, nilai yang akan diperbarui diteruskan ke pernyataan SQL dengan menggunakan tempat penampung. Untuk mengulangi apa yang telah kami katakan sebelumnya: karena alasan keamanan, hanya gunakan tempat penampung untuk meneruskan nilai ke pernyataan SQL.
Setelah kode menggunakan db.Execute
untuk menjalankan Update
pernyataan, kode akan dialihkan kembali ke halaman daftar, tempat Anda dapat melihat perubahan.
Tip
Pernyataan SQL yang Berbeda, Metode yang Berbeda
Anda mungkin telah memperhatikan bahwa Anda menggunakan metode yang sedikit berbeda untuk menjalankan pernyataan SQL yang berbeda. Untuk menjalankan Select
kueri yang berpotensi mengembalikan beberapa rekaman, Anda menggunakan metode .Query
Untuk menjalankan Select
kueri yang Anda tahu hanya akan mengembalikan satu item database, Anda menggunakan metode .QuerySingle
Untuk menjalankan perintah yang membuat perubahan tetapi tidak mengembalikan item database, Anda menggunakan metode .Execute
Anda harus memiliki metode yang berbeda karena masing-masing mengembalikan hasil yang berbeda, seperti yang Anda lihat sudah dalam perbedaan antara Query
dan QuerySingle
. (Metode ini Execute
benar-benar mengembalikan nilai juga — yaitu, jumlah baris database yang terpengaruh oleh perintah — tetapi Anda telah mengabaikannya sejauh ini.)
Tentu saja, metode ini Query
mungkin hanya mengembalikan satu baris database. Namun, ASP.NET selalu memperlakukan hasil Query
metode sebagai koleksi. Bahkan jika metode hanya mengembalikan satu baris, Anda harus mengekstrak baris tunggal tersebut dari koleksi. Oleh karena itu, dalam situasi di mana Anda tahu Anda hanya akan mendapatkan kembali satu baris, sedikit lebih nyaman untuk digunakan QuerySingle
.
Ada beberapa metode lain yang melakukan jenis operasi database tertentu. Anda dapat menemukan daftar metode database di Referensi Cepat API Halaman Web ASP.NET.
Membuat Validasi untuk ID Lebih Kuat
Pertama kali halaman berjalan, Anda mendapatkan ID film dari string kueri sehingga Anda bisa mendapatkan film tersebut dari database. Anda memastikan bahwa sebenarnya ada nilai yang harus dicari, yang Anda lakukan dengan menggunakan kode ini:
if(!IsPost){
if(!Request.QueryString["ID"].IsEmpty()){
// Etc.
}
}
Anda menggunakan kode ini untuk memastikan bahwa jika pengguna masuk ke halaman EditMovies tanpa terlebih dahulu memilih film di halaman Film , halaman akan menampilkan pesan kesalahan yang mudah digunakan. (Jika tidak, pengguna akan melihat kesalahan yang mungkin hanya akan membingungkannya.)
Namun, validasi ini tidak terlalu kuat. Halaman mungkin juga dipanggil dengan kesalahan ini:
- ID bukan angka. Misalnya, halaman dapat dipanggil dengan URL seperti
http://localhost:nnnnn/EditMovie?id=abc
. - ID adalah angka, tetapi mereferensikan film yang tidak ada (misalnya,
http://localhost:nnnnn/EditMovie?id=100934
).
Jika Anda ingin melihat kesalahan yang dihasilkan dari URL ini, jalankan halaman Film . Pilih film yang akan diedit, lalu ubah URL halaman EditMovie menjadi URL yang berisi ID alfabet atau ID film yang tidak ada.
Jadi apa yang harus Anda lakukan? Perbaikan pertama adalah memastikan bahwa tidak hanya ID yang diteruskan ke halaman, tetapi id adalah bilangan bulat. Ubah kode untuk !IsPost
pengujian agar terlihat seperti contoh ini:
if(!IsPost){
if(!Request.QueryString["ID"].IsEmpty() && Request.QueryString["ID"].IsInt()) {
// Etc.
Anda telah menambahkan kondisi kedua ke IsEmpty
pengujian, ditautkan dengan &&
(logika AND):
Request.QueryString["ID"].IsInt()
Anda mungkin ingat dari tutorial Pengantar ASP.NET Pemrograman Halaman Web yang metodenya seperti AsBool
AsInt
mengonversi string karakter ke beberapa jenis data lainnya. Metode IsInt
(dan lainnya, seperti IsBool
dan IsDateTime
) serupa. Namun, mereka hanya menguji apakah Anda dapat mengonversi string, tanpa benar-benar melakukan konversi. Jadi di sini Anda pada dasarnya mengatakan Jika nilai string kueri dapat dikonversi menjadi bilangan bulat ....
Potensi masalah lainnya adalah mencari film yang tidak ada. Kode untuk mendapatkan film terlihat seperti kode ini:
var row = db.QuerySingle(dbCommand, movieId);
Jika Anda meneruskan movieId
nilai ke QuerySingle
metode yang tidak sesuai dengan film aktual, tidak ada yang dikembalikan dan pernyataan yang mengikuti (misalnya, title=row.Title
) mengakibatkan kesalahan.
Sekali lagi ada perbaikan mudah.
db.QuerySingle
Jika metode tidak mengembalikan hasil, row
variabel akan null. Jadi Anda dapat memeriksa apakah row
variabel null sebelum Anda mencoba untuk mendapatkan nilai darinya. Kode berikut menambahkan if
blok di sekitar pernyataan yang mengeluarkan nilai dari row
objek:
if(row != null) {
title = row.Title;
genre = row.Genre;
year = row.Year;
}
else{
Validation.AddFormError("No movie was found for that ID.");
}
Dengan dua tes validasi tambahan ini, halaman menjadi lebih anti peluru. Kode lengkap untuk !IsPost
cabang sekarang terlihat seperti contoh ini:
if(!IsPost){
if(!Request.QueryString["ID"].IsEmpty() && Request.QueryString["ID"].IsInt()) {
movieId = Request.QueryString["ID"];
var db = Database.Open("WebPagesMovies");
var dbCommand = "SELECT * FROM Movies WHERE ID = @0";
var row = db.QuerySingle(dbCommand, movieId);
if(row != null) {
title = row.Title;
genre = row.Genre;
year = row.Year;
}
else {
Validation.AddFormError("No movie was found for that ID.");
}
}
else {
Validation.AddFormError("No movie was selected.");
}
}
Kami akan mencatat sekali lagi bahwa tugas ini adalah penggunaan yang else
baik untuk blok. Jika pengujian tidak lulus, else
blok menetapkan pesan kesalahan.
Menambahkan Tautan untuk Kembali ke Halaman Film
Detail terakhir dan bermanfaat adalah menambahkan tautan kembali ke halaman Film . Dalam alur peristiwa biasa, pengguna akan mulai di halaman Film dan mengklik tautan Edit . Itu membawa mereka ke halaman EditMovie , di mana mereka dapat mengedit film dan mengklik tombol . Setelah kode memproses perubahan, kode akan dialihkan kembali ke halaman Film .
Akan tetapi:
- Pengguna mungkin memutuskan untuk tidak mengubah apa pun.
- Pengguna mungkin telah masuk ke halaman ini tanpa terlebih dahulu mengklik tautan Edit di halaman Film .
Bagaimanapun, Anda ingin memudahkan mereka untuk kembali ke daftar utama. Ini adalah perbaikan yang mudah — tambahkan markup berikut tepat setelah tag penutup </form>
di markup:
<p><a href="~/Movies">Return to movie listing</a></p>
Markup ini menggunakan sintaks yang sama untuk <a>
elemen yang telah Anda lihat di tempat lain. URL termasuk ~
berarti "akar situs web."
Menguji Proses Pembaruan Film
Sekarang Anda dapat menguji. Jalankan halaman Film , dan klik Edit di samping film. Saat halaman EditMovie muncul, buat perubahan pada film dan klik Kirim Perubahan. Saat daftar film muncul, pastikan perubahan Anda ditampilkan.
Untuk memastikan validasi berfungsi, klik Edit untuk film lain. Saat Anda masuk ke halaman EditMovie , kosongkan bidang Genre (atau bidang Tahun , atau keduanya) dan coba kirimkan perubahan Anda. Anda akan melihat kesalahan, seperti yang Anda harapkan:
Klik tautan Kembali ke daftar film untuk mengabaikan perubahan Anda dan kembali ke halaman Film .
Berikutnya
Dalam tutorial berikutnya, Anda akan melihat cara menghapus rekaman film.
Daftar Lengkap untuk Halaman Film (Diperbarui dengan Edit Tautan)
@{
var db = Database.Open("WebPagesMovies") ;
var selectCommand = "SELECT * FROM Movies";
var searchTerm = "";
if(!Request.QueryString["searchGenre"].IsEmpty() ) {
selectCommand = "SELECT * FROM Movies WHERE Genre = @0";
searchTerm = Request.QueryString["searchGenre"];
}
if(!Request.QueryString["searchTitle"].IsEmpty() ) {
selectCommand = "SELECT * FROM Movies WHERE Title LIKE @0";
searchTerm = "%" + Request.QueryString["searchTitle"] + "%";
}
var selectedData = db.Query(selectCommand, searchTerm);
var grid = new WebGrid(source: selectedData, defaultSort: "Genre", rowsPerPage:3);
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Movies</title>
<style type="text/css">
.grid { margin: 4px; border-collapse: collapse; width: 600px; }
.grid th, .grid td { border: 1px solid #C0C0C0; padding: 5px; }
.head { background-color: #E8E8E8; font-weight: bold; color: #FFF; }
.alt { background-color: #E8E8E8; color: #000; }
</style>
</head>
<body>
<h1>Movies</h1>
<form method="get">
<div>
<label for="searchGenre">Genre to look for:</label>
<input type="text" name="searchGenre" value="@Request.QueryString["searchGenre"]" />
<input type="Submit" value="Search Genre" /><br/>
(Leave blank to list all movies.)<br/>
</div>
<div>
<label for="SearchTitle">Movie title contains the following:</label>
<input type="text" name="searchTitle" value="@Request.QueryString["searchTitle"]" />
<input type="Submit" value="Search Title" /><br/>
</div>
</form>
<div>
@grid.GetHtml(
tableStyle: "grid",
headerStyle: "head",
alternatingRowStyle: "alt",
columns: grid.Columns(
grid.Column(format: @<a href="~/EditMovie?id=@item.ID">Edit</a>),
grid.Column("Title"),
grid.Column("Genre"),
grid.Column("Year")
)
)
</div>
<p>
<a href="~/AddMovie">Add a movie</a>
</p>
</body>
</html>
Daftar Halaman Lengkap untuk Edit Halaman Film
@{
var title = "";
var genre = "";
var year = "";
var movieId = "";
if(!IsPost){
if(!Request.QueryString["ID"].IsEmpty() && Request.QueryString["ID"].IsInt()) {
movieId = Request.QueryString["ID"];
var db = Database.Open("WebPagesMovies");
var dbCommand = "SELECT * FROM Movies WHERE ID = @0";
var row = db.QuerySingle(dbCommand, movieId);
if(row != null) {
title = row.Title;
genre = row.Genre;
year = row.Year;
}
else{
Validation.AddFormError("No movie was selected.");
}
}
else{
Validation.AddFormError("No movie was selected.");
}
}
if(IsPost){
Validation.RequireField("title", "You must enter a title");
Validation.RequireField("genre", "Genre is required");
Validation.RequireField("year", "You haven't entered a year");
Validation.RequireField("movieid", "No movie ID was submitted!");
title = Request.Form["title"];
genre = Request.Form["genre"];
year = Request.Form["year"];
movieId = Request.Form["movieId"];
if(Validation.IsValid()){
var db = Database.Open("WebPagesMovies");
var updateCommand = "UPDATE Movies SET Title=@0, Genre=@1, Year=@2 WHERE Id=@3";
db.Execute(updateCommand, title, genre, year, movieId);
Response.Redirect("~/Movies");
}
}
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Edit a Movie</title>
<style>
.validation-summary-errors{
border:2px dashed red;
color:red;
font-weight:bold;
margin:12px;
}
</style>
</head>
<body>
<h1>Edit a Movie</h1>
@Html.ValidationSummary()
<form method="post">
<fieldset>
<legend>Movie Information</legend>
<p><label for="title">Title:</label>
<input type="text" name="title" value="@title" /></p>
<p><label for="genre">Genre:</label>
<input type="text" name="genre" value="@genre" /></p>
<p><label for="year">Year:</label>
<input type="text" name="year" value="@year" /></p>
<input type="hidden" name="movieid" value="@movieId" />
<p><input type="submit" name="buttonSubmit" value="Submit Changes" /></p>
</fieldset>
</form>
<p><a href="~/Movies">Return to movie listing</a></p>
</body>
</html>