1. 程式人生 > >【 MVC 】顯示資料庫資料表格

【 MVC 】顯示資料庫資料表格

之前看。net之美很多地方都看不明白,但是今天重新看了一下,覺得很有感悟。

我演示了在一個HTML表格中格式化一系列資料庫記錄的兩個方法。首先,我演示瞭如何直接在檢視中格式化資料庫記錄。接下來,我示範瞭如何在格式化資料庫記錄時利用部分類。

1.1建立模型類

我們將要顯示Movies資料庫表中的一系列記錄。Movies資料庫表包含下面的列:

Column Name Data Type Allow Nulls
Id Int False
Title Nvarchar(200) False
Director NVarchar(50) False
DateReleased DateTime False

為了表示Movies資料庫表,我們將利用Linq to SQL作為我們的資料訪問技術。換言之,我們將會使用LINQ to SQL來繫結我們的MVC模型類。

建立一系列LINQ to SQL類的最快辦法就是利用Visual Studio Object Relational Designer(Visual Studio 物件關係設計器)。右鍵點選Models資料夾,選擇“Add(新增)”,“New Item(新建項)”,選擇Linq To Sql類模板,將這個類命名為Movie.dbml,並且點選Add按鈕(如圖1)。

圖1:建立LINQ to SQL類

在你建立完Movie Linq to Sql 類以後,會立即出現物件關係設計器。你可以將資料庫表從伺服器瀏覽器(Server Explorer)視窗中拖曳到物件關係設計器中,以便建立代表著特定資料庫表的Linq to Sql類。你需要將Movies資料庫表新增到物件關係設計器中(如圖2)。

圖2:使用物件關係設計器

預設情況下,物件關係設計器將會試圖建立一個類名,該類名是資料庫表名的單數版本。換言之,如果你有一個叫做Customers的資料庫表,那麼物件關係設計器將會建立一個叫做Customer的類名。

通常,物件關係設計器非常適合完成這件事。不幸的是,物件關係設計器將資料庫表名Movies轉換為了Movy(很接近,但是錯的)。通過在設計器中的類名上點選,並且將類名由Movy改為Movie,你可以很容易地修正這個問題。

最後,記得點選“Save(儲存)”(軟盤圖示)按鈕來儲存LINQ to SQL類。否則的話,LINQ to SQL類將不會由物件關係設計器生成。

1.2 在控制器動作中使用LINQ to SQL

現在我們已經有了LINQ to SQL類,我們可以使用這些類從資料庫獲取資料。程式碼清單1中的控制器類使用LINQ to SQL類獲取來自Movies資料庫表的記錄。

程式碼清單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);
        }
    }
}

程式碼清單1中的Index()動作使用LINQ to SQL MovieDataContext類來獲取來自資料庫表中的電影。電影列表被傳遞給了Index檢視,作為ViewData.Model屬性的值。

1.3 在檢視中進行格式化

格式一系列資料庫記錄最簡單、但不一定是最好的辦法,就是直接在檢視中執行格式化。舉個例子,程式碼清單2中的Index檢視在一個HTML表格中呈現了movie資料庫的記錄。

程式碼清單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>

程式碼清單2中的檢視包含了一個foreach迴圈,該迴圈遍歷了movie記錄集中的每一個記錄。Movie的每一個屬性值都顯示在了各自的表格單元格中。表格的行由HTML <tr>標籤建立,表格單元格由HTML <td>標籤建立。

注意到Html.Encode()幫助方法用於在顯示每個屬性值之前對其進行編碼。任何時候當你接受使用者輸入,並且將輸入重新顯示在網頁上時,對輸入進行編碼以阻止JavaScript注入攻擊都是很重要的。當你對顯示HTML內容前對它進行編碼漠不關心時,黑客便可以做一些惡毒且邪惡的事情,例如從你的網站使用者中盜取私人資料。

當你執行應用程式,Index檢視會呈現如圖3所示的頁面。

圖3:使用HTML表格格式化了的資料庫記錄

圖3中HTML表格的格式化並不那麼令人興奮。我們可以通過建立層疊樣式表來改進HTML表格的外觀。因為程式碼清單2中的檢視是一個content檢視,我們必須將層疊樣式表新增到與content檢視相關聯的模板頁中。這個模板頁位於下面路徑:

\Views\Shared\Site.master

為了改進HTML表格的外觀,我們可以將程式碼清單3中的樣式表新增到模板頁<head>的開閉標籤之間。

程式碼清單3 – 層疊樣式表

<style type="text/css">
table
{
     border-collapse:collapse;
}

table td, table th
{
     border: solid 1px black;
     padding:10px;
}
</style>

程式碼清單3中的樣式表將單元格之間的邊框合併起來,並且添加了網格(gridlines)。在你將這個樣式表新增到模板頁之後,Index檢視呈現出圖4中的頁面。

圖4:使用了樣式的HTML表格

1.4 在區域性中格式化

除了在檢視本身中執行所有的格式化以外,你可以使用區域性頁面(partial)作為一個模板來格式化每一個數據庫記錄。舉個例子,程式碼清單4中的區域性頁面代表著對於一個特定movie資料庫記錄的格式化。

程式碼清單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>

程式碼清單4中的模板將每個movie記錄格式化為一個HTML表格行。模板應用到每一個數據庫記錄上。注意到ViewData.Model屬性,位於區域性頁面中,代表著單個數據庫記錄,而不是所有的資料庫記錄集。

為了將ViewData.Model屬性轉換為Movie類的例項,你需要為這個區域性頁面建立一個程式碼後置類。程式碼清單5中的程式碼後置類指定了MovieTemplate部分類繼承自一個泛型類,該泛型類將Movie作為它的型別引數。

程式碼清單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>類。因為MovieTemplate類繼承自這個類,ViewData.Model屬性自動轉換為Movie。

程式碼清單6中的Index檢視演示瞭如何在檢視中使用MovieTemplate部分類。Html.RenderPartial()方法用於呈現MovieTemplate區域性頁面。

程式碼清單 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>

在程式碼清單6中,Html.RenderPartial()方法用於為每個Movie記錄呈現MovieTemplate區域性頁面。兩個引數傳遞給了RenderPartial()方法。第一個引數是將要呈現的區域性頁面的名稱。和檢視一樣,預設情況下,區域性頁面必須位於Views\ControlName 資料夾或者是 Views\Shared資料夾。

第二個引數指定了傳遞給部分的檢視資料。在區域性頁面內部,ViewData.Model屬性將會代表一個特定的Movie記錄。

還有一個重要的警告。與大多數其他幫助方法不同,Html.RenderPartial()方法並不會返回一個字串。這意味著你不能像下面這樣呼叫RenderPatial()方法:

<%= Html.RenderPartial("MovieTemplate", m) %>

相反,你應該這樣呼叫這個方法:

<% Html.RenderPartial("MovieTemplate", m) %>

RenderPartial()方法完成了一些事情,但它不會表示出來。

1.5 小結

這本書探索了格式化資料庫記錄的兩個方法。首先,我們直接在一個檢視中格式化資料庫記錄。接下來,使用一個區域性頁面作為模板來格式化每一個數據庫記錄。