設計ASP.NET MVC2 Master Page

by Vivid 5. 四月 2011 21:39

許多的網站都有一些共通的視覺化介面,例如網站名稱、選單項目、公司LOGO等等,在網站中的多個網頁都會重複的出現。在ASP.NET 2.0版後引進一個主版頁面(Master Page)的技術,將這些共通的部分定義在*.master檔案,搭配內容頁面(Content Page,*.aspx)來設計網站。在網頁執行時期,ASP.NET會自動地將*.master檔案的內容和內容頁面合併成一個網頁。當然ASP.NET MVC類型的專案也支援這樣的設計模式,View Master Page能夠在ASP.NET MVC類型的專案中,建立一致的網站外觀,並能夠簡化程式的設計。本文將介紹如何在ASP.NET MVC 2的架構之下使用Master Page主版頁面。

預設在使用Visual Studio工具建立ASP.NET MVC專案時,會自動在View\Shared目錄中建立一個Site.Master檔案,當做主檔頁面。如果要自行建立一個Master Page,讓所有的View存取,您可以在View\Shared目錄上,按滑鼠右鍵,選擇「Add」「New Item」「MVC 2 View Master Page」項目來建立它們,參考圖1所示。


 clip_image002
圖 1:建立MVC 2 View Master Page。


Master Page的副檔名是.master,可以包含HTML標籤,如<Html>、<head>、<body>等,以及指令碼(Script),底下是一個Master檔範例:

<%@ Master Language = "C#" Inherits = "System.Web.Mvc.ViewMasterPage" % >
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" >
<html xmlns = "http://www.w3.org/1999/xhtml" >
<head runat = "server">
    <title> <asp:ContentPlaceHolder ID = "TitleContent" runat = "server" /> </title>
</head>
<body>
    <div>
        <asp:ContentPlaceHolder ID = "MainContent" runat = "server">
        我是預設的內容
        </asp:ContentPlaceHolder>
    </div>
</body>
</html>


在Master Page中,可以包含一到多個<asp:ContentPlaceHolder> 標籤,每一個<asp:ContentPlaceHolder> 標籤預留了一塊可以使用內容頁面進行客製化的空間。您可以在ContentPlaceHolder之中加入客製化的內容,如範例中加入「我是預設的內容」字串,參考圖2所示。


 clip_image002[4]
圖 2:內容頁面執行結果。

View的內容如下,沒有改寫Master ContentPlaceHolder中的內容,只包含一個顯示標題的Content控制項:

<%@ Page Language = "C#" MasterPageFile = "~/Views/Shared/ViewMasterPage1.Master" Inherits  = "System.Web.Mvc.ViewPage"  % >

<asp:Content ID = "indexTitle" ContentPlaceHolderID = "TitleContent" runat = "server">
    Home Page
</asp:Content>

執行結果,參考圖3所示:


 clip_image002[6]
圖 3:內容頁面執行結果。


您也可以在Master檔案中設計多個ContentPlaceHolder控制項,例如底下HTML標籤定義了兩個置放內容的ContentPlaceHolder:

<%@ Master Language  = "C#" Inherits  = "System.Web.Mvc.ViewMasterPage" % >

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"  >

<html xmlns =  "http://www.w3.org/1999/xhtml" >
<head runat = "server" >
    <title>  <asp:ContentPlaceHolder ID = "TitleContent" runat = "server" /> </title>
</head>
<body>
    <div>
        <asp:ContentPlaceHolder ID = "MainContent" runat = "server">
        我是預設的內容
        </asp:ContentPlaceHolder>
        <hr />
          <asp:ContentPlaceHolder ID = "ContentPlaceHolder1" runat = "server">
         我是預設的內容2
        </asp:ContentPlaceHolder>
    </div>
</body>
</html>

接著修改View,加入兩個Content控制項,第一個Content控制項(indexContent)的ContentPlaceHolderID設定為MainContent,對應到master檔案中ID為MainContent的ContentPlaceHolder控制項;第二個Content控制項(Content1)的ContentPlaceHolderID設定為ContentPlaceHolder1,對應到master檔案中ID為ContentPlaceHolder1的ContentPlaceHolder控制項:

<%@ Page Language = "C#" MasterPageFile = "~/Views/Shared/ViewMasterPage1.Master" Inherits = "System.Web.Mvc.ViewPage" % >
<asp:Content ID = "indexTitle" ContentPlaceHolderID = "TitleContent" runat = "server">
    Home Page
</asp:Content>
<asp:Content ID = "indexContent" ContentPlaceHolderID = "MainContent" runat = "server">
    <h2> <%= Html.Encode( ViewData["Message"] ) %> </h2>
    <p>
        這是MainContent
    </p>
</asp:Content>
<asp:Content ID = "Content1" ContentPlaceHolderID = "ContentPlaceHolder1" runat = "server">
    <h2> Content1 </h2>
    <p>
        這是Content1
    </p>
</asp:Content>

內容頁面執行的結果,參考圖4所示。


 clip_image002[8]
圖 4:內容頁面執行結果。

 

在Controller存取Master

 

在ASP.NET MVC專案中,可以在Controller Action回傳View時,指明要將Master與Content 網頁進行合併,以便動態利用程式碼來設定Master。當您如此做時,它的優先順序會比在網頁上方使用MasterPageFile設定Master來的高。例如View利用MasterPageFile設定:

<%@ Page Language = "C#" MasterPageFile = "~/Views/Shared/Site.Master" Inherits = "System.Web.Mvc.ViewPage" %>

而Controller動態指定為ViewMasterPage1.master,回傳View時,傳入View的名稱以及其主版頁面的名稱即可:

public class HomeController : Controller {
        public ActionResult Index () {
            return View( "Index" , "ViewMasterPage1" );
        }
        public ActionResult About () {
            return View();
        }
    }

巢狀式主版頁面

 

ASP.NET MVC 2也支援主版頁面,適合在多層次的主版頁面架構下使用。舉例來說,假設總公司設計一個Systex.Master主版頁面,包含以下HTML標籤,顯示「這是Systex Content」文字,表示總公司共有介面。

<%@ Master Language = "C#" Inherits = "System.Web.Mvc.ViewMasterPage" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" >
<html xmlns = "http://www.w3.org/1999/xhtml" >
<head runat = "server">
    <title> <asp:ContentPlaceHolder ID = "TitleContent" runat = "server" /> </title>
</head>
<body>
    <div>
    <h1> Systex </h1>
        <asp:ContentPlaceHolder ID = "MainContent" runat = "server">
        這是Systex Content
        </asp:ContentPlaceHolder>
    </div>
</body>
</html>


Systex總公司底下有一個UUU子公司,其主版頁面為UUU.Master,內容如下,利用MasterPageFile指定主版頁面為~/Views/Shared/ Systex.Master。因為UUU.Master是Systex.master的內容頁面,因此需要先使用Content控制項將欲顯示資訊封裝起來。在Content下,包含一個ContentPlaceHolder控制項,這是預留給真正的Content(.aspx)頁面顯示的空間,包含以下HTML標籤,顯示「這是UUU的 Content」文字,表示子公司UUU共有介面:

<%@ Master Language = "C#" MasterPageFile = "~/Views/Shared/Systex.Master" Inherits = "System.Web.Mvc.ViewMasterPage" %>
<asp:Content ID = "indexContent" ContentPlaceHolderID = "MainContent" runat = "server">
    <h1>
        UUU </h1>
    <asp:ContentPlaceHolder ID = "MainContent" runat = "server">
        這是UUU的 Content
    </asp:ContentPlaceHolder>
</asp:Content>


Index View的HTML標籤如下,先利用MasterPageFile指示詞指定主版頁面為~/Views/Shared/UUU.Master,然後顯示「這是Index的Content」靜態文字:

<%@ Page Language = "C#" MasterPageFile = "~/Views/Shared/UUU.Master" Inherits = "System.Web.Mvc.ViewPage" %>
<asp:Content ID = "indexContent" ContentPlaceHolderID = "MainContent" runat = "server">
    <h2>
        <%= Html.Encode(ViewData["Message"]) %> </h2>
    <p>
        這是Index的Content
    </p>
</asp:Content>


內容頁面執行結果,參考圖5所示。
 
