学习ASP.NET MVC(七)——我的第一个ASP.NET MVC 查询页面
学习ASP.NET MVC 编程系列目录
学习ASP.NET MVC(一)——我的第一个ASP.NET MVC应用程序
学习ASP.NET MVC(二)——我的第一个ASP.NET MVC 控制器
学习ASP.NET MVC(三)——我的第一个ASP.NET MVC 视图
学习ASP.NET MVC(四)——我的第一个ASP.NET MVC 实体对象
学习ASP.NET MVC(五)——我的第一个ASP.NET MVC CURD页面
学习ASP.NET MVC(六)——我的第一个ASP.NET MVC 编辑页面
学习ASP.NET MVC(七)——我的第一个ASP.NET MVC 查询页面
学习ASP.NET MVC(八)——“Code First Migrations ”工具
学习ASP.NET MVC(九)——“Code First Migrations ”工具使用示例
在本篇文章中,我将添加一个新的查询页面(SearchIndex),可以按书籍的种类或名称来进行查询。这个新页面的网址是http://localhost:36878/Book/ SearchIndex。该页面中用一个下拉框来显示种类,用一文本框让用户输入书籍的名称。当用户在点击“查询”按钮之后,页面会被刷新,显示用户的查询结果。控制器会根据用户提交查询参数,由动作方法(Action Motehd)去解析用户提交的参数值,并使用这些值来查询数据库。
第一步,创建SearchIndex查询页面
首先,在BookController中添加一个SearchIndex动作方法。该方法将返回一个包含HTML表单的视图。代码如下:
public ActionResult SearchIndex(string searchString)
{ var books = from m in db.Books
select m; if (!String.IsNullOrEmpty(searchString))
{ books = books.Where(s => s.Name.Contains(searchString)); }
return View(books);
}
上面SearchIndex方法代码中的第一行如下面,其作用是创建一个LINQ查询从数据库中筛选相应的书籍数据:
var books = from m in db.Books
select m;
这一句表示查询已经建立,但是尚未对数据存储区中的数据进行筛选。
如果“searchString”参数变量中有一个字符串,则这个“books”查询语句将以“searchString”参数变量的值做为查询条件进行筛选相应的书籍数据,如下面的代码:
if (!String.IsNullOrEmpty(searchString))
{
books = books.Where(s => s.Name.Contains(searchString)); }
上面代码中的s =>s.Title代码是一个Lambda表达式。 Lambda 表达式用在基于方法的 LINQ 查询中,作为诸如 Where 和 Where 等标准查询运算符方法的参数。 例如上面的代码中使用的方法。LINQ查询时未执行它们的定义,或者当他们通过调用一个方法进行修改,或在排序时进行修改。相反,查询执行的延迟,这意味着一个表达式的计算被延迟,直到其变量实际上的迭代结束或者可以调用的方法(ToList方法)被调用。在SearchIndex这个页面中,查询是在SearchIndex视图下执行。
接下来,我们来制作一个SearchIndex视图,以将这个查询界面呈现给用户看。在Visual Studio中的BookController文件中右键单击里面的SearchIndex方法,在弹出菜单中单击“添加视图”菜单。在添加视图对话框中,指定你要一个Book对象传递给视图模板作为它的模型类。在支架模板列表中,选择列表,然后单击“添加”。如下图。

当单击“添加”按钮,将创建一个Views\Book\ SearchIndex.cshtml视图模板。因为你选择了列表中的支架模板列表中,Visual Studio会自动生成(搭建)的视图中的一些默认的标记。基架创建一个HTML表单。它检查Book类和创建的代码来呈现为类的每个属性<label>元素。下面的清单显示生成的创建视图:
@model IEnumerable<MvcApplication1.Models.Book>
@{
ViewBag.Title = "书籍查询";
}
<h2>书籍查询</h2>
<p>
@Html.ActionLink("Create New", "Create")
</p>
<table>
<tr>
<th>
@Html.DisplayNameFor(model => model.Category)
</th>
<th>
@Html.DisplayNameFor(model => model.Name)
</th>
<th>
@Html.DisplayNameFor(model => model.Numberofcopies)
</th>
<th>
@Html.DisplayNameFor(model => model.AuthorID)
</th>
<th>
@Html.DisplayNameFor(model => model.Price)
</th>
<th>
@Html.DisplayNameFor(model => model.PublishDate)
</th>
<th></th>
</tr>
@foreach (var item in Model) {
<tr>
<td>
@Html.DisplayFor(modelItem => item.Category)
</td>
<td>
@Html.DisplayFor(modelItem => item.Name)
</td>
<td>
@Html.DisplayFor(modelItem => item.Numberofcopies)
</td>
<td>
@Html.DisplayFor(modelItem => item.AuthorID)
</td>
<td>
@Html.DisplayFor(modelItem => item.Price)
</td>
<td>
@Html.DisplayFor(modelItem => item.PublishDate)
</td>
<td>
@Html.ActionLink("Edit", "Edit", new { id=item.BookID }) |
@Html.ActionLink("Details", "Details", new { id=item.BookID }) |
@Html.ActionLink("Delete", "Delete", new { id=item.BookID })
</td>
</tr>
}
</table>
按F5, 运行该应用程序,并使用浏览器导航到/Book/ SearchIndex。在URL后面会追加一个查询字符串,如“?searchString=sql”。提交之后,符合条件的书籍数据将显示。如下图。

