.NET前后台传值后使结果显示在同一个界面的方法
代码清单1:更新后的Index方法 - MoviesController.cs
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 查询,用来选择符合条件的电影:
代码清单2:选择电影的LINQ查询
var movies = from m in db.Movies
select m;
这个查询虽然在这里定义出来,但并没有在数据库中执行。
如果 searchString
参数包含一个字符串(不是空字符串),movies 查询将会添加一个查询字符串的过滤条件,代码如下:
代码清单3:添加查询过滤条件
if (!String.IsNullOrEmpty(searchString))
{
movies = movies.Where(s => s.Title.Contains(searchString));
}
代码清单3中的 s => s.Title
是一个 Lambda 表达式,Lambda 表达式被用在基于方法的LINQ查询中(上面代码中的 Where 方法),当做参数来使用。LINQ 语句在定义或修改的时候不会执行,相反的,查询会延迟执行,这意味着一个赋值语句直到迭代完成或调用 ToList 方法才具备真正的值。在上面的示例中,查询语句在 Index.cshtml 视图中执行。
现在,你可以修改Index 视图,让他展示一个表单给用户输入。
运行应用程序,并导航到 /Movies/Index ,在URL后面添加一个查询,例如 ?searchString=中国
,被过滤的电影内容如下:
图1:查询到的电影数据
如果你把 Index 方法的参数名改为 id,那么 id 参数将会匹配 App_Start\RouteConfig.cs 文件中的默认路由中的{id}
。
{controller}/{action}/{id}
修改后的Index方法如下:
代码清单4:修改后的 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);
}
修改以后,我们可以通过路由数据来传递查询字符串:
图2:使用URL片段进行查找
然而,你不能指望用户每次都通过修改URL来查找电影,因此你需要在界面上帮助他们过滤数据。如果你刚刚使用代码清单4中的代码测试了路由绑定是如何传递ID参数,现在再把它改回来,原始的代码可参考代码清单1。
打开Views\Movies\Index.cshtml 文件,在@Html.ActionLink("Create New", "Create")
后面添加如下代码:
代码清单5:修改Index.cshtml
<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>
标签。通过单击“Filter”按钮将表单提交给当前的页面。
运行应用程序,然后试着查找一个电影:
图3:在界面中过滤数据
我们可以为 Index 方法添加 HttpPost 的重载,这样一来,程序将会调用 HttpPost 修饰的 Index 方法,相应的代码和截图如下:
代码清单6:HttpPost 版的 Index 方法
[HttpPost]
public string Index(FormCollection fc, string searchString)
{
return "<h3> From [HttpPost]Index: " + searchString + "</h3>";
}
图4:调用了 HttpPost 版本的 Index 方法
然而,尽管我们添加了HttpPost版的Index方法,它在实现的时候仍然存在一些局限性。设想你想将一个比较详细的查询添加书签,或者你想将查询结果以链接形式发送给朋友,注意观察HTTP POST 请求的时候,URL是没有改变的(仍然是 localhost:xxxxx/Movies/Index),这个地址本身不包含查询信息。现在,查询信息是作为表单数据发送到服务器的,这意味着你不能抓取到URL中的查询信息,将URL作为书签或发送给朋友。
解决方案就是重写 BeginForm 语句,使它发送一个GET请求,从而调用HttpGet版本的Index方法,修改后的代码如下:
代码清单7:使用GET请求的BeginForm方法
@using (Html.BeginForm("Index", "Movies", FormMethod.Get))
图5:使用GET请求的BeginForm参数描述
现在你再点击“Filter”按钮进行查找,查找的参数将包含在URL中,然后调用HttpGet 版的 Index 方法:
图6:URL中包含了查询参数
之所以想到用这个方法,是因为这个方法可以实现将查询结果页面和原始查询输入页面实现在同一个页面中显示,实现这个预期功能之后,即使用户因为网速或其他问题导致查询结果页面暂时无法显示,也不会出现空页面状态,可以充分照顾用户心情。
一开始我自己按照上述讲解编写代码时,只是纯粹地将他的前后台代码复制粘贴了过来,却没有考虑到我的前台是使用foreach来显示后台数据,查找的语句也是编写在foreach里,将源代码复制后,导致整个格局混乱,且所编写的代码含参数很多,不可能每个函数一一声明,若按照借鉴的源代码根本不能实现,后来经过再次检查理解源代码,在微信的代码中删掉了一些改进后不需要的参数,原文中提到将Post方法删掉,我个人的代码因为Index中还有很多从后台传值到前台的功能,所以保留了Post,附上我后台的代码
[HttpPost]
public ActionResult Index5()//查询某一门成绩
{
string subjecname = Request.Form["SearchString"];
string xuehao = string.Empty;
}
前台如果现实的数据很多的话相信大家都会使用foreach,由于个人觉得Post虽然有瑕疵但更方便,所以我依然沿用了Post方法,即将原文中的最后一个参数改为FormMethod.Post,附上前台代码。
@using (Html.BeginForm("Index5", "Wechat", FormMethod.Post))
{ <p> 课程名称: @Html.TextBox("SearchString")<br />
<input type="submit" value="查询" /> </p>
}
然后如愿以偿实现了将输入数据页面和查询结果页面在同一个页面中实现的功能,附图