clip_image002[10]

圖 5:內容頁面執行結果。

存取Master資料

 

您可以使用ViewData傳遞資料給Master,為了能夠重複地使用,它的寫法和一般寫法不太一樣,不直接在Controller的Action中,將想傳遞的資料加入ViewData集合,而是將程式獨立出來,例如以下範例程式撰寫一個DataController類別,繼承 Controller 類別,在其建構函式中將資料放在ViewData集合,這資料將提供給Master存取:

namespace MVC2_MP.Controllers {
    public class DataController : Controller {
        public DataController () {
            ViewData [ "data" ] = "Hello from DataController";
        }
    }
}


讓你的Controller再繼承自DataController,例如底下的HomeController: 

namespace MVC2_MP.Controllers {
    [HandleError]
    public class HomeController : DataController {
        public ActionResult Index () {
            return View();
        }
   }
}

接著修改Master的內容,在Master檔案中,使用ViewData["Data"]取得Controller傳遞過來的資料:

<%@ Master Language = "C#" Inherits = "System.Web.Mvc.ViewMasterPage" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" >
<html xmlns = "http://www.w3.org/1999/xhtml" >
<head runat = "server">
    <title> <asp:ContentPlaceHolder ID = "TitleContent" runat = "server" />
    </title>
</head>
<body>
    <div>
   <h2> <%= Html.Encode(ViewData["Data"]) %></h2>
        <asp:ContentPlaceHolder ID = "MainContent" runat = "server">
        ViewMasterPage1.Master我是預設的內容
        </asp:ContentPlaceHolder>    
    </div>
</body>
</html>

Index View的內容如下:

<%@ Page Language = "C#" MasterPageFile = "~/Views/Shared/ViewMasterPage1.Master" Inherits = "System.Web.Mvc.ViewPage" %>

<asp:Content ID = "indexContent" ContentPlaceHolderID = "MainContent" runat = "server">
   <p>
        這是Index的Content
    </p>
</asp:Content>

執行,網頁中就會顯示出Controller傳遞到Master的「Hello from Data Controller」字串,參考圖6所示。

 clip_image002[12]
圖 6:內容頁面執行結果。

 

使用View User Control

類似ASP.NET的使用者控制項,View User Control代表部分的View,它可以包含HTML與Script,以便於您在同一個頁面中,重複的使用。您可以在View\Shared目錄上,按滑鼠右鍵,選擇「Add」「View」項目來建立它們,底下建立一個名為Copyright的View User Control,建立時要勾選「Create a partial view(.ascx)」核取方塊,參考圖7所示。

 clip_image002[14]
圖 7:加入View User Control

專案中Shared目錄下會自動建立一個Copyright.ascx檔案,檔案中以Control指示詞進行宣告,其中我加上了版權的文字說明:

<%@ Control Language = "C#" Inherits = "System.Web.Mvc.ViewUserControl" %>
<h2> Copyright © 2010 by UUU, All Rights Reserved </h2>

在View之中,若要使用到View User Control,你可以叫用RenderPartial方法,並傳入View User Control的名字,如以下程式碼所示:
<%@ Page Language = "C#" MasterPageFile = "~/Views/Shared/ViewMasterPage1.Master" Inherits = "System.Web.Mvc.ViewPage" %>

<asp:Content ID = "indexContent" ContentPlaceHolderID = "MainContent" runat = "server">
   <h1> Index </h1>
    <p>
        <% Html.RenderPartial("Copyright"); %>
    </p>
</asp:Content>

內容頁面執行結果,參考圖8所示:

 clip_image002[16]
圖 8:內容頁面執行結果。


傳遞ViewData到View User Control

 

要如何將ViewData傳到View User Control呢?您可以從Model著手。假設在Model目錄下,建立一個Contact.cs類別檔案,其中定義一個Contact類別,包含ID、Name屬性。
namespace MVC2_MP.Models {
    public class Contact {
        public string ID { get; set; }
        public string Name { get; set; }
    }
}