第三,修改SearchIndex查询方法
我们也可以修改SearchIndex方法的参数,传入一个命名参数“ID”,这个“ID”参数将匹配在Global.asax文件中的缺省路由设置中的{id}占位符。路由设置如下:
{controller}/{action}/{id}
原来SearchIndex方法如下所示:
public ActionResult SearchIndex(string searchString)
{ var books = from m in db.Books select m; if (!String.IsNullOrEmpty(searchString)) { books = books.Where(s => s.Name.Contains(searchString)); } return View(books);
}
修改后的SearchIndex方法将如下所示:
public ActionResult SearchIndex(string id)
{ string searchString = id;
var books = from m in db.Books
select m; if (!String.IsNullOrEmpty(searchString))
{ books = books.Where(s => s.Name.Contains(searchString)); } return View(books);
}
现在,您可以把查询条件“书籍名称”作为路由数据(URL中的一段字符),而不是作为查询字符串值。如下图。

第三,添加“书籍名称”查询条件
通过上面的学习,我们实现了数据查询功能。但是我们不能希望普通用户也能像我们一样,会在URL中添加查询条件。当需要进行查询时,自己去修改URL中的查询条件内容来进行书籍查询。所以,需要添加一个查询页面,方便普通用户输入相应的查询条件,根据查询条件去查询书籍。
一、改变SearchIndex方法的签名,并通过路由绑定到ID参数上,让SearchIndex方法接受一个名为“searchString”字符串作为参数。代码如下:
public ActionResult SearchIndex(string searchString)
{ var books = from m in db.Books select m; if (!String.IsNullOrEmpty(searchString)) { books = books.Where(s => s.Name.Contains(searchString)); }
return View(books); }
二、打开Views\Book\ SearchIndex.cshtml文件,在@Html.ActionLink("Create New", "Create")的位置处,添加一个文本框与一个查询按钮。内容如下:
@using (Html.BeginForm())
{ <p> 书籍名称: @Html.TextBox("SearchString")<br /> <input type="submit" value="查询" /></p> }
下面的代码显示了Views\Book\ SearchIndex.cshtml文件的一部分与增加的筛选标记。
@Model IEnumerable<MvcApplication1.Models.Book>
@{
ViewBag.Title = "书籍查询";
}
<h2>书籍查询</h2>
@using (Html.BeginForm())
{
<p> 书籍名称: @Html.TextBox("SearchString")<br />
<input type="submit" value="查询" /></p>
}
这个Html.BeginForm辅助方法创建了一个<form>标签。当用户通过单击“查询”按钮提交表单时,Html.BeginForm辅助方法将会把这个Form中的内容提交给控制器,同时刷新页面。
三、按F5,运行该应用程序,并在“书籍名称”文本框中输入“sql”,然后点击“查询”按钮,进行书籍查询。如下图。 
还有不需要重载SearchIndex的HttpPost的方法。因为该方法不改变应用程序的状态,只是是用来查询数据。
你可以象下面一样把[HttpPost]加在SearchIndex方法的上面。在添加了[HttpPost]之后,浏览器将首先调用匹配HttpPost的SearchIndex方法。HttpPost的SearchIndex方法运行结果如下图。
[HttpPost] public string SearchIndex(FormCollection fc, string searchString)
{ return "<h3> From [HttpPost]SearchIndex: " + searchString + "</h3>"; }

