Phương thức Tìm kiếm

Thêm Search Method và Search View

Trong phần này, bạn sẽ thêm khả năng tìm kiếm vào phương thức hành động Index cho phép bạn tìm kiếm movies theo thể loại hoặc tên.

Cập nhật biểu mẫu Index

Bắt đầu bằng cách cập nhật phương thức hành động Index thành lớp MoviesController hiện có. Đây là code:

public ActionResult Index(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); 
}

Dòng đầu tiên của phương thức Index tạo truy vấn LINQ sau đây để chọn movie:

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

Truy vấn được định nghĩa tại thời điểm này, nhưng chưa được chạy với cơ sở dữ liệu.

Nếu tham số searchString chứa chuỗi, truy vấn movie được sửa đổi để lọc giá trị của chuỗi tìm kiếm, sử dụng code sau:

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

Mã s => s.Title ở trên là biểu thức Lambda. Lambdas được sử dụng trong các truy vấn LINQ dựa trên phương thức làm đối số cho các phương thức toán tử truy vấn chuẩn như phương thức Where được sử dụng trong đoạn code trên. Truy vấn LINQ không được thực hiện khi chúng được xác định hoặc khi chúng được sửa đổi bằng cách gọi một phương thức như Where hoặc OrderBy. Thay vào đó, việc thực hiện truy vấn được hoãn lại, có nghĩa là việc đánh giá biểu thức bị trì hoãn cho đến khi giá trị đã nhận của nó thực sự được lặp lại hoặc phương thức ToList được gọi. Trong mẫu Search, truy vấn được thực thi trong view Index.cshtml. Để biết thêm thông tin về thực thi truy vấn bị trì hoãn, hãy xem Thực thi truy vấn.

Chú thích

Phương thức Contains được chạy trên cơ sở dữ liệu, chứ không phải code C# ở trên. Trên cơ sở dữ liệu, Contains chỉ dẫn đến SQL LIKE, đó là trường hợp không nhạy cảm.

Bây giờ bạn có thể cập nhật Index view mà sẽ hiển thị biểu mẫu cho người dùng.

Chạy ứng dụng và điều hướng đến / Movies / Index. Nối chuỗi truy vấn chẳng hạn như ? SearchString = ghost vào URL. Các movie đã lọc được hiển thị.

Nếu bạn thay đổi hướng dẫn của phương thức Index để có tham số tên là id, tham số id sẽ khớp với trình giữ chỗ {id} cho các đường dẫn mặc định được đặt trong tệp App_Start \ RouteConfig.cs.

{controller}/{action}/{id}

Phương thức Index ban đầu trông như thế này

public ActionResult Index(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);  }

Phương thức Index được sửa đổi sẽ trông như sau

public ActionResult Index(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);  }

Bây giờ, bạn có thể chuyển title tìm kiếm dưới dạng dữ liệu đường dẫn (phân đoạn URL) thay vì dưới dạng giá trị chuỗi truy vấn.

Tuy nhiên, bạn không thể mong đợi người dùng sửa đổi URL mỗi khi họ muốn tìm kiếm movie. Vì vậy, bây giờ bạn sẽ thêm giao diện người dùng để giúp họ lọc các movie. Nếu bạn thay đổi chỉ dẫn của phương thức Index để kiểm tra cách vượt qua tham số ID đường dẫn, hãy thay đổi lại để phương thức Index của bạn lấy tham số chuỗi có tên searchString:

public ActionResult Index(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);  }

Mở tệp Views \ Movies \ Index.cshtml và chỉ sau @Html.ActionLink(“Create New”, “Create”), thêm đánh dấu biểu mẫu được đánh dấu bên dưới:

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

Trình trợ giúp Html.BeginForm tạo thẻ mở <form>. Trình trợ giúp Html.BeginForm làm cho biểu mẫu đăng lên chính nó khi người dùng gửi biểu mẫu bằng cách nhấp vào nút Filter.

Visual Studio 2013 có một cải tiến tốt hơn khi hiển thị và chỉnh sửa View files. Khi bạn chạy các ứng dụng với một tệp view mở, Visual Studio 2013 gọi phương thức hành động điều khiển chính xác để hiển thị view.

Với Index view mở trong Visual Studio (như trong hình trên), hãy nhấn Ctr F5 hoặc F5 để chạy ứng dụng và sau đó thử tìm kiếm một movie.

Không có HttpPost overload của phương thức Index. Bạn không cần nó, bởi vì phương thức không thay đổi trạng thái của ứng dụng, nó chỉ lọc dữ liệu.

Bạn có thể thêm phương thức HttpPost Index dưới đây. Trong trường hợp đó, hành động Invoker sẽ phù hợp với phương thức HttpPost Index, và phương thức HttpPost Index sẽ chạy như thể hiện trong hình bên dưới.

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

Tuy nhiên, ngay cả khi bạn thêm phiên bản HttpPost này của phương thức Index, có một giới hạn về cách thực hiện tất cả điều này. Hãy tưởng tượng rằng bạn muốn đánh dấu một tìm kiếm cụ thể hoặc bạn muốn gửi một liên kết đến bạn bè mà họ có thể nhấp vào để xem danh sách phim được lọc tương tự. Lưu ý rằng URL cho yêu cầu HTTP POST giống với URL cho yêu cầu GET (localhost: xxxxx/Movies /Index) – không có thông tin tìm kiếm nào trong chính URL đó. Ngay bây giờ, thông tin chuỗi tìm kiếm được gửi đến máy chủ dưới dạng giá trị trường biểu mẫu. Điều này có nghĩa là bạn không thể nắm bắt thông tin tìm kiếm đó để đánh dấu hoặc gửi cho bạn bè trong một URL.

