自学MVC——增加搜索方法和视图

本节中,我们将添加一个SearchIndex方法,可以通过片名来搜索影片。/Movies/SearchIndex地址将可用。该请求将显示一个包含用户可以输入的Input元素的表单来查找影片。当用户提交表单后,该方法将得到用户提交的搜索值并用于搜索数据库。

首先在现有的MoviesController类中增加一个SearchIndex方法。该方法将返回包含Html表单的视图。以下为代码:

public ActionResult SearchIndex(string searchValue)
        {
            var movies = from m in db.Movies
                         select m;
            if (string.IsNullOrEmpty(searchValue)==false)
            {
                movies = movies.Where(m => m.Name.Contains(searchValue));
            }

            return View(movies);
        }

查询操作是延迟执行的,意味着表达式的值运算直到值被遍历或者调用ToList方法才会被执行。在这个例子中,查询是在SearchIndex视图中执行的。

现在我们可以来实现SearchIndex视图,由它来呈现用户表单。在SearchIndex方法内部右键单击,选择添加视图。在对话框中,勾选“创建强类型视图“,然后指定你将传递Movie对象给视图模板作为它的模型类。在支架模板列表中,选择List后点击添加,如下图所示

点击添加按钮后,视图模板Views\Movies\SearchIndex.cshtml将被创建。因为你选择了支架模板中的List,Visual Studio在视图中自动生成一些默认标记。支架系统查看Movie类并为其每个属性创建了<Label>属性元素,形成HTML表单。以下为视图文件:

@model IEnumerable<Mvc_Movie.Models.Movie>

@{
    ViewBag.Title = "SearchIndex";
}

<h2>SearchIndex</h2>

<p>
    @Html.ActionLink("Create New", "Create")
</p>
<table>
    <tr>
        <th>
            @Html.DisplayNameFor(model => model.Name)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Genra)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Price)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Date)
        </th>
        <th></th>
    </tr>

@foreach (var item in Model) {
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.Name)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Genra)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Price)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Date)
        </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>

运行程序,导航到/Movies/SearchIndex,在地址后附加一个类似”?searchValue=私人定制“的查询字符串,会将过滤后的结构显示出来。

如果你改变SearchIndex方法的签名,使参数标示符为ID,则参数ID将与在Global.asax文件中设置的默认路由匹配{controller}/{action}/{id},即把SearchIndex的形参searchValue修改为ID。现在你可以传递搜索名称作为路由数据替代查询字符串方式,即采用以下方式访问

http://localhost:54454/Movies/SearchIndex/私人定制

然而,你不能期望用户为了搜索影片而每次去修改Url.因此,添加交互界面(UI)来帮助他们过滤影片。如果你上文中对SearchIndex的方法签名进行了修改,用来测试通过路由绑定方式来传递ID参数,那么改回来,即方法拥有一个名称为searchValue的字符串类型参数。

打开Views\Movies\SearchIndex.cshtml文件,在@Html.ActionLink("Create New","Create")代码改为如下代码

@using (Html.BeginForm()){ 
<p> 片名: @Html.TextBox("searchValue")<br /> 
<input type="submit" value="查询" /></p> 
}

Html.BeginForm方法将创建<form>标记。用户通过点击”查询“按钮提交表单。运行程序并尝试查询影片。

实际并没有标记为HttpPost属性的SearchIndex的方法。因为该方法并没有修改应用的状态,仅仅是过滤数据,因此不需要HttpPost属性的重载方法。

此处有个问题,按上文所述,默认的SearchIndex方法属性是HttpGet,在视图中使用Html.BeginForm(),运行程序后,查看页面源代码,发现默认是<form action="/Movies/SearchIndex" method="post">,也即用户点击按钮后,是通过post方式把表单传递过来的,为啥会调用上面接受HttpGet方式的SearchIndex方法?难道是优先找HttpPost属性,找不到的情况下提交给HttpGet处理?这是Http协议机制还是MVC机制处理的结果?

你可以添加下面的HttpPost属性的SearchIndex方法。在这种情况下,方法调用将匹配HttpPost方式,下面的方法将被执行:

[HttpPost]
        public string SearchIndex(FormCollection frm, string searchValue)
        {
            return "<h3> 表单HttpPost方式搜索 : " + searchValue + "</h3>"; 
        }

 但是,即使我们添加了SearchIndex的HttpPost方法,使用的时候仍然存在限制。试想一下,你要得到一个特定的搜索书签,或者你想发送一个连接给朋友,他们可以通过点击看到与你相同的过滤后的电影列表。注意post请求的url和get请求的url完全相同,在地址栏没有搜索信息。搜索的文本信息作为表单域值送到服务器。因此你不能获取包含搜索信息的书签或者发给朋友一个链接。

解决方式就是使用BeginForm的重载方法,指明post请求添加搜索信息到url地址,并路由到HttpGet版本的SearchIndex方法。使用以下代码替换已存在的BeginForm方法

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

现在当你提交搜索时,url将包含查询字符串。即使存在HttpPost属性的SearchIndex方法,搜索工作也将由HttpGet属性的SearchIndex方法处理。

在本节中,我们创建了搜索方法和视图,让用户可以通过影片名称搜索数据库。在下节中,我们将学习如何给Movie模型添加一个属性,以及如何添加一个初始化器,用来自动创建测试数据库。

转载于:https://www.cnblogs.com/jackbase/articles/3517819.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值