【MVC5】8.添加一个Search方法和Search视图

在本节中,您将添加搜索功能到Index操作方法,这样您能够通过电影类型或名称来搜索电影。


更新Index形式


先更新现有MoviesController类的Index操作方法。这是代码:


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); 
}



第一行 Index方法创建下面的LINQ查询选择电影:


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


查询定义在这一点上,但尚未对数据库运行。


如果searchString参数包含一个字符串,电影修改查询过滤搜索字符串的值,使用下面的代码:


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


s => s.Title代码是一个 Lambda表达式。Lambdas用于基于方法的LINQ查询参数标准查询运算符方法,正如上述方法的代码。LINQ查询时不执行他们定义的或修改WhereOrderBy等方法。相反,查询执行延迟,这意味着一个表达式的评价是推迟到其实现价值实际上是迭代或ToList方法被调用。在搜索示例中,执行查询的 Index.cshtml视图。关于延迟查询执行的更多信息,请参阅查询执行。注:包含方法在数据库上运行,而不是上面的c#代码。在数据库,包含映射到SQL,不分大小写。


现在你可以更新Index视图将显示给用户。


运行应用程序并导航到 /Movies/Index。追加一个查询字符串,如?searchString=ghost的URL,显示过滤后的电影。





如果你改变的Index方法有一个参数命名为id,id参数匹配{ id }占位符中设置的默认路由App_Start\RouteConfig.cs文件。


{controller}/{action}/{id}



原来的 Index方法是这样的:


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); 
}

修改后的 Index方法如下:


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); 
}


现在可以通过标题搜索路由数据(一个URL段),而不是作为一个查询字符串值。





然而,你不能指望用户每次他们想修改URL搜索一部电影。现在你将添加界面,帮助他们过滤电影。如果你改变了Index方法来测试如何传递route-bound ID参数,把它改回来,这样你的Index方法接受一个字符串参数命名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); 
}

打开 Views\Movies\Index.cshtml 文件,在   @Html.ActionLink("Create New", "Create") 后面添加如下:


@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>

Html.BeginForm助手创建一个<form>标记。Html.BeginForm的作用是当用户点击过滤按钮提交时表单form发布自己。


Visual Studio 2013在显示和编辑视图文件时有一个很好的改善,当您运行应用程序打开一个视图文件,Visual Studio 2013调用正确的控制器操作方法来显示视图。






在Visual Studio中打开Index视图(如上图所示),利用Ctr F5或F5运行应用程序,然后试着寻找一个电影。






没有HttpPost过载的Index方法。你不需要它,因为方法不改变应用程序的状态,只是过滤数据。


你可以添加以下HttpPost Index方法。在这种情况下,调用者将匹配HttpPost Index方法,而且HttpPost Index方法将如下图所示运行。


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






然而,即使你添加这个HttpPost版本的Index方法,有一个限制在都是如何实现的。想象一下你想收藏一个特定搜索或者您想要发送一个链接给朋友,他们可以点击为了看到相同的过滤列表的电影。注意到HTTP POST请求的URL是一样的GET请求的URL(localhost:xxxxx/Movies/Index)——在URL本身没有搜索的信息。现在,搜索字符串信息发送到服务器作为一个表单字段的值。这意味着你不能捕获搜索信息在URL书签或发送给朋友。


解决方案是使用一个超载的BeginForm指定POST请求应该搜索信息添加到URL,应该被路由到HttpGet版本的Index方法。取代现有的无参数BeginForm方法使用以下标记:


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




现在当你提交搜索的URL包含一个搜索查询字符串。搜索也会去HttpGet Index操作方法,即使你有一个HttpPost Index方法。






添加搜索类型


如果你添加 HttpPost版本的Index方法,现在删除它。
接下来,您将添加一个功能,让用户搜索电影流派。用下面的代码替换Index方法:


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);
}


这个版本的Index方法需要一个额外的参数,即movieGenre。最初的几行代码从数据库创建一个List对象来保存电影流派。


下面的代码是一个LINQ查询,从数据库中检索所有的流派。


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


通用列表的代码使用AddRange方法收集所有不同类型添加到列表中。(没有Distinct修饰词,重复类型将被添加——例如,喜剧会添加两次在我们的样例)。然后,代码存储ViewBag.movieGenre对象中的类型的列表。存储类数据(比如一个电影流派)作为ViewBag SelectList对象,然后访问类别下拉列表框中的数据,是一个典型的MVC应用程序的方法。


下面的代码显示了如何检查movieGenre参数。如果它不是空的,代码进一步限制了电影的代码查询,限制选择的电影为指定的类型。


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


如前所述,并不是运行在数据库的查询,而是直到电影遍历列表完成(视图中发生,在Index操作方法返回)。



将标记添加到Index视图支持搜索类型


在Views\Movies\Index.cshtml文件添加一个Html.DropDownList。在TextBox之前。如下所示完成标记:


@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">



在以下代码:


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

参数“movieGenre”为 DropDownListViewBag中找到 IEnumerable < SelectListItem  >提供了关键ViewBag是密集的操作方法:


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);
}

参数列表中的“ All”提供了项目预选。我们使用下面的代码:


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


在我们的数据库中有一个电影“ Comedy”风格,“ Comedy”将预选的下拉列表。因为我们没有一个电影流派“ All”,在 SelectList中没有“ All”,所以当我们回来后没有做一个选择, movieGenre查询字符串值是空的。


运行应用程序和浏览/Movies/Index。试着搜索类型,电影名称和标准。






在本节中,您创建了一个search动作方法和观点,让用户搜索电影标题和流派。在下一节中,您将看看如何将属性添加到电影模型以及如何添加一个初始化,将自动创建一个测试数据库。


  

















评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值