接著在專案中根路徑下建立一個Filter子目錄,其中包含一個MyFilter.cs檔案,定義MyFilter類別,此類別繼承了System.Web.Mvc命名空間下的ActionFilterAttribute類別,在Controller的Action Result 執行之前會執行OnResultExecuting中的程式碼。範例中改寫了OnResultExecuting
方法,建立了Contact物件,設定ID、Name的值為「001」、「Mary」,然後將物件指定給ViewData [ "MyData" ]

using MVC2_MP.Models;
namespace MVC2_MP.Filter {
    public class MyFilter : ActionFilterAttribute
    {
        public override void OnResultExecuting ( ResultExecutingContext filterContext ) {
            base.OnResultExecuting( filterContext );
            Contact c = new Contact();
            c.ID = "001";
            c.Name = "Mary";
            filterContext.Controller.ViewData [ "MyData" ] = c;
        }
    }
}

在View User Control之中,您可以直接使用Model取得Contact物件,例如修改底下的Copyright.ascx,在版權宣告的下方,印出連絡人資訊:

<%@ Control Language = "C#" Inherits = "System.Web.Mvc.ViewUserControl< MVC2_MP.Models.Region >" % >
<h2> Copyright © 2010 by UUU, All Rights Reserved </h2>

連絡人:<%=  Model.ID %> - <%= Model.Name %>
再來您Controller的Action必需要套用前述的MyFilter,在HomeController類別Index方法上方,加上MyFilter Attribute:

public class HomeController : Controller {
        [MVC2_MP.Filter.MyFilter]
        public ActionResult Index () {
            return View();
        }
    }

除了在Index action上方標示MyFilter Attribute之外,若有其它Action需要使用到相同的功能,你也可以在這些方法上方進行套用。最後Index View要呈現View User Control時,便可以叫用RenderPartial方法,額外傳入ViewData,例如底下所示:

<%@ Page Language = "C#" MasterPageFile = "~/Views/Shared/ViewMasterPage1.Master" Inherits = "System.Web.Mvc.ViewPage" %>

<asp:Content ID = "indexContent" ContentPlaceHolderID = "MainContent" runat = "server" >
   <h1> Index </h1>
    <p>
        <% Html.RenderPartial( "Copyright", ViewData["MyData"]); %>
    </p>
</asp:Content>

Html.RenderPartial傳入兩個參數:一為View User Control的名稱,此例為Copyright;一為ViewData,傳入MyData。

總結

在大型的網站之中,主版頁面是一個非常重要的設計架構,能夠讓你很容易地管理網站中會重複出現的UI介面或程式碼。在這篇文章中,介紹如何建立Master檔案來控制整個網站的顯示格式,以及如何在Master檔案與內容頁面中傳遞資料。

Tags:

ASP.NET | 許薰尹Vivid Hsu | .NET Magazine國際中文電子雜誌

評論 (63) -

cours de theatre
cours de theatre United States
2017/9/30 下午 02:25:39 #

I loved your blog article.Thanks Again. Will read on...

回覆

can ho vung tau
can ho vung tau United States
2017/10/6 下午 11:16:45 #

Im obliged for the article post.Much thanks again. Much obliged.

回覆

buy hacklinks
buy hacklinks United States
2017/10/9 下午 01:12:06 #

Thank you for your blog.Thanks Again. Keep writing.

回覆

sklep z lekami na potencje
sklep z lekami na potencje United States
2017/10/9 下午 02:49:49 #

Major thankies for the blog. Fantastic.

回覆

solarmovie
solarmovie United States
2017/10/10 下午 06:55:01 #

wow, awesome blog post. Want more.

回覆

Sterling Businesses Ltd
Sterling Businesses Ltd United States
2017/10/10 下午 09:01:35 #

I really like and appreciate your post.Really thank you! Cool.

回覆

pirater un compte facebook
pirater un compte facebook United States
2017/10/10 下午 11:20:22 #

Thank you ever so for you article post.Much thanks again. Great.

回覆

buy hacklink
buy hacklink United States
2017/10/12 下午 07:44:59 #

Say, you got a nice blog article. Really Great.

回覆

over here
over here United States
2017/10/14 下午 02:25:08 #

Major thanks for the blog post.Really thank you! Fantastic.

回覆