然而,即使添加了SearchIndex的HttpPost版本的方法。假设一下如下场景,你想把某个查询结果发给你的朋友,你又想只发一个特定链接给朋友,让他们可以查询查看相同的一个查询结果。请注意,如果是相同的查询结果,一个为HTTP POST请求,另一个为相同的URL GET请求(例如本地主机:XXXXX /图书/ SearchIndex ) 。则HTTP POST请求在URL本身没有带查询参数的情况下,是无法看到查询结果的。如果只是一个URL,这就意味着你与朋友们永远不能看到相同的查询结果。
你应该使用以下的解决方案,使用BeginForm的重载方法,指定POST请求应该在URL中添加的相应的查询参数信息 ,它应该被路由到SearchIndex方法的HTTPGET版本。使用下面的代码替换现有参数的BeginForm方法将:如下图。
@using (Html.BeginForm("SearchIndex", "book", FormMethod.Get))

现在,当你点击“查询”按钮时,URL中将包含查询条件的字符串。查询请求也将去请求HTTPGET的 SearchIndex操作方法,即使你有一个HttpPost的SearchIndex方法。如下图。 
第三,添加“书籍种类”查询方法
第一步,删除代码中HttpPost版本的SearchIndex方法。
第二步,添加新的查询功能。在页面中添加一个“书籍种类”的查询条件,让用户可以通过“书籍种类”查询到相关书籍。用下面的代码替换SearchIndex方法:
public ActionResult SearchIndex(string Category, string searchString)
{ var cateLst = new List<string>();
var cateQry = from d in db.Books orderby d.Category select d.Category; cateLst.AddRange(cateQry.Distinct()); ViewBag.category = new SelectList(cateLst); var books = from m in db.Books select m; if (!String.IsNullOrEmpty(searchString))
{
books = books.Where(s => s.Name.Contains(searchString)); } if (string.IsNullOrEmpty(Category)) return View(books); else {
return View(books.Where(x => x.Category == Category));
}
}
这个新的SearchIndex方法增加了一个新的查询条件,即Category。代码的前几行创建一个List对象从数据库中查询“书籍种类”,并将查询到的结果添加到List对象中。
下面的代码是通过一个LINQ查询从数据库把所有书籍种类都查了出来。
var cateQry = from d in db.Books
orderby d.Category
select d.Category;
以下代码的作用是使用泛型List集合的AddRange方法所有书籍类型添加到列表中。 (如果没有DISTINCT修饰符,会将相同的类型增加到列表中 - 例如,MS,SAP将会被我们添加两次)。
cateLst.AddRange(cateQry.Distinct());
然后,该代码存储在ViewBag对象流派列表。
ViewBag.category = new SelectList(cateLst);
下面的代码演示如何检查Category参数。如果它不是空的,该代码进一步限制了书的查询所选择的书限制到指定的种类。
if (string.IsNullOrEmpty(Category))
return View(books);
else
{
return View(books.Where(x => x.Category == Category));
}
第四,在SearchIndex查询页面中添加“书籍种类”查询条件
添加一个HTML样式的下拉列表框(DropDownList)到Views\Book\ SearchIndex.cshtml文件中,放在“书籍名称”文本框的前面。已完成的代码如下所示:
<p>
@using (Html.BeginForm("SearchIndex","book",FormMethod.Get)){
<p>书籍种类: @Html.DropDownList("category", "All")
书籍名称: @Html.TextBox("SearchString")
<input type="submit" value="查询" /></p>
}
</p>
按F5,运行这个应用程序,在浏览器中浏览/Book/ SearchIndex这个地址。就可以按“书籍种类”、“书籍名称”进行书籍信息查询。如下图1,图2。

图1

