zoukankan      html  css  js  c++  java
  • 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模型以及如何添加初始值设定项将自动创建测试数据库。

  • 相关阅读:
    理想团队模式构建的设想以及对软件流程的理解
    一、环境搭建 之 Windows10 安装 python3.5.2
    Codeforces1176A(A题)Divide it!
    Codeforces1144A(A题)Diverse Strings
    Codeforces1144B(B题)Parity Alternated Deletions
    Codeforces1144C(C题)Two Shuffled Sequences
    Codeforces1144D(D题)Equalize Them All
    Codeforces1157A(A题)Reachable Numbers
    Codeforces1157B(B题)Long Number
    Codeforces1141E(E题)Superhero Battle
  • 原文地址:https://www.cnblogs.com/springsnow/p/13264843.html
Copyright © 2011-2022 走看看