十一、以表格形式显示数据库中的数据
一、创建模型类
我们下面要显示Movies表中的数据,Movies表的结构如下:
Id Int False
Title Nvarchar(200) False
Director NVarchar(50) False
DateReleased DateTime False
我们以 Linq to Sql作为我们显示Movies表的数据访问技术。换句话说,我们使用Linq to Sql来写我们MVC模型类
在解决方案管理器中右击,选择“Add”-“New Item”,在弹出的对话框中,选择LINQ to SQL Classes模板,在把它命名为Movie.dbml,点击“Add”按钮。
《图1》
创建完LINQ to SQL Classes后,就会显示Object Relational Designer。我们从Server Explorer窗口中拖Movies表到Object Relational Designer,这样就会他建Linq to Sql类。
《图2》
默认情况下,Object Relational Designer会按照数据库中的表名来为Linq to Sql类命名。即,当我们把Customer表拖到Object Relational Designer上的时,会自动为我们创建名子为Customer的Linq to Sql类。我们可以在设计器中单击表的名子,修改类的名子。
最后记得点击“保存”按钮,否则Object Relational Designer 不会自动生成Linq to Sql类。
二、在控制器动作中使用Linq to Sql (原创:灰灰虫 http://hi.baidu.com/grayworm)
现在我们有了Linq to Sql类了,我们可以使用这些类从数据库中检索数据。下面的控制器代码就是使用 Linq to Sql类从Movies表中检索数据。
Listing 1 – Controllers\HomeController.cs
using System.Linq;
using System.Web.Mvc;
using MvcApplication1.Models;
namespace MvcApplication1.Controllers
{
[HandleError]
public class HomeController : Controller
{
public ActionResult Index()
{
var dataContext = new MovieDataContext();
var movies = from m in dataContext.Movies select m;
return View(movies);
}
}
}
上面的Index()动作使用LINQ to SQL中的MovieDataContext类从movies表中检索数据,并通过ViewData.Model属性向视图中传递movies表的记录集合。
三、在视图层格式化显示数据(原创:灰灰虫 http://hi.baidu.com/grayworm)
最简单的方法是直接对view进行格式化显示。比如下面的代码中,直接在把movies表中的数据显示在HTML表格中。
Listing 2 – Views\Home\Index.aspx
<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" AutoEventWireup="true" CodeBehind="Index.aspx.cs" Inherits="MvcApplication1.Views.Home.Index" %>
<%@ Import Namespace="MvcApplication1.Models" %>
<asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server">
<table>
<tr>
<th>Id</th><th>Title</th><th>Release Date</th>
</tr>
<% foreach (Movie m in (IEnumerable)ViewData.Model) { %>
<tr>
<td><%= m.Id %></td><td><%= Html.Encode(m.Title) %></td><td><%= m.DateReleased %></td>
</tr>
<% } %>
</table>
</asp:Content>
在上面的代码中包含一个foreach循环,该循环枚举movies集合中的值,因此每个movie对象的属性显示在table表格中。
这里需要注意的是我们在table表格中显示movies属性的时候都加上了Html.Encode()方法,当我们在接收用户输入的数据,并在页面上显示数据的时候,都应当使用Html.Encode()方法防止javascript注入攻击。
动行界面如图所示:
《图3》
上面显示的HTML表格对我们来说不是特别兴奋(因为界面不是多么友好)。我们可以使用CSS样式表来改善HTML表格外观。因为上面的表格只是显示内容,所以我们应当在母版页的<head></head>标记内加入样式表,样式表代码如下:。
Listing 3 – Cascading Style Sheet
<style type="text/css">
table
{
border-collapse:collapse;
}
table td, table th
{
border: solid 1px black;
padding:10px;
}
</style>
上面的样式表在单元格之间加入了格线,当我们向母版页中加入这段CSS样式表后,Index视图显示如下所示:
《图4》
四、格式化一部分
除了像上面讲的,在视图层格式化显示所有数据外,我们还可以像使用模板那样,只格式化显示数据库的一行。下面的代码我们只格式化显示了一第数据库记录的内容。
Listing 4 – \Views\Movies\MovieTemplate.ascx
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="MovieTemplate.ascx.cs" Inherits="MvcApplication1.Views.Movies.MovieTemplate" %>
<tr>
<td> <%=ViewData.Model.Id%></td>
<td> <%=Html.Encode(ViewData.Model.Title)%></td>
<td> <%=ViewData.Model.DateReleased.ToString("D")%></td>
</tr>
从上面的的代码模板我们可以看到,把每行movie记录格式化为一个HTML行。需要我们注意的是这里的ViewData.Model属性,它不再是一个记录集合,而一个表的一条记录。
要把ViewData.Model属性变为Movies类的一个实例,我们需要在后置代码类进行如下设置,从下面的代码中我们可以看到后置代码partial类不再继承自Page或Control,而是派生自System.Web.Mvc.ViewUserControl<Movie>泛型集合,其中每个元素是Movie类型的。
Listing 5 – \Views\Movies\MovieTemplate.ascx.cs
using MvcApplication1.Models;
namespace MvcApplication1.Views.Movies
{
public partial class MovieTemplate : System.Web.Mvc.ViewUserControl<Movie>
{
}
}
从上面的代码中我们看到MovieTemplate类派生自ViewUserControl<movie>类,所以ViewData.Model属性被自动转换成一个Movie对象。
下面的代码告诉我们如何在视图中使用MovieTemplate类,Html.RenderPartial()方法用来呈显MovieTemplate列表。
Listing 6 – \Views\Movies\Index.aspx
<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" AutoEventWireup="true" CodeBehind="Index.aspx.cs" Inherits="MvcApplication1.Views.Movies.Index" %>
<%@ Import Namespace="MvcApplication1.Models" %>
<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server">
<table>
<tr>
<th>Id</th><th>Title</th><th>Release Date</th>
</tr>
<% foreach (Movie m in (IEnumerable)ViewData.Model)
{
Html.RenderPartial("MovieTemplate", m);
} %>
</table>
</asp:Content>
在上面的代码中,Html.RenderPartial()方法是使用MovieTemplate类来呈显每一条Movie数据。RenderPartial()方法接收两个参数,第一个参数是要呈显的模板类的名称(与视图相似,默认情况下,模板类默认必须放在Views\ControllerName文件夹或Views\Shared文件夹);第二个参数指定传递给模板类的值,即将要在模板类中显示的实例对象,也就是模板中中ViewData.Model属性的值。
一个很重要的东西需要提醒一下:Html.RenderPartial()方法不像其它helper方法那样返回字符串,这意味着我们不能用下面的方式调用Html.RenderPartial()方法
<%= Html.RenderPartial("MovieTemplate", m) %>
应当使用下面这种调用方法
<% Html.RenderPartial("MovieTemplate", m); %>
总结
这篇文章主要讲了如何把数据库中表的数据显示为一个HTML表格。我们使用了两种方法来格式化显示表中的数据:
第一种法:直接在视图中格式化数据显示。
第二种法:使用ascx模板来格式化一条记录的显示情况,然后在视图中使用Html.RenderPartial()显示所有记录。