dragon city hack unlimited gems apk
dragon city hack unlimited gems apk United States
2017/10/15 下午 02:26:45 #

Great article post.Much thanks again. Cool.

回覆

look at this web-site
look at this web-site United States
2017/10/17 下午 01:44:09 #

I loved your blog.Really thank you! Want more.

回覆

sletrokor
sletrokor United States
2017/10/17 下午 07:16:58 #

I cannot thank you enough for the post.Really thank you! Keep writing.

回覆

sex pills
sex pills United States
2017/10/19 上午 06:20:14 #

Great, thanks for sharing this post.Really looking forward to read more. Cool.

回覆

visit homepage
visit homepage United States
2017/10/19 下午 05:07:43 #

Im thankful for the blog post. Great.

回覆

pure slim 1000 review
pure slim 1000 review United States
2017/10/20 上午 02:38:19 #

Thank you ever so for you article. Want more.

回覆

carte grise en ligne
carte grise en ligne United States
2017/10/21 上午 05:58:04 #

Looking forward to reading more. Great article.Thanks Again. Great.

回覆

kassa
kassa United States
2017/10/21 下午 04:22:42 #

Awesome article. Really Cool.

回覆

Turbotax phone number
Turbotax phone number United States
2017/10/24 上午 08:37:53 #

Thanks for the blog.Really looking forward to read more. Want more.

回覆

vung tau melody
vung tau melody United States
2017/10/28 上午 08:52:04 #

Really enjoyed this blog article.Really thank you! Fantastic.

回覆

EZ Battery Reconditioning Review
EZ Battery Reconditioning Review United States
2017/10/30 上午 07:45:04 #

Thanks again for the blog article.Really looking forward to read more. Awesome.

回覆

lepszy plock
lepszy plock United States
2017/10/30 下午 03:31:05 #

Really appreciate you sharing this post.Much thanks again. Will read on...

回覆

life leadership
life leadership United States
2017/11/1 上午 07:59:12 #

Major thankies for the article post.Really looking forward to read more. Cool.

回覆

phenocal
phenocal United States
2017/11/1 下午 03:22:26 #

Thanks a lot for the blog post.Really looking forward to read more. Great.

回覆

phentaslim review
phentaslim review United States
2017/11/3 下午 12:45:54 #

Say, you got a nice blog article.Really thank you! Want more.

回覆

home remedies for back pain
home remedies for back pain United States
2017/11/15 上午 09:14:57 #

I am so grateful for your blog.Thanks Again. Really Great.

回覆

avocat criminel montreal
avocat criminel montreal United States
2017/11/16 下午 07:48:34 #

I cannot thank you enough for the blog article.Much thanks again. Really Great.

回覆

https://penzu.com/p/c42ffb18
https://penzu.com/p/c42ffb18 United States
2017/11/17 下午 06:22:10 #

Im obliged for the blog.Really looking forward to read more. Much obliged.

回覆

bikinis
bikinis United States
2017/11/23 下午 11:20:15 #

Very neat article post.Much thanks again. Fantastic.

回覆

Seo Services New Zealand
Seo Services New Zealand United States
2017/11/25 下午 08:15:30 #

Thank you for your article. Cool.

回覆

Chad Boonswang and Jeffrey Goodman
Chad Boonswang and Jeffrey Goodman United States
2017/11/26 下午 07:25:20 #

Thank you ever so for you blog article.Thanks Again. Keep writing.

回覆

Chad Boonswang SEO
Chad Boonswang SEO United States
2017/11/27 上午 01:33:59 #

Appreciate you sharing, great blog.Really thank you! Really Great.

回覆

car wrecker scammer
car wrecker scammer United States
2017/11/29 下午 05:56:51 #

Thanks again for the article.Much thanks again. Much obliged.

回覆

Osimi Sea view
Osimi Sea view United States
2017/11/30 上午 12:34:49 #

Wow, great blog article.Much thanks again. Awesome.

回覆

commercial real estate loan
commercial real estate loan United States
2017/12/1 上午 02:21:25 #

I really liked your blog post.Much thanks again. Want more.

回覆

porno
porno United States
2017/12/1 下午 06:04:06 #

Fantastic blog post.Really thank you! Will read on...

