ASP.NET MVC 5 入门(08):添加搜索方法和搜索视图

原文:https://docs.microsoft.com/zh-cn/aspnet/mvc/overview/getting-started/introduction/adding-search

一、添加搜索方法和搜索视图

在本部分中,你将添加到搜索功能Index操作方法,您可以搜索电影的流派或名称。

二、系统必备

若要匹配此部分的屏幕截图,需要运行应用程序 (F5),并将以下电影添加到数据库。

标题 发布日期 流派 价格
Ghostbusters 6/8/1984 喜剧 6.99
Ghostbusters II 6/16/1989 喜剧 6.99
颗行星的大猩猩 3/27/1986 操作 5.99

三、更新索引窗体

通过更新开始Index到现有的操作方法MoviesController类。 下面是代码:

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 表达式 Lambda 在基于方法的用于LINQ查询用作标准查询运算符方法的参数,如其中上述代码中使用的方法。 进行定义或通过调用一个方法,如修改后不会执行 LINQ 查询WhereOrderBy 相反,延迟查询执行,这意味着表达式的计算延迟,直到真正循环访问其实现的值或 ToList 调用方法。 在中Search示例中,该查询中执行Index.cshtml视图。 有关延迟执行查询的详细信息,请参阅Query Execution(查询执行)。

Note

Contains方法运行数据库,而不是 c# 代码更高版本。 在数据库中, Contains映射到SQL LIKE,这是不区分大小写。

现在可以更新Index将向用户显示窗体的视图。

运行应用程序并导航到 /Movies/Index 将查询字符串(如 ?searchString=ghost)追加到 URL。 筛选的电影将显示出来。

SearchQryStr

如果您更改的签名Index方法,以使名为的参数id,则id参数将匹配{id}占位符默认路由中的设置应用_用户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。 因此需要添加 UI 来帮助他们筛选电影。 如果已更改的签名Index方法来测试如何传递绑定路由的 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); 
} 

打开ViewsMoviesIndex.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帮助器后,窗体会发布到其自身,当用户通过单击提交窗体筛选器按钮。

Visual Studio 2013 具有较好的改进时显示和编辑视图文件。 当你运行应用程序时的视图文件打开时,Visual Studio 2013 调用正确的控制器操作方法,以显示该视图。

索引视图 (如在上图中所示) 在 Visual Studio 中打开,点击 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>"; 
} 

SearchPostGhost

但是,即使添加 Index 方法的 HttpPost 版本,其实现方式也受到限制。 假设你想要将特定搜索加入书签,或向朋友发送一个链接,让他们单击链接即可查看筛选出的相同电影列表。 请注意,HTTP POST 请求的 URL 是 GET 请求 (localhost:xxxxx/Movies/Index) 的 URL 相同--没有 URL 本身中的搜索信息。 右现在,搜索字符串信息发送到服务器作为窗体字段值。 这意味着无法捕获该搜索信息加入书签或发送给朋友,在 URL 中。

解决方法是使用的重载BeginForm,它指定 POST 请求,应将搜索信息添加到 URL,并且应路由到HttpGet版本的Index方法。 替换现有无参数BeginForm方法替换为以下标记:

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

BeginFormPost_SM

现在提交搜索时,URL 包含搜索查询字符串。 即使具备 HttpPost Index 方法,搜索也将转到 HttpGet Index 操作方法。

IndexWithGetURL

四、添加按流派搜索

如果添加了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方法的泛型List集合以添加到列表中的所有不同的流派。 (而无需Distinct修饰符,则添加重复的流派 — 例如,将在我们的示例中两次添加喜剧)。 然后代码将存储在流派列表的ViewBag.MovieGenre对象。 将类别数据 (此类电影流派) 作为SelectList对象中ViewBag,则访问下拉列表框中的类别数据是典型的 MVC 应用程序的方法。

下面的代码演示了如何检查movieGenre参数。 如果不为空,则代码进一步约束电影查询,以限制到指定类型的所选的电影。

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

如前面所述,运行查询时不在数据库上直到电影列表循环访问 (这在视图中,会发生后Index操作方法返回)。

五、将标记添加到索引视图,以支持按流派搜索

添加Html.DropDownList到帮助程序ViewsMoviesIndex.cshtml文件,再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"提供的键DropDownList帮助器以查找IEnumerable<SelectListItem>ViewBag 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"提供选项标签参数。 如果在浏览器中查看该选择,您将看到其"值"属性为空。 由于我们的控制器仅筛选if字符串不是null或为空,将提交为空值movieGenre显示所有流派。

此外可以设置默认情况下选择的选项。 如果您希望"喜剧"作为默认选项,则会更改控制器中的代码如下所示:

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

运行应用程序,并浏览到 /Movies/Index 按流派、 电影名称和这两个条件,请尝试搜索。

在本部分中创建了搜索操作方法和视图,以让用户搜索电影标题和流派。 在下一部分中,将探讨如何将属性添加到Movie模型以及如何添加初始值设定项将自动创建测试数据库。

原文地址:https://www.cnblogs.com/springsnow/p/13264843.html