Giải pháp là sử dụng overload của BeginForm chỉ rõ rằng yêu cầu POST nên thêm thông tin tìm kiếm vào URL và nó sẽ được định tuyến tới phiên bản HttpGet của phương thức Index. Thay thế phương thức BeginForm không có tham số hiện tại bằng đánh dấu sau:

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

Bây giờ khi bạn gửi search, URL chứa chuỗi truy vấn tìm kiếm. Search cũng sẽ đi đến phương thức hành động của HttpGet Index, ngay cả khi bạn có phương thức HttpPost Index.

Thêm Search theo thể loại

Nếu bạn đã thêm phiên bản HttpPost của phương thức Index, hãy xóa nó ngay bây giờ.

Tiếp theo, bạn sẽ thêm một tính năng để cho phép người dùng search movie theo thể loại. Thay thế phương thức Index bằng code sau:

public ActionResult Index(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)) 
{ movies = movies.Where(x => x.Genre == movieGenre); } 
return View(movies); }

Phiên bản này của phương thức Index có tham số bổ sung, cụ thể là movieGenre. Một vài dòng code đầu tiên tạo một đối tượng List để giữ các thể loại movie từ cơ sở dữ liệu.

Đoạn code sau đây là truy vấn LINQ truy xuất tất cả các thể loại từ cơ sở dữ liệu.

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

Code này sử dụng phương thức AddRange của bộ sưu tập List chung để thêm tất cả các thể loại riêng biệt vào danh sách. (Nếu không có Distinct bổ nghĩa, các thể loại trùng lặp sẽ được thêm vào – ví dụ: phim hài sẽ được thêm hai lần trong mẫu của chúng ta). Đoạn code sau đó lưu trữ danh sách các thể loại trong đối tượng ViewBag.MovieGenre. Lưu trữ dữ liệu danh mục (như thể loại phim) như một đối tượng SelectList trong ViewBag, sau đó truy cập dữ liệu danh mục trong hộp danh sách thả xuống là cách tiếp cận điển hình cho các ứng dụng MVC.

Đoạn code sau đây cho thấy cách kiểm tra tham số movieGenre. Nếu nó không có sản phẩm nào, sẽ tiếp tục hạn chế truy vấn movie để giới hạn các movie được chọn thành thể loại được chỉ định.

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

Như đã nêu trước đó, truy vấn không chạy trên cơ sở dữ liệu cho đến khi danh sách movie được lặp lại (điều này xảy ra trong View, sau khi phương thức hành động Index trả về).

Thêm đánh dấu vào Index View để hỗ trợ Search theo thể loại
Thêm một trình trợ giúp Html.DropDownList vào tệp Views\Movies\Index.cshtml, ngay trước trình trợ giúp TextBox. Đánh dấu hoàn thành được hiển thị bên dưới:

@model IEnumerable<MvcMovie.Models.Movie> 
@{ ViewBag.Title = "Index"; } <h2>Index</h2> <p> 
@Html.ActionLink("Create New", "Create") 
@using (Html.BeginForm("Index", "Movies", FormMethod.Get)) 
{ <p>  Genre: @Html.DropDownList("movieGenre", "All") 
Title: @Html.TextBox("SearchString") <input type="submit" value="Filter" /> </p> } 
</p> <table class="table">

Trong đoạn code sau

@Html.DropDownList("movieGenre", "All")

Tham số “MovieGenre” cung cấp khóa cho trình trợ giúp DropDownList để tìm một IEnumerable<SelectListItem> trong ViewBag. ViewBag đã được điền trong phương thức hành động:

public ActionResult Index(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)) { movies = movies.Where(x => x.Genre == movieGenre); } 
return View(movies); }

Tham số “All” cung cấp nhãn tùy chọn. Nếu bạn kiểm tra lựa chọn đó trong trình duyệt của mình, bạn sẽ thấy thuộc tính “giá trị” của nó trống. Vì bộ điều khiển của chúng ta chỉ lọc chuỗi if không rỗng hoặc trống, việc gửi một giá trị trống cho movieGenre hiển thị tất cả các thể loại.

Bạn cũng có thể đặt tùy chọn được chọn theo mặc định. Nếu bạn muốn “Comedy” làm tùy chọn mặc định, bạn sẽ thay đổi code trong Controller như sau:

ViewBag.movieGenre = new SelectList(GenreLst, "Comedy");

Chạy ứng dụng và duyệt đến /Movies/Index. Thử search theo thể loại, theo tên movie và theo cả hai tiêu chí.

Trong phần này, bạn đã tạo phương thức hành động search và view cho phép người dùng search theo tiêu đề movie và thể loại. Trong phần tiếp theo, bạn sẽ xem xét cách thêm một thuộc tính vào mô hình Movie và cách thêm một bộ khởi tạo sẽ tự động tạo một cơ sở dữ liệu thử nghiệm.

 

Trả lời

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *