您的位置:首页 > 编程语言 > ASP

学习ASP.NET MVC(七)——我的第一个ASP.NET MVC 查询页面

2014-08-17 20:58 369 查看
在本篇文章中,我将添加一个新的查询页面(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
在本篇中学习如何创建一个新的查询操作方法和视图,让用户通过书籍名称和书籍类型来进行查询。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