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 Microsoft
Ini adalah langkah 4 dari tutorial aplikasi "NerdDinner" gratis yang memandu cara membangun aplikasi web kecil, tetapi lengkap menggunakan ASP.NET MVC 1.
Langkah 4 menunjukkan cara menambahkan Pengontrol ke aplikasi yang memanfaatkan model kami untuk memberi pengguna pengalaman navigasi daftar/detail data untuk makan malam di situs NerdDinner kami.
Jika Anda menggunakan ASP.NET MVC 3, kami sarankan Anda mengikuti tutorial Memulai MVC 3 atau MVC Music Store .
NerdDinner Langkah 4: Pengontrol dan Tampilan
Dengan kerangka kerja web tradisional (ASP klasik, PHP, ASP.NET Formulir Web, dll), URL masuk biasanya dipetakan ke file pada disk. Misalnya: permintaan URL seperti "/Products.aspx" atau "/Products.php" mungkin diproses oleh file "Products.aspx" atau "Products.php".
Kerangka kerja MVC berbasis web memetakan URL ke kode server dengan cara yang sedikit berbeda. Alih-alih memetakan URL masuk ke file, mereka malah memetakan URL ke metode pada kelas. Kelas-kelas ini disebut "Pengontrol" dan bertanggung jawab untuk memproses permintaan HTTP masuk, menangani input pengguna, mengambil dan menyimpan data, dan menentukan respons untuk dikirim kembali ke klien (menampilkan HTML, mengunduh file, mengalihkan ke URL yang berbeda, dll).
Sekarang setelah kami membangun model dasar untuk aplikasi NerdDinner kami, langkah kami selanjutnya adalah menambahkan Pengontrol ke aplikasi yang memanfaatkannya untuk memberi pengguna pengalaman navigasi daftar/detail data untuk Makan Malam di situs kami.
Menambahkan Pengontrol DinnersController
Kita akan mulai dengan mengklik kanan folder "Pengontrol" dalam proyek web kita, lalu pilih perintah menu Add-Controller> (Anda juga dapat menjalankan perintah ini dengan mengetik Ctrl-M, Ctrl-C):
Ini akan memunculkan dialog "Tambahkan Pengontrol":
Kami akan memberi nama pengontrol baru "DinnersController" dan klik tombol "Tambahkan". Visual Studio kemudian akan menambahkan file DinnersController.cs di bawah direktori \Controllers kami:
Ini juga akan membuka kelas DinnersController baru dalam editor kode.
Menambahkan Metode Tindakan Index() dan Details() ke Kelas DinnersController
Kami ingin memungkinkan pengunjung menggunakan aplikasi kami untuk menelusuri daftar makan malam mendatang, dan memungkinkan mereka untuk mengklik Makan Malam apa pun dalam daftar untuk melihat detail spesifik tentang hal itu. Kami akan melakukan ini dengan menerbitkan URL berikut dari aplikasi kami:
| URL | Tujuan |
|---|---|
| /Makan malam/ | Menampilkan daftar HTML makan malam mendatang |
| /Dinners/Details/[id] | Tampilkan detail tentang makan malam tertentu yang ditunjukkan oleh parameter "id" yang disematkan dalam URL - yang akan cocok dengan DinnerID makan malam dalam database. Misalnya: /Dinners/Details/2 akan menampilkan halaman HTML dengan detail tentang Dinner yang nilai DinnerID-nya adalah 2. |
Kami akan menerbitkan implementasi awal URL ini dengan menambahkan dua "metode tindakan" publik ke kelas DinnersController seperti di bawah ini:
public class DinnersController : Controller {
//
// HTTP-GET: /Dinners/
public void Index() {
Response.Write("<h1>Coming Soon: Dinners</h1>");
}
//
// HTTP-GET: /Dinners/Details/2
public void Details(int id) {
Response.Write("<h1>Details DinnerID: " + id + "</h1>");
}
}
Kami kemudian akan menjalankan aplikasi NerdDinner dan menggunakan browser kami untuk memanggilnya. Mengetik di URL "/Dinners/" akan menyebabkan metode Index() kami berjalan, dan itu akan mengirim kembali respons berikut:
Mengetik di URL "/Dinners/Details/2" akan menyebabkan metode Details() kami berjalan, dan mengirim kembali respons berikut:
Anda mungkin bertanya-tanya - bagaimana ASP.NET MVC tahu untuk membuat kelas DinnersController kami dan memanggil metode tersebut? Untuk memahami bahwa mari kita lihat sekilas cara kerja perutean.
Memahami Perutean MVC ASP.NET
ASP.NET MVC menyertakan mesin perutean URL canggih yang memberikan banyak fleksibilitas dalam mengontrol bagaimana URL dipetakan ke kelas pengontrol. Ini memungkinkan kita untuk sepenuhnya menyesuaikan bagaimana ASP.NET MVC memilih kelas pengontrol mana yang akan dibuat, metode mana yang akan dipanggil di atasnya, serta mengonfigurasi berbagai cara agar variabel dapat secara otomatis diurai dari URL/Querystring dan diteruskan ke metode sebagai argumen parameter. Ini memberikan fleksibilitas untuk sepenuhnya mengoptimalkan situs untuk SEO (pengoptimalan mesin pencari) serta menerbitkan struktur URL apa pun yang kami inginkan dari aplikasi.
Secara default, proyek ASP.NET MVC baru dilengkapi dengan serangkaian aturan perutean URL yang telah dikonfigurasi sebelumnya yang sudah terdaftar. Ini memungkinkan kita untuk dengan mudah memulai aplikasi tanpa harus mengonfigurasi apa pun secara eksplisit. Pendaftaran aturan perutean default dapat ditemukan dalam kelas "Aplikasi" dari proyek kami - yang dapat kami buka dengan mengklik dua kali file "Global.asax" di akar proyek kami:
Aturan perutean ASP.NET MVC default terdaftar dalam metode "RegisterRoutes" dari kelas ini:
public void RegisterRoutes(RouteCollection routes) {
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL w/ params
new { controller="Home", action="Index",id="" } // Param defaults
);
}
"Rute. Panggilan metode MapRoute()" di atas mendaftarkan aturan perutean default yang memetakan URL masuk ke kelas pengontrol menggunakan format URL: "/{controller}/{action}/{id}" – di mana "pengontrol" adalah nama kelas pengontrol untuk membuat instans, "tindakan" adalah nama metode publik untuk memanggilnya, dan "id" adalah parameter opsional yang disematkan dalam URL yang dapat diteruskan sebagai argumen ke metode . Parameter ketiga yang diteruskan ke panggilan metode "MapRoute()" adalah sekumpulan nilai default yang akan digunakan untuk nilai pengontrol/tindakan/id jika tidak ada di URL (Pengontrol = "Beranda", Tindakan="Indeks", Id="").
Di bawah ini adalah tabel yang menunjukkan bagaimana berbagai URL dipetakan menggunakan aturan rute "/{controllers}/{action}/{id}" default:
| URL | Kelas Pengontrol | Metode Tindakan | Parameter Lulus |
|---|---|---|---|
| /Dinners/Details/2 | DinnersController | Detail(id) | id=2 |
| /Dinners/Edit/5 | DinnersController | Edit(id) | id=5 |
| /Dinners/Create | DinnersController | Create() | T/A |
| /Makan malam | DinnersController | Index() | T/A |
| /Rumah | HomeController | Index() | T/A |
| / | HomeController | Index() | T/A |
Tiga baris terakhir menunjukkan nilai default (Pengontrol = Beranda, Tindakan = Indeks, Id = "") yang digunakan. Karena metode "Indeks" terdaftar sebagai nama tindakan default jika tidak ditentukan, URL "/Dinners" dan "/Home" menyebabkan metode tindakan Index() dipanggil pada kelas Pengontrol mereka. Karena pengontrol "Rumah" terdaftar sebagai pengontrol default jika tidak ditentukan, URL "/" menyebabkan HomeController dibuat, dan metode tindakan Index() di atasnya akan dipanggil.
Jika Anda tidak menyukai aturan perutean URL default ini, kabar baiknya adalah bahwa aturan tersebut mudah diubah - cukup edit dalam metode RegisterRoutes di atas. Namun, untuk aplikasi NerdDinner kami, kami tidak akan mengubah salah satu aturan perutean URL default - sebagai gantinya kita hanya akan menggunakannya apa adanya.
Menggunakan DinnerRepository dari DinnersController kami
Sekarang mari kita ganti implementasi metode tindakan DinnersController's Index() dan Details() saat ini dengan implementasi yang menggunakan model kita.
Kami akan menggunakan kelas DinnerRepository yang kami bangun sebelumnya untuk mengimplementasikan perilaku. Kita akan mulai dengan menambahkan pernyataan "menggunakan" yang mereferensikan namespace "NerdDinner.Models", dan kemudian mendeklarasikan instans DinnerRepository kami sebagai bidang di kelas DinnerController kami.
Kemudian dalam bab ini kami akan memperkenalkan konsep "Injeksi Dependensi" dan menunjukkan cara lain bagi Pengontrol kami untuk mendapatkan referensi ke DinnerRepository yang memungkinkan pengujian unit yang lebih baik - tetapi untuk saat ini kita hanya akan membuat instans DinnerRepository sebaris seperti di bawah ini.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using NerdDinner.Models;
namespace NerdDinner.Controllers {
public class DinnersController : Controller {
DinnerRepository dinnerRepository = new DinnerRepository();
//
// GET: /Dinners/
public void Index() {
var dinners = dinnerRepository.FindUpcomingDinners().ToList();
}
//
// GET: /Dinners/Details/2
public void Details(int id) {
Dinner dinner = dinnerRepository.GetDinner(id);
}
}
}
Sekarang kita siap untuk menghasilkan respons HTML kembali menggunakan objek model data yang diambil.
Menggunakan Tampilan dengan Pengontrol kami
Meskipun dimungkinkan untuk menulis kode dalam metode tindakan kami untuk merakit HTML dan kemudian menggunakan metode pembantu Response.Write() untuk mengirimkannya kembali ke klien, pendekatan itu menjadi cukup sulit dengan cepat. Pendekatan yang jauh lebih baik adalah bagi kita untuk hanya melakukan aplikasi dan logika data di dalam metode tindakan DinnersController kami, dan untuk kemudian meneruskan data yang diperlukan untuk merender respons HTML ke templat "tampilan" terpisah yang bertanggung jawab untuk menghasilkan representasi HTML itu. Seperti yang akan kita lihat dalam sekejap, templat "tampilan" adalah file teks yang biasanya berisi kombinasi markup HTML dan kode penyajian yang disematkan.
Memisahkan logika pengontrol kami dari penyajian tampilan kami membawa beberapa manfaat besar. Secara khusus, ini membantu memberlakukan "pemisahan kekhawatiran" yang jelas antara kode aplikasi dan kode pemformatan/penyajian UI. Ini membuatnya jauh lebih mudah untuk logika aplikasi pengujian unit dalam isolasi dari logika penyajian UI. Ini memudahkan untuk kemudian memodifikasi templat penyajian UI tanpa harus membuat perubahan kode aplikasi. Dan itu dapat memudahkan pengembang dan desainer untuk berkolaborasi bersama dalam proyek.
Kita dapat memperbarui kelas DinnersController untuk menunjukkan bahwa kita ingin menggunakan templat tampilan untuk mengirim kembali respons UI HTML dengan mengubah tanda tangan metode dari dua metode tindakan kita dari memiliki jenis pengembalian "kekosongan" untuk sebaliknya memiliki jenis pengembalian "ActionResult". Kita kemudian dapat memanggil metode pembantu View() pada kelas dasar Pengontrol untuk mengembalikan objek "ViewResult" seperti di bawah ini:
public class DinnersController : Controller {
DinnerRepository dinnerRepository = new DinnerRepository();
//
// GET: /Dinners/
public ActionResult Index() {
var dinners = dinnerRepository.FindUpcomingDinners().ToList();
return View("Index", dinners);
}
//
// GET: /Dinners/Details/2
public ActionResult Details(int id) {
Dinner dinner = dinnerRepository.GetDinner(id);
if (dinner == null)
return View("NotFound");
else
return View("Details", dinner);
}
}
Tanda tangan metode pembantu View() yang kami gunakan di atas terlihat seperti di bawah ini:
Parameter pertama untuk metode pembantu View() adalah nama file templat tampilan yang ingin kita gunakan untuk merender respons HTML. Parameter kedua adalah objek model yang berisi data yang dibutuhkan templat tampilan untuk merender respons HTML.
Dalam metode tindakan Index() kami, kami memanggil metode pembantu View() dan menunjukkan bahwa kami ingin merender daftar HTML makan malam menggunakan templat tampilan "Indeks". Kami meneruskan templat tampilan urutan objek Makan Malam untuk menghasilkan daftar dari:
//
// GET: /Dinners/
public ActionResult Index() {
var dinners = dinnerRepository.FindUpcomingDinners().ToList();
return View("Index", dinners);
}
Dalam metode tindakan Details() kami, kami mencoba mengambil objek Dinner menggunakan id yang disediakan dalam URL. Jika Makan Malam yang valid ditemukan, kami memanggil metode pembantu View(), menunjukkan bahwa kami ingin menggunakan templat tampilan "Detail" untuk merender objek Makan Malam yang diambil. Jika makan malam yang tidak valid diminta, kami merender pesan kesalahan bermanfaat yang menunjukkan bahwa Makan Malam tidak ada menggunakan templat tampilan "NotFound" (dan versi metode pembantu View() yang kelebihan beban yang hanya mengambil nama templat):
//
// GET: /Dinners/Details/2
public ActionResult Details(int id) {
Dinner dinner = dinnerRepository.FindDinner(id);
if (dinner == null)
return View("NotFound");
else
return View("Details", dinner);
}
Sekarang mari kita terapkan templat tampilan "NotFound", "Detail", dan "Indeks".
Menerapkan Templat Tampilan "NotFound"
Kita akan mulai dengan menerapkan templat tampilan "NotFound" - yang menampilkan pesan kesalahan ramah yang menunjukkan bahwa makan malam yang diminta tidak dapat ditemukan.
Kita akan membuat templat tampilan baru dengan memposisikan kursor teks kita dalam metode tindakan pengontrol, lalu klik kanan dan pilih perintah menu "Tambahkan Tampilan" (kita juga dapat menjalankan perintah ini dengan mengetik Ctrl-M, Ctrl-V):
Ini akan memunculkan dialog "Tambahkan Tampilan" seperti di bawah ini. Secara default dialog akan mengisi nama tampilan untuk dibuat agar sesuai dengan nama metode tindakan yang digunakan kursor saat dialog diluncurkan (dalam hal ini "Detail"). Karena kita ingin terlebih dahulu menerapkan templat "NotFound", kita akan mengambil alih nama tampilan ini dan mengaturnya menjadi "NotFound":
Ketika kita mengklik tombol "Tambahkan", Visual Studio akan membuat templat tampilan "NotFound.aspx" baru untuk kita dalam direktori "\Views\Dinners" (yang juga akan dibuat jika direktori belum ada):
Ini juga akan membuka templat tampilan "NotFound.aspx" baru kami dalam editor kode:
Lihat templat secara default memiliki dua "wilayah konten" tempat kita dapat menambahkan konten dan kode. Yang pertama memungkinkan kami untuk menyesuaikan "judul" halaman HTML yang dikirim kembali. Yang kedua memungkinkan kami untuk menyesuaikan "konten utama" dari halaman HTML yang dikirim kembali.
Untuk mengimplementasikan templat tampilan "NotFound" kami, kami akan menambahkan beberapa konten dasar:
<asp:Content ID="Title" ContentPlaceHolderID="TitleContent" runat="server">
Dinner Not Found
</asp:Content>
<asp:Content ID="Main" ContentPlaceHolderID="MainContent" runat="server">
<h2>Dinner Not Found</h2>
<p>Sorry - but the dinner you requested doesn't exist or was deleted.</p>
</asp:Content>
Kita kemudian dapat mencobanya di dalam browser. Untuk melakukan ini, mari kita minta URL "/Dinners/Details/9999 ". Ini akan mengacu pada makan malam yang saat ini tidak ada dalam database, dan akan menyebabkan metode tindakan DinnersController.Details() kami merender templat tampilan "NotFound" kami:
Satu hal yang akan Anda perhatikan dalam cuplikan layar di atas adalah bahwa templat tampilan dasar kami telah mewarisi banyak HTML yang mengelilingi konten utama di layar. Ini karena templat tampilan kami menggunakan templat "halaman master" yang memungkinkan kami menerapkan tata letak yang konsisten di semua tampilan di situs. Kita akan membahas cara kerja halaman master lebih lanjut di bagian selanjutnya dari tutorial ini.
Menerapkan Templat Tampilan "Detail"
Sekarang mari kita terapkan templat tampilan "Detail" - yang akan menghasilkan HTML untuk satu model Makan Malam.
Kita akan melakukan ini dengan memposisikan kursor teks kita dalam metode tindakan Detail, lalu klik kanan dan pilih perintah menu "Tambahkan Tampilan" (atau tekan Ctrl-M, Ctrl-V):
Ini akan memunculkan dialog "Tambahkan Tampilan". Kami akan menyimpan nama tampilan default ("Detail"). Kami juga akan memilih kotak centang "Buat Tampilan yang diketik dengan kuat" dalam dialog dan memilih (menggunakan dropdown kotak kombo) nama jenis model yang kami berikan dari Pengontrol ke Tampilan. Untuk tampilan ini kami melewati objek Makan Malam (nama yang sepenuhnya memenuhi syarat untuk jenis ini adalah: "NerdDinner.Models.Dinner"):
Tidak seperti templat sebelumnya, di mana kami memilih untuk membuat "Tampilan Kosong", kali ini kami akan memilih untuk secara otomatis "perancah" tampilan menggunakan templat "Detail". Kami dapat menunjukkan ini dengan mengubah drop-down "Lihat konten" dalam dialog di atas.
"Perancah" akan menghasilkan implementasi awal dari templat tampilan detail kami berdasarkan objek Makan Malam yang kami teruskan ke dalamnya. Ini menyediakan cara mudah bagi kami untuk dengan cepat memulai implementasi templat tampilan kami.
Ketika kami mengklik tombol "Tambahkan", Visual Studio akan membuat file templat tampilan "Details.aspx" baru untuk kami dalam direktori "\Views\Dinners" kami:
Ini juga akan membuka templat tampilan "Details.aspx" baru kami dalam editor kode. Ini akan berisi implementasi perancah awal dari tampilan detail berdasarkan model Makan Malam. Mesin perancah menggunakan refleksi .NET untuk melihat properti publik yang terekspos pada kelas yang melewatinya, dan akan menambahkan konten yang sesuai berdasarkan setiap jenis yang ditemukannya:
<asp:Content ID="Title" ContentPlaceHolderID="TitleContent" runat="server">
Details
</asp:Content>
<asp:Content ID="Main" ContentPlaceHolderID="MainContent" runat="server">
<h2>Details</h2>
<fieldset>
<legend>Fields</legend>
<p>
DinnerID:
<%=Html.Encode(Model.DinnerID) %>
</p>
<p>
Title:
<%=Html.Encode(Model.Title) %>
</p>
<p>
EventDate:
<%= Html.Encode(String.Format("{0:g}", Model.EventDate)) %>
</p>
<p>
Description:
<%=Html.Encode(Model.Description) %>
</p>
<p>
HostedBy:
<%=Html.Encode(Model.HostedBy) %>
</p>
<p>
ContactPhone:
<%=Html.Encode(Model.ContactPhone) %>
</p>
<p>
Address:
<%=Html.Encode(Model.Address) %>
</p>
<p>
Country:
<%=Html.Encode(Model.Country) %>
</p>
<p>
Latitude:
<%= Html.Encode(String.Format("{0:F}",Model.Latitude)) %>
</p>
<p>
Longitude:
<%= Html.Encode(String.Format("{0:F}",Model.Longitude)) %>
</p>
</fieldset>
<p>
<%=Html.ActionLink("Edit","Edit", new { id=Model.DinnerID }) %>|
<%=Html.ActionLink("Back to List", "Index") %>
</p>
</asp:Content>
Kita dapat meminta URL "/Dinners/Details/1" untuk melihat seperti apa implementasi perancah "detail" ini di browser. Menggunakan URL ini akan menampilkan salah satu makan malam yang kami tambahkan secara manual ke database kami ketika kami pertama kali membuatnya:
Ini membuat kita siap dan berjalan dengan cepat, dan memberi kita implementasi awal dari tampilan Details.aspx kami. Kita kemudian dapat pergi dan mengubahnya untuk menyesuaikan UI dengan kepuasan kita.
Ketika kita melihat templat Details.aspx lebih dekat, kita akan menemukan bahwa templat tersebut berisi HTML statis serta kode penyajian yang disematkan. <% %> nugget kode menjalankan kode ketika templat tampilan merender, dan <%= %> nugget kode menjalankan kode yang terkandung di dalamnya dan kemudian merender hasilnya ke aliran output templat.
Kami dapat menulis kode dalam Tampilan kami yang mengakses objek model "Makan Malam" yang diteruskan dari pengontrol kami menggunakan properti "Model" yang sangat diketik. Visual Studio memberi kami kode lengkap-intellisense saat mengakses properti "Model" ini dalam editor:
Mari kita buat beberapa tweak sehingga sumber untuk templat tampilan Detail akhir kita terlihat seperti di bawah ini:
<asp:Content ID="Title" ContentPlaceHolderID="TitleContent" runat="server">
Dinner: <%=Html.Encode(Model.Title) %>
</asp:Content>
<asp:Content ID="Main" ContentPlaceHolderID="MainContent" runat="server">
<h2><%=Html.Encode(Model.Title) %></h2>
<p>
<strong>When:</strong>
<%=Model.EventDate.ToShortDateString() %>
<strong>@</strong>
<%=Model.EventDate.ToShortTimeString() %>
</p>
<p>
<strong>Where:</strong>
<%=Html.Encode(Model.Address) %>,
<%=Html.Encode(Model.Country) %>
</p>
<p>
<strong>Description:</strong>
<%=Html.Encode(Model.Description) %>
</p>
<p>
<strong>Organizer:</strong>
<%=Html.Encode(Model.HostedBy) %>
(<%=Html.Encode(Model.ContactPhone) %>)
</p>
<%= Html.ActionLink("Edit Dinner", "Edit", new { id=Model.DinnerID })%> |
<%= Html.ActionLink("Delete Dinner","Delete", new { id=Model.DinnerID})%>
</asp:Content>
Ketika kita mengakses URL "/Dinners/Details/1" lagi sekarang akan dirender seperti di bawah ini:
Menerapkan Templat Tampilan "Indeks"
Sekarang mari kita terapkan templat tampilan "Indeks" - yang akan menghasilkan daftar Makan Malam yang akan datang. Untuk melakukan ini, kita akan memposisikan kursor teks kita dalam metode tindakan Indeks, lalu klik kanan dan pilih perintah menu "Tambahkan Tampilan" (atau tekan Ctrl-M, Ctrl-V).
Dalam dialog "Tambahkan Tampilan" kita akan menyimpan templat tampilan bernama "Indeks" dan pilih kotak centang "Buat tampilan yang ditik dengan kuat". Kali ini kami akan memilih untuk secara otomatis menghasilkan templat tampilan "Daftar", dan memilih "NerdDinner.Models.Dinner" sebagai jenis model yang diteruskan ke tampilan (yang karena kami telah menunjukkan kami membuat perancah "Daftar" akan menyebabkan dialog Tambahkan Tampilan untuk mengasumsikan kami meneruskan urutan objek Makan Malam dari Pengontrol kami ke Tampilan):
Ketika kita mengklik tombol "Tambahkan", Visual Studio akan membuat file templat tampilan "Index.aspx" baru untuk kita dalam direktori "\Views\Dinners". Ini akan "perancah" implementasi awal di dalamnya yang menyediakan daftar tabel HTML dari Makan Malam yang kami berikan ke tampilan.
Ketika kita menjalankan aplikasi dan mengakses URL "/Dinners/" itu akan merender daftar makan malam kita seperti:
Solusi tabel di atas memberi kami tata letak seperti kisi data Makan Malam kami - yang bukan apa yang kami inginkan untuk daftar Makan Malam yang dihadapi konsumen kami. Kita dapat memperbarui templat tampilan Index.aspx dan memodifikasinya untuk mencantumkan lebih sedikit <kolom data, dan menggunakan elemen ul> untuk merendernya alih-alih tabel menggunakan kode di bawah ini:
<asp:Content ID="Main" ContentPlaceHolderID="MainContent" runat="server">
<h2>Upcoming Dinners</h2>
<ul>
<% foreach (var dinner in Model) { %>
<li>
<%=Html.Encode(dinner.Title) %>
on
<%=Html.Encode(dinner.EventDate.ToShortDateString())%>
@
<%=Html.Encode(dinner.EventDate.ToShortTimeString())%>
</li>
<% } %>
</ul>
</asp:Content>
Kami menggunakan kata kunci "var" dalam pernyataan foreach di atas saat kami mengulang setiap makan malam dalam Model kami. Mereka yang tidak terbiasa dengan C# 3.0 mungkin berpikir bahwa menggunakan "var" berarti bahwa objek makan malam terikat terlambat. Sebaliknya berarti bahwa kompilator menggunakan type-inference terhadap properti "Model" yang sangat diketik (yang merupakan jenis "IEnumerable<Dinner>") dan mengkompilasi variabel "makan malam" lokal sebagai jenis Makan Malam - yang berarti kita mendapatkan intellisense penuh dan pemeriksaan waktu kompilasi untuk itu dalam blok kode:
Ketika kami menekan refresh pada URL /Dinners di browser kami, tampilan kami yang diperbarui sekarang terlihat seperti di bawah ini:
Ini terlihat lebih baik - tetapi belum sepenuhnya ada. Langkah terakhir kami adalah mengaktifkan pengguna akhir untuk mengklik Makan Malam individual dalam daftar dan melihat detail tentang mereka. Kami akan menerapkan ini dengan merender elemen hyperlink HTML yang menautkan ke metode tindakan Detail pada DinnersController kami.
Kami dapat menghasilkan hyperlink ini dalam tampilan Indeks kami dengan salah satu dari dua cara. Yang pertama adalah membuat HTML <> secara manual elemen seperti di bawah ini, di mana kami menyematkan <% %> blok dalam <> elemen HTML:
Pendekatan alternatif yang dapat kita gunakan adalah memanfaatkan metode pembantu "Html.ActionLink()" bawaan dalam ASP.NET MVC yang mendukung pembuatan HTML <> secara terprogram elemen yang terhubung ke metode tindakan lain pada Pengontrol:
<%= Html.ActionLink(dinner.Title, "Details", new { id=dinner.DinnerID }) %>
Parameter pertama untuk metode pembantu Html.ActionLink() adalah teks tautan untuk ditampilkan (dalam hal ini judul makan malam), parameter kedua adalah nama tindakan Pengontrol yang ingin kita hasilkan tautannya (dalam hal ini metode Detail), dan parameter ketiga adalah sekumpulan parameter untuk dikirim ke tindakan (diimplementasikan sebagai jenis anonim dengan nama/nilai properti). Dalam hal ini kami menentukan parameter "id" dari makan malam yang ingin kami tautkan, dan karena aturan perutean URL default di ASP.NET MVC adalah "{Controller}/{Action}/{id}" metode pembantu Html.ActionLink() akan menghasilkan output berikut:
<a href="/Dinners/Details/1">.NET Futures</a>
Untuk tampilan Index.aspx kami, kami akan menggunakan pendekatan metode pembantu Html.ActionLink() dan memiliki setiap makan malam dalam tautan daftar ke URL detail yang sesuai:
<asp:Content ID="Title" ContentPlaceHolderID="TitleContent" runat="server">
Upcoming Dinners
</asp:Content>
<asp:Content ID="Main" ContentPlaceHolderID="MainContent" runat="server">
<h2>Upcoming Dinners</h2>
<ul>
<% foreach (var dinner in Model) { %>
<li>
<%=Html.ActionLink(dinner.Title, "Details", new { id=dinner.DinnerID }) %>
on
<%=Html.Encode(dinner.EventDate.ToShortDateString())%>
@
<%=Html.Encode(dinner.EventDate.ToShortTimeString())%>
</li>
<% } %>
</ul>
</asp:Content>
Dan sekarang ketika kita mencapai URL Makan Malam daftar makan malam kami terlihat seperti di bawah ini:
Ketika kita mengklik salah satu Makan Malam dalam daftar, kita akan menavigasi untuk melihat detail tentang hal itu:
Penamaan berbasis konvensi dan struktur direktori \Views
ASP.NET aplikasi MVC secara default menggunakan struktur penamaan direktori berbasis konvensi saat menyelesaikan templat tampilan. Ini memungkinkan pengembang untuk menghindari harus sepenuhnya memenuhi syarat jalur lokasi saat mereferensikan tampilan dari dalam kelas Pengontrol. Secara default ASP.NET MVC akan mencari file templat tampilan dalam direktori *\Views[ControllerName]* di bawah aplikasi.
Misalnya, kami telah mengerjakan kelas DinnersController - yang secara eksplisit mereferensikan tiga templat tampilan: "Indeks", "Detail" dan "NotFound". ASP.NET MVC secara default akan mencari tampilan ini dalam direktori \Views\Dinners di bawah direktori akar aplikasi kami:
Perhatikan di atas bagaimana saat ini ada tiga kelas pengontrol dalam proyek (DinnersController, HomeController dan AccountController - dua terakhir ditambahkan secara default ketika kami membuat proyek), dan ada tiga sub-direktori (satu untuk setiap pengontrol) dalam direktori \Views.
Tampilan yang direferensikan dari pengontrol Beranda dan Akun akan secara otomatis menyelesaikan templat tampilannya dari direktori \Views\Home dan \Views\Account masing-masing. Sub-direktori \Views\Shared menyediakan cara untuk menyimpan templat tampilan yang digunakan kembali di beberapa pengontrol dalam aplikasi. Ketika ASP.NET MVC mencoba menyelesaikan templat tampilan, pertama-tama akan memeriksa dalam direktori spesifik \Views[Controller] , dan jika tidak dapat menemukan templat tampilan di sana, templat tersebut akan terlihat dalam direktori \Views\Shared .
Dalam hal penamaan templat tampilan individual, panduan yang disarankan adalah agar templat tampilan memiliki nama yang sama dengan metode tindakan yang menyebabkannya dirender. Misalnya, di atas metode tindakan "Indeks" kami menggunakan tampilan "Indeks" untuk merender hasil tampilan, dan metode tindakan "Detail" menggunakan tampilan "Detail" untuk merender hasilnya. Ini memudahkan untuk dengan cepat melihat templat mana yang terkait dengan setiap tindakan.
Pengembang tidak perlu secara eksplisit menentukan nama templat tampilan ketika templat tampilan memiliki nama yang sama dengan metode tindakan yang dipanggil pada pengontrol. Kita hanya dapat meneruskan objek model ke metode pembantu "View()" (tanpa menentukan nama tampilan), dan ASP.NET MVC akan secara otomatis menyimpulkan bahwa kita ingin menggunakan templat tampilan \Views[ControllerName][ActionName] pada disk untuk merendernya.
Ini memungkinkan kami untuk membersihkan kode pengontrol kami sedikit, dan menghindari duplikasi nama dua kali dalam kode kami:
public class DinnersController : Controller {
DinnerRepository dinnerRepository = new DinnerRepository();
//
// GET: /Dinners/
public ActionResult Index() {
var dinners = dinnerRepository.FindUpcomingDinners().ToList();
return View(dinners);
}
//
// GET: /Dinners/Details/2
public ActionResult Details(int id) {
Dinner dinner = dinnerRepository.GetDinner(id);
if (dinner == null)
return View("NotFound");
else
return View(dinner);
}
}
Kode di atas adalah semua yang diperlukan untuk mengimplementasikan pengalaman daftar / detail Makan Malam yang bagus untuk situs.
Langkah Selanjutnya
Kami sekarang memiliki pengalaman penjelajahan Makan Malam yang bagus yang dibangun.
Sekarang mari kita aktifkan dukungan pengeditan formulir data CRUD (Create, Read, Update, Delete).