Bagikan melalui


Memeriksa Metode Tindakan dan Tampilan untuk Pengontrol Film

oleh Rick Anderson

Catatan

Versi terbaru dari tutorial ini tersedia di sini yang menggunakan ASP.NET MVC 5 dan Visual Studio 2013. Lebih aman, jauh lebih mudah untuk diikuti dan menunjukkan lebih banyak fitur.

Di bagian ini, Anda akan memeriksa metode tindakan dan tampilan yang dihasilkan untuk pengontrol film. Kemudian Anda akan menambahkan halaman pencarian kustom.

Jalankan aplikasi dan telusuri pengontrol Movies dengan menambahkan /Movies ke URL di bilah alamat browser Anda. Tahan penunjuk mouse di atas tautan Edit untuk melihat URL yang ditautkannya.

EditLink_sm

Tautan Edit dihasilkan oleh Html.ActionLink metode dalam tampilan Views\Movies\Index.cshtml :

@Html.ActionLink("Edit", "Edit", new { id=item.ID })

Html.ActionLink

Objek Html adalah pembantu yang diekspos menggunakan properti pada kelas dasar System.Web.Mvc.WebViewPage . Metode ActionLink pembantu memudahkan untuk secara dinamis menghasilkan hyperlink HTML yang ditautkan ke metode tindakan pada pengontrol. Argumen pertama untuk ActionLink metode ini adalah teks tautan untuk dirender (misalnya, <a>Edit Me</a>). Argumen kedua adalah nama metode tindakan yang akan dipanggil. Argumen akhir adalah objek anonim yang menghasilkan data rute (dalam hal ini, ID 4).

Tautan yang dihasilkan yang ditampilkan pada gambar sebelumnya adalah http://localhost:xxxxx/Movies/Edit/4. Rute default (ditetapkan dalam App_Start\RouteConfig.cs) mengambil pola {controller}/{action}/{id}URL . Oleh karena itu, ASP.NET diterjemahkan http://localhost:xxxxx/Movies/Edit/4 ke dalam permintaan ke Edit metode Movies tindakan pengontrol dengan parameter ID sama dengan 4. Periksa kode berikut dari file App_Start\RouteConfig.cs .

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    routes.MapRoute(
        name: "Default",
        url: "{controller}/{action}/{id}",
        defaults: new { controller = "Home", action = "Index", 
            id = UrlParameter.Optional }
    );
}

Anda juga dapat meneruskan parameter metode tindakan menggunakan string kueri. Misalnya, URL http://localhost:xxxxx/Movies/Edit?ID=4 juga meneruskan parameter ID 4 ke Edit metode Movies tindakan pengontrol.

EditQueryString

Movies Buka pengontrol. Dua Edit metode tindakan ditunjukkan di bawah ini.

//
// GET: /Movies/Edit/5

public ActionResult Edit(int id = 0)
{
    Movie movie = db.Movies.Find(id);
    if (movie == null)
    {
        return HttpNotFound();
    }
    return View(movie);
}

//
// POST: /Movies/Edit/5

[HttpPost]
public ActionResult Edit(Movie movie)
{
    if (ModelState.IsValid)
    {
        db.Entry(movie).State = EntityState.Modified;
        db.SaveChanges();
        return RedirectToAction("Index");
    }
    return View(movie);
}

Perhatikan metode tindakan kedua Edit didahului oleh HttpPost atribut . Atribut ini menentukan bahwa kelebihan beban Edit metode hanya dapat dipanggil untuk permintaan POST. Anda dapat menerapkan atribut ke HttpGet metode edit pertama, tetapi itu tidak perlu karena itu adalah default. (Kami akan merujuk ke metode tindakan yang secara implisit ditetapkan HttpGet atribut sebagai HttpGet metode.)

Metode mengambil HttpGet Edit parameter ID film, mencari film menggunakan metode Kerangka Kerja Find Entitas, dan mengembalikan film yang dipilih ke tampilan Edit. Parameter ID menentukan nilai default nol jika metode dipanggil Edit tanpa parameter. Jika film tidak dapat ditemukan, HttpNotFound dikembalikan. 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:

@model MvcMovie.Models.Movie

@{
    ViewBag.Title = "Edit";
}

<h2>Edit</h2>

@using (Html.BeginForm()) {
    @Html.ValidationSummary(true)

    <fieldset>
        <legend>Movie</legend>

        @Html.HiddenFor(model => model.ID)

        <div class="editor-label">
            @Html.LabelFor(model => model.Title)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Title)
            @Html.ValidationMessageFor(model => model.Title)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.ReleaseDate)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.ReleaseDate)
            @Html.ValidationMessageFor(model => model.ReleaseDate)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.Genre)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Genre)
            @Html.ValidationMessageFor(model => model.Genre)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.Price)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Price)
            @Html.ValidationMessageFor(model => model.Price)
        </div>

        <p>
            <input type="submit" value="Save" />
        </p>
    </fieldset>
}

<div>
    @Html.ActionLink("Back to List", "Index")
</div>

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}

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

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

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

<form action="/Movies/Edit/4" method="post">    <fieldset>
        <legend>Movie</legend>

        <input data-val="true" data-val-number="The field ID must be a number." data-val-required="The ID field is required." id="ID" name="ID" type="hidden" value="4" />

        <div class="editor-label">
            <label for="Title">Title</label>
        </div>
        <div class="editor-field">
            <input class="text-box single-line" id="Title" name="Title" type="text" value="Rio Bravo" />
            <span class="field-validation-valid" data-valmsg-for="Title" data-valmsg-replace="true"></span>
        </div>

        <div class="editor-label">
            <label for="ReleaseDate">ReleaseDate</label>
        </div>
        <div class="editor-field">
            <input class="text-box single-line" data-val="true" data-val-date="The field ReleaseDate must be a date." data-val-required="The ReleaseDate field is required." id="ReleaseDate" name="ReleaseDate" type="text" value="4/15/1959 12:00:00 AM" />
            <span class="field-validation-valid" data-valmsg-for="ReleaseDate" data-valmsg-replace="true"></span>
        </div>

        <div class="editor-label">
            <label for="Genre">Genre</label>
        </div>
        <div class="editor-field">
            <input class="text-box single-line" id="Genre" name="Genre" type="text" value="Western" />
            <span class="field-validation-valid" data-valmsg-for="Genre" data-valmsg-replace="true"></span>
        </div>

        <div class="editor-label">
            <label for="Price">Price</label>
        </div>
        <div class="editor-field">
            <input class="text-box single-line" 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" type="text" value="2.99" />
            <span class="field-validation-valid" data-valmsg-for="Price" data-valmsg-replace="true"></span>
        </div>

        <p>
            <input type="submit" value="Save" />
        </p>
    </fieldset>
</form>

Elemen <input> berada dalam elemen HTML <form> yang atributnya action diatur untuk memposting ke URL /Movies/Edit . Data formulir akan diposting ke server saat tombol Edit diklik.

Memproses Permintaan POST

Daftar berikut menunjukkan HttpPost versi Edit metode tindakan.

[HttpPost] 
public ActionResult Edit(Movie movie)  
{ 
    if (ModelState.IsValid)  
    { 
        db.Entry(movie).State = EntityState.Modified; 
        db.SaveChanges(); 
        return RedirectToAction("Index"); 
    } 
    return View(movie); 
}

Pengikat model MVC ASP.NET mengambil nilai formulir yang diposting dan membuat Movie objek yang diteruskan sebagai movie parameter . Metode memverifikasi ModelState.IsValid bahwa data yang dikirimkan dalam formulir dapat digunakan untuk memodifikasi (mengedit atau memperbarui) Movie objek. Jika data valid, data film disimpan ke Movies koleksi db(MovieDBContext instans). Data film baru disimpan ke database dengan memanggil SaveChanges metode MovieDBContext. Setelah menyimpan data, kode mengalihkan pengguna ke Index metode MoviesController tindakan kelas, yang menampilkan koleksi film, termasuk perubahan yang baru saja dilakukan.

Jika nilai yang diposting tidak valid, nilai tersebut akan diputar ulang dalam formulir. Pembantu Html.ValidationMessageFor dalam templat tampilan Edit.cshtml mengurus menampilkan pesan kesalahan yang sesuai.

abcNotValid

Catatan

untuk mendukung validasi jQuery untuk lokal non-Bahasa Inggris yang menggunakan koma (",") untuk titik desimal, Anda harus menyertakan globalize.js dan budaya/globalize.cultures.js file spesifik Anda(dari https://github.com/jquery/globalize ) dan JavaScript untuk menggunakan Globalize.parseFloat. Kode berikut menunjukkan modifikasi pada file Views\Movies\Edit.cshtml untuk bekerja dengan budaya "fr-FR":

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
    <script src="~/Scripts/globalize.js"></script>
    <script src="~/Scripts/globalize.culture.fr-FR.js"></script>
    <script>
        $.validator.methods.number = function (value, element) {
            return this.optional(element) ||
                !isNaN(Globalize.parseFloat(value));
        }
        $(document).ready(function () {
            Globalize.culture('fr-FR');
        });
    </script>
    <script>
        jQuery.extend(jQuery.validator.methods, {    
            range: function (value, element, param) {        
                //Use the Globalization plugin to parse the value        
                var val = $.global.parseFloat(value);
                return this.optional(element) || (
                    val >= param[0] && val <= param[1]);
            }
        });

    </script>
}

Bidang desimal mungkin memerlukan koma, bukan titik desimal. Sebagai perbaikan sementara, Anda dapat menambahkan elemen globalisasi ke file web.config root proyek. Kode berikut menunjukkan elemen globalisasi dengan budaya yang diatur ke Amerika Serikat bahasa Inggris.

<system.web>
    <globalization culture ="en-US" />
    <!--elements removed for clarity-->
  </system.web>

HttpGet Semua metode mengikuti pola yang sama. Mereka mendapatkan objek film (atau daftar objek, dalam kasus Index), dan meneruskan model ke tampilan. Metode Create meneruskan objek film kosong ke tampilan Buat. Semua metode yang membuat, mengedit, menghapus, atau memodifikasi data melakukannya dalam HttpPost kelebihan beban metode. Memodifikasi data dalam metode HTTP GET adalah risiko keamanan. Memodifikasi data dalam metode GET juga melanggar praktik terbaik HTTP dan pola REST arsitektur, 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.

Menambahkan Metode Pencarian dan Tampilan Pencarian

Di bagian ini Anda akan menambahkan SearchIndex metode tindakan yang memungkinkan Anda mencari film berdasarkan genre atau nama. Ini akan tersedia menggunakan URL /Movies/SearchIndex . Permintaan akan menampilkan formulir HTML yang berisi elemen input yang dapat dimasukkan pengguna untuk mencari film. Saat pengguna mengirimkan formulir, metode tindakan akan mendapatkan nilai pencarian yang diposting oleh pengguna dan menggunakan nilai untuk mencari database.

Menampilkan Formulir SearchIndex

Mulailah dengan menambahkan SearchIndex metode tindakan ke kelas yang MoviesController ada. Metode ini akan mengembalikan tampilan yang berisi formulir HTML. Berikut kodenya:

public ActionResult SearchIndex(string searchString) 
{           
    var movies = from m in db.Movies 
                 select m; 
 
    if (!String.IsNullOrEmpty(searchString)) 
    { 
        movies = movies.Where(s => s.Title.Contains(searchString)); 
    } 
 
    return View(movies); 
}

Baris SearchIndex pertama metode membuat kueri LINQ berikut untuk memilih film:

var movies = from m in db.Movies 
             select m;

Kueri didefinisikan pada saat ini, tetapi belum dijalankan terhadap penyimpanan data.

searchString Jika parameter berisi string, kueri film dimodifikasi untuk memfilter nilai string pencarian, menggunakan kode berikut:

if (!String.IsNullOrEmpty(searchString)) 
{ 
    movies = movies.Where(s => s.Title.Contains(searchString)); 
}