图2
在本篇中学习如何创建一个新的查询操作方法和视图,让用户通过书籍名称和书籍类型来进行查询。
学习ASP.NET MVC(七)——我的第一个ASP.NET MVC 查询页面的更多相关文章
- 学习ASP.NET MVC(一)——我的第一个ASP.NET MVC应用程序
学习ASP.NET MVC系列: 学习ASP.NET MVC(一)——我的第一个ASP.NET MVC应用程序 学习ASP.NET MVC(二)——我的第一个ASP.NET MVC 控制器 学习ASP ...
- 学习ASP.NET MVC(三)——我的第一个ASP.NET MVC 视图
今天我将对前一篇文章中的示例进行修改,前一篇文章中并没有用到视图,这次将用到视图.对于前一个示例中的HelloWorldController类进行修改,使用视图模板文件生成HTML响应给浏览器. 一. ...
- 7、ASP.NET MVC入门到精通——第一个ASP.NET MVC程序
本系列目录:ASP.NET MVC4入门到精通系列目录汇总 开发流程 新建Controller 创建Action 根据Action创建View 在Action获取数据并生产ActionResult传递 ...
- ASP.NET MVC入门到精通——第一个ASP.NET MVC程序
开发流程 新建Controller 创建Action 根据Action创建View 在Action获取数据并生产ActionResult传递给View. View是显示数据的模板 Url请求→Cont ...
- 初入码田--ASP.NET MVC4 Web应用之创建一个空白的MVC应用程序
初入码田--ASP.NET MVC4 Web应用开发之一 实现简单的登录 初入码田--ASP.NET MVC4 Web应用开发之二 实现简单的增删改查 2016-07-29 在此之前,需要一台电脑( ...
- ASP.NET没有魔法——开篇-用VS创建一个ASP.NET Web程序
为什么写这一系列文章? 本系列文章基于ASP.NET MVC,在ASP.NET Core已经发布2.0版本,微服务漫天的今天为什么还写ASP.NET?. 答:虽然现在已经有ASP.NET Core并且 ...
- 学习ASP.NET MVC(四)——我的第一个ASP.NET MVC 实体对象
今天我将根据数据库中的表结构添加一些类.这些类将成为这个ASP.NET MVC应用程序中“模型”的一部分. 我们使用Entity Framework(实体框架)来定义和使用这些模型类,并且 ...
- 学习ASP.NET MVC(六)——我的第一个ASP.NET MVC 编辑页面
在上一文章中由Entity Framework(实体框架)去实现了对数据库的CURD操作.在本篇文章中,主要是调试修改自动生成的动作方法和视图,以及调试编辑功能与编辑功能的Book控制器. 首先,在V ...
- 学习ASP.NET MVC(五)——我的第一个ASP.NET MVC CURD页面
在上一篇文章中我们已经创建了实体类,在这一篇文章中,我将创建一个新的控制器类——BookController,使用BookController对Books表中的数据进行CURD操作的方法,并使用视图模 ...
随机推荐
- [fortify] open redirect漏洞
简介: 些通过请求(如查询字符串和表单数据)指定重定向URL的Web程序可能会被篡改,而把用户重定向到外部的恶意URL.这种篡改就被称为开发重定向攻击. 场景分析 假设有一个正规网站http://ne ...
- ruby 学习笔记 2 -变量
变量 在ruby的世界里,变量有5种,全局变量 局部变量 实例变量 常量 类变量以及伪变量 常用的: 全局: 在全局使用,使用$开头,因为是全局的,所以在任何的代码例子中都可以改变其值,造成混乱,所以 ...
- 尝试u3d中将代码与编辑器分离
最近与朋友交流,他一直是做端游,最近接触了u3d以后无法忍受代码与配置文件,美术资源全部纠缠在一起的状况,于是一直在琢磨怎么将编辑器与代码彻底分离. 自己也抽空研究一下,碰到一些问题先记录下来. 首先 ...
- Asp.net Authenticated users 权限问题
偶然发现Windows,非系统盘 权限具有这个组Authenticated users 拥有这个组会出现的问题: Web站点可以访问非Web目录的文件.
- java轻量级Http Server
lighttpd 官方主页:www.lighttpd.netLighttpd是一个德国人领导的开源软件,其根本的目的是提供一个专门针对高性能网站,安全.快速.兼容性好并且灵活的web server环境 ...
- input文本框去除单击时的边框的方法
前端开发写的input文本框标签后单击时可以看到有边框,去除边框的方法: input{ outline:medium; }
- (一)读取PCD文件
下面是一个简单的读取PCD文件并显示的代码: #include <iostream> #include <pcl/io/pcd_io.h> #include <pcl/p ...
- redmine中创建项目与跟踪标签(原创)
今天来说下本公司所用到的项目管理工具redmine,总体来说还是比较好用的.redmine中可以记录项目的整个过程,可创建跟踪标签(里程碑.需求用例.功能.任务.缺陷)来进行对项目的管控.跟踪标签根据 ...
- iPhone的Push(推送通知)功能原理浅析
第一部分:Push原理(以下绝大多数内容参考自.图片来自iPhone OS Reference Library)机制简介Push 的工作机制可以简单的概括为下图图中,Provider是指某个iPhon ...
- javascript Xml兼容性随笔
一.前言 (function (window) { if (!window.jasen) { window.jasen = {}; } if (!window.jasen.core) { window ...