回覆

Credit Mastery builds business credit
Credit Mastery builds business credit United States
2017/12/3 上午 06:17:27 #

Awesome post.Much thanks again. Fantastic.

回覆

mobile hentai
mobile hentai United States
2017/12/5 上午 11:06:22 #

Really enjoyed this blog article.Much thanks again. Keep writing.

回覆

Really informative blog article.Really looking forward to read more. Awesome.

回覆

Major thankies for the blog.Really looking forward to read more. Cool.

回覆

legal law
legal law United States
2017/12/10 下午 08:41:10 #

I value the article post.Really looking forward to read more.

回覆

Chloe Silao
Chloe Silao United States
2017/12/14 上午 10:48:08 #

Really appreciate you sharing this blog. Keep writing.

回覆

canon drivers
canon drivers United States
2017/12/16 下午 07:21:41 #

I value the blog article. Great.

回覆

weight loss
weight loss United States
2017/12/17 上午 01:41:07 #

A round of applause for your article.Really thank you! Great.

回覆

I think this is a real great blog article.Really thank you! Cool.

回覆

Transition
Transition United States
2017/12/17 下午 06:59:05 #

Hey, thanks for the blog post.Thanks Again. Want more.

回覆

buy degree certificate online
buy degree certificate online United States
2017/12/18 上午 02:06:28 #

I really enjoy the blog post.Really thank you! Great.

回覆

online job
online job United States
2017/12/20 下午 08:17:51 #

Really informative article.Much thanks again. Keep writing.

回覆

canon drivers
canon drivers United States
2017/12/23 上午 08:25:14 #

Really informative blog post.Really thank you! Great.

回覆

Darwin Horan
Darwin Horan United States
2017/12/23 下午 06:52:52 #

Fantastic article post.Really thank you! Much obliged.

回覆

Thanks again for the blog article.Really looking forward to read more. Cool.

回覆

driver hp
driver hp United States
2017/12/25 下午 08:23:37 #

wow, awesome blog article. Really Great.

回覆

Really appreciate you sharing this article post.Much thanks again. Awesome.

回覆

Im thankful for the post. Much obliged.

回覆

SOCCER HIGHLIGHTS
SOCCER HIGHLIGHTS United States
2017/12/26 下午 03:56:07 #

I truly appreciate this post.Much thanks again. Cool.

回覆

canon drivers
canon drivers United States
2017/12/27 下午 07:14:26 #

A round of applause for your blog article.Thanks Again. Will read on...

回覆

drivers hp
drivers hp United States
2018/1/2 上午 09:52:58 #

I truly appreciate this post.Really looking forward to read more. Keep writing.

回覆

Read More Here
Read More Here United States
2018/1/2 下午 05:57:57 #

Very good post.Thanks Again. Great.

回覆

Wow, great blog.Much thanks again. Cool.

回覆

printer driver
printer driver United States
2018/1/3 上午 09:16:10 #

Awesome blog post.Much thanks again. Will read on...

回覆

casino bonus codes
casino bonus codes United States
2018/1/4 下午 07:56:50 #

Major thanks for the article post.Thanks Again. Much obliged.

回覆

hp printer driver
hp printer driver United States
2018/1/5 下午 08:15:40 #

Fantastic post. Much obliged.

回覆

FBA
FBA United States
2018/1/6 下午 12:19:58 #

Awesome article post.Much thanks again. Awesome.

回覆

colocation miami
colocation miami United States
2018/1/10 上午 08:59:35 #

wow, awesome article.Really thank you! Will read on...

回覆

新增評論




  Country flag
biuquote
  • 評論
  • 線上預覽
Loading






NET Magazine國際中文電子雜誌

NET Magazine國際中文電子版雜誌,由恆逸資訊創立於2000,自發刊日起迄今已發行超過500篇.NET相關技術文章,擁有超過40000名註冊讀者群。NET Magazine國際中文電子版雜誌希望藉於電子雜誌與NET Developer達到共同學習與技術新知分享,歡迎每一位對.NET 技術有興趣的朋友們多多支持本雜誌,讓作者群們可以有持續性的動力繼續爬文。<請加入免費訂閱>

月分類Month List