Kode s => s.Title di atas adalah Ekspresi Lambda. Lambda digunakan dalam kueri LINQ berbasis metode sebagai argumen ke metode operator kueri standar seperti metode Where yang digunakan dalam kode di atas. Kueri LINQ tidak dijalankan ketika didefinisikan atau ketika dimodifikasi dengan memanggil metode seperti Where atau OrderBy. Sebaliknya, eksekusi kueri ditangguhkan, yang berarti bahwa evaluasi ekspresi tertunda sampai nilai yang direalisasikan benar-benar diulang atau ToList metode dipanggil. SearchIndex Dalam sampel, kueri dijalankan dalam tampilan SearchIndex. Untuk informasi selengkapnya tentang eksekusi kueri yang ditangguhkan, lihat Eksekusi Kueri.

Sekarang Anda dapat menerapkan SearchIndex tampilan yang akan menampilkan formulir kepada pengguna. Klik kanan di SearchIndex dalam metode lalu klik Tambahkan Tampilan. Dalam kotak dialog Tambahkan Tampilan , tentukan bahwa Anda akan meneruskan Movie objek ke templat tampilan sebagai kelas modelnya. Di daftar Templat perancah, pilih Daftar, lalu klik Tambahkan.

TambahkanSearchView

Saat Anda mengklik tombol Tambahkan , templat tampilan Views\Movies\SearchIndex.cshtml dibuat. Karena Anda memilih Daftar dalam daftar templat Scaffold, Visual Studio secara otomatis membuat (scaffolded) beberapa markup default dalam tampilan. Perancah membuat formulir HTML. Ini memeriksa Movie kelas dan membuat kode untuk merender <label> elemen untuk setiap properti kelas. Daftar di bawah ini memperlihatkan tampilan Buat yang dihasilkan:

@model IEnumerable<MvcMovie.Models.Movie> 
 
@{ 
    ViewBag.Title = "SearchIndex"; 
} 
 
<h2>SearchIndex</h2> 
 
<p> 
    @Html.ActionLink("Create New", "Create") 
</p> 
<table> 
    <tr> 
        <th> 
            Title 
        </th> 
        <th> 
            ReleaseDate 
        </th> 
        <th> 
            Genre 
        </th> 
        <th> 
            Price 
        </th> 
        <th></th> 
    </tr> 
 
@foreach (var item in Model) { 
    <tr> 
        <td> 
            @Html.DisplayFor(modelItem => item.Title) 
        </td> 
        <td> 
            @Html.DisplayFor(modelItem => item.ReleaseDate) 
        </td> 
        <td> 
            @Html.DisplayFor(modelItem => item.Genre) 
        </td> 
        <td> 
            @Html.DisplayFor(modelItem => item.Price) 
        </td> 
        <td> 
            @Html.ActionLink("Edit", "Edit", new { id=item.ID }) | 
            @Html.ActionLink("Details", "Details", new { id=item.ID }) | 
            @Html.ActionLink("Delete", "Delete", new { id=item.ID }) 
        </td> 
    </tr> 
} 
 
</table>

Jalankan aplikasi dan navigasikan ke /Movies/SearchIndex. Tambahkan string kueri seperti ?searchString=ghost ke URL. Film yang difilter ditampilkan.

SearchQryStr

Jika Anda mengubah tanda tangan SearchIndex metode agar memiliki parameter bernama id, id parameter akan cocok dengan {id} tempat penampung untuk rute default yang diatur dalam file Global.asax .

{controller}/{action}/{id}

Metode asli SearchIndex terlihat seperti ini::

public ActionResult SearchIndex(string searchString) 
{           
    var movies = from m in db.Movies 
                 select m; 
 
    if (!String.IsNullOrEmpty(searchString)) 
    { 
        movies = movies.Where(s => s.Title.Contains(searchString)); 
    } 
 
    return View(movies); 
}

Metode yang dimodifikasi SearchIndex akan terlihat sebagai berikut:

public ActionResult SearchIndex(string id) 
{ 
    string searchString = id; 
    var movies = from m in db.Movies 
                 select m; 
 
    if (!String.IsNullOrEmpty(searchString)) 
    { 
        movies = movies.Where(s => s.Title.Contains(searchString)); 
    } 
 
    return View(movies); 
}

Sekarang Anda dapat meneruskan judul pencarian sebagai data rute (segmen URL) alih-alih sebagai nilai string kueri.

SearchRouteData

Namun, Anda tidak dapat mengharapkan pengguna untuk memodifikasi URL setiap kali mereka ingin mencari film. Jadi sekarang Anda akan menambahkan UI untuk membantu mereka memfilter film. Jika Anda mengubah tanda tangan SearchIndex metode untuk menguji cara melewati parameter ID yang terikat rute, ubah kembali sehingga metode Anda SearchIndex mengambil parameter string bernama searchString:

public ActionResult SearchIndex(string searchString) 
{           
     var movies = from m in db.Movies 
                  select m; 
 
    if (!String.IsNullOrEmpty(searchString)) 
    { 
        movies = movies.Where(s => s.Title.Contains(searchString)); 
    } 
 
    return View(movies); 
}

Buka file Views\Movies\SearchIndex.cshtml, dan tepat setelah @Html.ActionLink("Create New", "Create"), tambahkan yang berikut ini:

@using (Html.BeginForm()){    
         <p> Title: @Html.TextBox("SearchString")<br />  
         <input type="submit" value="Filter" /></p> 
        }

Contoh berikut menunjukkan sebagian file Views\Movies\SearchIndex.cshtml dengan markup pemfilteran yang ditambahkan.

@model IEnumerable<MvcMovie.Models.Movie> 
 
@{ 
    ViewBag.Title = "SearchIndex"; 
} 
 
<h2>SearchIndex</h2> 
 
<p> 
    @Html.ActionLink("Create New", "Create") 
     
     @using (Html.BeginForm()){    
         <p> Title: @Html.TextBox("SearchString") <br />   
         <input type="submit" value="Filter" /></p> 
        } 
</p>

Pembantu Html.BeginForm membuat tag pembuka <form> . Pembantu Html.BeginForm menyebabkan formulir diposting ke dirinya sendiri ketika pengguna mengirimkan formulir dengan mengklik tombol Filter .

Jalankan aplikasi dan coba cari film.

Cuplikan layar menjalankan aplikasi dan mencoba mencari film.

Tidak ada HttpPost kelebihan metode SearchIndex . Anda tidak memerlukannya, karena metode tidak mengubah status aplikasi, hanya memfilter data.

Anda dapat menambahkan metode berikut HttpPost SearchIndex . Dalam hal ini, pemanggil tindakan akan cocok dengan HttpPost SearchIndex metode , dan HttpPost SearchIndex metode akan berjalan seperti yang ditunjukkan pada gambar di bawah ini.

[HttpPost] 
public string SearchIndex(FormCollection fc, string searchString) 
{ 
    return "<h3> From [HttpPost]SearchIndex: " + searchString + "</h3>"; 
}

SearchPostGhost

Namun, bahkan jika Anda menambahkan versi SearchIndex metode iniHttpPost, ada batasan dalam bagaimana semua ini telah diimplementasikan. Bayangkan Anda ingin menandai pencarian tertentu atau Anda ingin mengirim tautan ke teman yang dapat mereka klik untuk melihat daftar film yang difilter yang sama. Perhatikan bahwa URL untuk permintaan HTTP POST sama dengan URL untuk permintaan GET (localhost:xxxxx/Movies/SearchIndex) -- tidak ada informasi pencarian di URL itu sendiri. Saat ini, informasi string pencarian dikirim ke server sebagai nilai bidang formulir. Ini berarti Anda tidak dapat mengambil informasi pencarian tersebut untuk menandai atau mengirim ke teman di URL.

Solusinya adalah menggunakan kelebihan beban BeginForm yang menentukan bahwa permintaan POST harus menambahkan informasi pencarian ke URL dan harus dirutekan ke versi HttpGet metode SearchIndex . Ganti metode tanpa BeginForm parameter yang ada dengan yang berikut ini:

