為什麼使用主版頁面?為了整個網站樣式統一,任何WEB應用程式都應該使用主版頁面。MVC架構中,有新的方式為主版頁面傳遞資料。
一個WEB應用程式可以包含多個主版頁面,主版頁面用於定義頁面配置,它與普通頁面的最大區別是多了<asp:ContentPlaceHolder>標籤,用於為子頁面內容佔位。當你建立視圖內容頁面(即普通頁面)時,可以選擇使用哪個主版頁面。內容頁面中會添加<asp:Content> 標籤來對應主版頁面中的<asp:ContentPlaceHolder>。在內容頁面中,並不抱括<html>或者<head>這些標籤。你必須把想要顯示的內容放在<asp:Content>標籤的範圍內,否則預覽頁面時會報錯。但是你並不用把所有<asp:ContentPlaceHolder>都用掉。
[1]修改內容頁面
當你使用主版頁面時,預設會使用主版頁面的頁面標題,如果想要自訂標題的話有兩種方式:
(1)使用在頁面源檔案頂部的<%@ page %> 標籤,如<%@ page title="Super Great Website" />
(2)有時你不僅需要修改標題,甚至需要修改meta標籤裡的內容,那麼你在設計主複本頁時將可以將Title、Meta標籤都包括在<asp:ContentPlaceHolder>標籤內部,當視圖頁面需要覆蓋這些內容時,你就可以用<asp:Content>標籤來重新定義你的Title和Meta.
如一個主版頁面中這樣定義:
Code
<head>
<asp:ContentPlaceHolder ID="head" runat="server">
<title>Please change my title</title>
<meta name="description" content="Please provide a description" />
<meta name="keywords" content="keyword1,keyword2" />
</asp:ContentPlaceHolder>
</head>
那麼在視圖頁面中你就可以用Content 覆蓋ContentPlaceHolder 裡的部份:
Code
<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server">
<title>The Index2 Page</title>
<meta name="description" content="Description of Index2 page" />
<meta name="keywords" content="asp.net,mvc,cool,groovy" />
</asp:Content>
[2]傳遞資料
(1)簡單的方式
使用ViewData將要顯示的資料傳遞給主版頁面,ViewData是一個Dictionary結構,主版頁面與內容頁面共用ViewData,只要通ViewData[key]的方式,就可以設定或擷取對應的Value。你可以在主版頁面中迭代ViewData中的列表用來顯示資料。但是這樣做會有一個問題:你必須在所有使用了這個主版頁面的View對應的Action中為ViewData賦值,否則頁面顯示就會報“未將對像引用到對像執行個體”異常,為瞭解決這個問題,你不得不在所有Action中添加相同的代碼,為主版頁面中的ViewData賦值,然而這樣會導致你的程式的可維護性、適應性大打折扣。
(2)較好的解決方案
為瞭解決重複代碼的問題,實現一次性為主版頁面賦值,可以定義一個抽像類實現ViewData賦值,而其它Contrller則繼承這個抽像類。比如定義這樣一個抽像類:
Code
namespace MvcApplication1.Controllers
{
public abstract class ApplicationController : Controller
{
private MovieDataContext _dataContext = new MovieDataContext();
public MovieDataContext DataContext
{
get { return _dataContext; }
}
public ApplicationController()
{
ViewData["categories"] = from c in DataContext.MovieCategories
select c;
}
}
}
這個類的建構函式中實現了查詢資料,並賦值給ViewData。這個["categories"] 就是key,是主版頁面中使用到的。同時這個類繼承了Controller。那麼其它地方的Contrller就可以繼承這個抽像類了:
public class MoviesController : ApplicationController
當介面顯示時,由於MoviesController 繼承自ApplicationController,所以會調用ApplicationController的建構函式以實現資料查詢,這樣資料就顯示在主版頁面上了。