@using (Html.BeginForm("SearchIndex","Movies",FormMethod.Get))

BeginFormPost_SM

Sekarang saat Anda mengirimkan pencarian, URL berisi string kueri pencarian. Pencarian juga akan masuk ke HttpGet SearchIndex metode tindakan, bahkan jika Anda memiliki HttpPost SearchIndex metode .

SearchIndexWithGetURL

Menambahkan Pencarian menurut Genre

Jika Anda menambahkan HttpPost versi SearchIndex metode , hapus sekarang.

Selanjutnya, Anda akan menambahkan fitur untuk memungkinkan pengguna mencari film berdasarkan genre. Ganti metode SearchIndex dengan kode berikut:

public ActionResult SearchIndex(string movieGenre, string searchString) 
{ 
    var GenreLst = new List<string>(); 
 
    var GenreQry = from d in db.Movies 
                   orderby d.Genre 
                   select d.Genre; 
    GenreLst.AddRange(GenreQry.Distinct()); 
    ViewBag.movieGenre = new SelectList(GenreLst); 
 
    var movies = from m in db.Movies 
                 select m; 
 
    if (!String.IsNullOrEmpty(searchString)) 
    { 
        movies = movies.Where(s => s.Title.Contains(searchString)); 
    } 
 
    if (string.IsNullOrEmpty(movieGenre)) 
        return View(movies); 
    else 
    { 
        return View(movies.Where(x => x.Genre == movieGenre)); 
    } 
 
}

Versi SearchIndex metode ini mengambil parameter tambahan, yaitu movieGenre. Beberapa baris kode pertama membuat List objek untuk menahan genre film dari database.

Kode berikut adalah kueri LINQ yang mengambil semua genre dari database.

var GenreQry = from d in db.Movies 
                   orderby d.Genre 
                   select d.Genre;

Kode menggunakan AddRange metode koleksi generik List untuk menambahkan semua genre yang berbeda ke daftar. (Tanpa pengubah Distinct , genre duplikat akan ditambahkan — misalnya, komedi akan ditambahkan dua kali dalam sampel kami). Kode kemudian menyimpan daftar genre dalam ViewBag objek.

Kode berikut menunjukkan cara memeriksa movieGenre parameter. Jika tidak kosong, kode selanjutnya membatasi kueri film untuk membatasi film yang dipilih ke genre yang ditentukan.

if (string.IsNullOrEmpty(movieGenre)) 
        return View(movies); 
else 
{ 
    return View(movies.Where(x => x.Genre == movieGenre)); 
}

Menambahkan Markup ke Tampilan SearchIndex untuk Mendukung Pencarian berdasarkan Genre

Html.DropDownList Tambahkan pembantu ke file Views\Movies\SearchIndex.cshtml, tepat sebelum pembantuTextBox. Markup yang telah selesai ditunjukkan di bawah ini:

<p> 
    @Html.ActionLink("Create New", "Create") 
    @using (Html.BeginForm("SearchIndex","Movies",FormMethod.Get)){     
         <p>Genre: @Html.DropDownList("movieGenre", "All")   
           Title: @Html.TextBox("SearchString")   
         <input type="submit" value="Filter" /></p> 
        } 
</p>

Jalankan aplikasi dan telusuri ke /Movies/SearchIndex. Coba cari berdasarkan genre, berdasarkan nama film, dan menurut kedua kriteria.

Cuplikan layar menjalankan aplikasi dan mencoba mencari berdasarkan nama film genre dan dengan kedua kriteria.

Di bagian ini Anda memeriksa metode tindakan CRUD dan tampilan yang dihasilkan oleh kerangka kerja. Anda membuat metode tindakan pencarian dan tampilan yang memungkinkan pengguna mencari berdasarkan judul dan genre film. Di bagian berikutnya, Anda akan melihat cara menambahkan properti ke Movie model dan cara menambahkan penginisialisasi yang akan secara otomatis membuat database pengujian.