摘要:[ASP.NET MVC]部分視圖詳解
在網路上介紹的這幾種部分檢視的用法五花八門,個人是認為這幾種的分界已經漸漸的越來越模糊了拉,所以只提出主觀的見解:
在開始介紹之前,先要準備一些檔案,首先是要一個Layout.cshtml當作樣版,
剛好最近在研究jquery mobile,就從這邊[JQM]常用空白範本直接複製過來吧,用行動版網頁實驗比較有趣,首先先新增一個新的樣版,取名叫做_LayoutResearchPartial.cshtml,內容如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>@ViewBag.Title</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
@Styles.Render("~/Content/Mobile/css", "~/Content/jquerymobile/css")
@Scripts.Render("~/bundles/jquery", "~/bundles/jquerymobile")
@*也可用官方的CDN,比nuget:jquery.mobile.mvc內建的新,嗚嗚*@
@*<link rel="stylesheet" href="http://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.css" />
<script src="http://code.jquery.com/jquery-1.11.1.min.js"></script>
<script src="http://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.js"></script>*@
<script>
$(document).ready(function () {
$.mobile.ajaxEnabled = false;
});
</script>
</head>
<body>
<div data-role="page" data-theme="c">
<div data-role="header">
<h1>@ViewBag.Title</h1>
@RenderSection("headerSection", false)
</div>
<div data-role="content">
@RenderSection("contentSection", false)
@RenderBody()
</div>
</div>
</body>
</html>
並且新增一個Controller叫做ResearchPartialController.cs,內容就先用預設內容就好。
並且在Views資料夾下面,新增一個資料夾叫做ResearchPartial,用來放我們等等要測試用的View。
nuget請安裝jquery.mobile.mvc套件,純粹是因為用行動版的網頁測試比較有趣,因此而安裝。
然後就開始介紹了:
那麼就先來介紹@html.partial, @Html.RenderPartial:
從英文翻譯成中文的感覺來說,他就是單純的輸出一段已經寫好的html,就網路上的介紹來說,@html.partial, @Html.RenderPartial還是可以傳變數進去的,不過那樣會讓我感覺與@Html.Action,@Html.RenderAction的定位混淆,因此我寧願讓@html.partial, @Html.RenderPartial輸出單純的靜態html或是不用傳參數進去的Server端razor語法
為了測試@html.partial, @Html.RenderPartial,我們在剛剛新增的ResearchPartial資料夾新增一個View叫做TestPartialRenderPartial.cshtml,並且套用剛剛新增的_LayoutResearchPartial.cshtml為主版
然後在剛剛的Controller裡面加上這段來使用這個View:
public ActionResult TestPartialRenderPartial()
{
return View();
}
目前為止建立出來的網頁是空白的,還沒加入任何內容,如下:
現在先在~/Views/ResearchPartial/新增一個PartialView叫做_EasyStaticHtmlPartial.cshtml:,包含是靜態的網頁html如下(通常是header或是footer的內容,或是用來include一些.js或.css):
這是一個<strong>靜態html</strong>的內容
並且利用@Html.Partial以及@Html.RenderPartial語法,在剛剛的TestPartialRenderPartial.cshtml測試剛剛新增的partialView:_EasyStaticHtmlPartial.cshtml
TestPartialRenderPartial.cshtml的程式碼片段為:
@{
ViewBag.Title = "TestPartialRenderPartial";
Layout = "~/Views/Shared/_LayoutResearchPartial.cshtml.cshtml";
}
<h2>TestPartialRenderPartial</h2>
這是用@@Html.Partial產生的靜態html內容:
<br/>
@Html.Partial("~/Views/ResearchPartial/_EasyStaticHtmlPartial.cshtml")
<br />
這是用@@Html.RenderPartial產生的靜態html內容:
<br/>
@{Html.RenderPartial("~/Views/ResearchPartial/_EasyStaticHtmlPartial.cshtml");}
然後就可以看執行結果了,電腦版+手機版網頁:成功的利用@html.partial, @Html.RenderPartial在網頁上顯示靜態html
而@Html.Partial以及@Html.RenderPartial語法雖然也可以傳入動態的資料並顯示在畫面上,但是這樣會導致與其他的部分檢視用法混淆(例如:@Html.Action)
因此這裡寧願採用靜態html以及靜態的伺服器端Razor語法(就是programmer不用傳參數進去的意思)為主,這裡就示範一個顯示靜態的伺服器端Razor語法的例子:在~/Views/ResearchPartial新增另一個partialView叫做_EasyStaticRazorPartial.cshtml,內容為不用傳參數進去的一堆html以及伺服器端的Razor語法,如下:
@{
if(DateTime.Now.Month == 12)
{
<p>現在是12月</p>
}
else
{
<p>現在不是12月</p>
}
}
並且在TestPartialRenderPartial.cshtml引用這個partialview, 程式碼片段為:
<br/>
<br/>
<div>
這是用@@Html.Partial產生的非互動式(即免傳參數)razor內容:
<br />
@Html.Partial("~/Views/ResearchPartial/_EasyStaticRazorPartial.cshtml")
<br />
這是用@@Html.RenderPartial產生的非互動式(即免傳參數)razor內容:
<br />
@{Html.RenderPartial("~/Views/ResearchPartial/_EasyStaticRazorPartial.cshtml");}
</div>
執行結果為:
同時還有在@section裡面該用哪種部分檢視要注意,見參考文章第三篇
如何在@section裡面如何使用partialview也是很重要的,理論上說起來,@section裡面並不是@Html.Partial以及@Html.RenderPartial都可使用
因為@Html.RenderPartial產出來的是一般html string,而@section裡面的內容都是MVCHtmlString, 因此只有@Html.Partial能在@section裡面使用
但是實際上測試,卻是@Html.Partial 以及 @Html.RenderPartial皆可使用,真奇怪了...既然這樣就先不管理論,先示範一下範例,如何在@section裡面使用@Html.Partial 以及 @Html.RenderPartial:
TestPartialRenderPartial.cshtml內容改為如下:
程式碼會在section Header裡面示範@Html.Partial,且在section Content裡面示範@Html.RenderPartial
@{
ViewBag.Title = "TestPartialRenderPartial";
Layout = "~/Views/Shared/_LayoutResearchPartial.cshtml";
}
<h2>TestPartialRenderPartial</h2>
@section headerSection
{
@Html.Partial("~/Views/ResearchPartial/_EasyStaticRazorPartial.cshtml")
}
@section contentSection
{
@{Html.RenderPartial("~/Views/ResearchPartial/_EasyStaticRazorPartial.cshtml");}
}
執行結果如下:電腦版+手機版:
看到上面的執行結果,相信已經很清楚如何在@section裡面使用@Html.Partial以及@Html.RenderPartial了,學習這個的原因是因為只要是從asp.net web form出身的程式設計師,都一定會用過user control來顯示常常重複出現的程式碼,學習這個技巧就是為了在mvc的架構,達成相同的功用。
ps.補充:就目前的情況來看,@Html.Partial與@Html.RenderPartial的差別就只有效能而已,@Html.RenderPartial較好,因為直接輸出string,不用像是@Html.Partial輸出的MvcHtmlString還要暫存一下並且再轉換成string才輸出所以導致較慢
接下來介紹@Html.Action以及@Html.RenderAction:
其實跟@Html.Partial, @Html.RenderPartial本質上的意義差不多,都是幫忙程式設計師避免一直寫重複的html用的html helper
只是@Html.Action以及@Html.RenderAction有到伺服器端(Controller)進行一些Server端的程式碼或是取得資料庫的資料,然後再輸出而已
接下來就開始示範如何使用@Html.Action以及@Html.RenderAction:
首先新增一個範例資料庫AdventureWork, 可參考這篇文章[SQL]如何使用微軟的範例資料庫AdventureWorksDB直接從微軟網站下載.mdf檔案之後,直接新增到本機的SQLServer即可
並且在專案的~/Views/Models資料夾新增一個Ado.net Entity model(.edmx)來存取這個資料庫:
然後在~/Views/ResearchPartial資料夾新增一個PartialView叫做:_EasyDynamicRazorPartial.cshtml
此PartialView將會顯示範例資料庫的聯絡人資料表裡面的資料,內容程式碼如下:
@model IEnumerable<JQueryMobileMVC.Models.Contact>
<ul data-role="listview">
@foreach (var item in Model)
{
<li>
<h2>@Html.DisplayFor(modelItem => item.LastName)</h2>
<p>@Html.DisplayFor(modelItem => item.EmailAddress)</p>
</li>
}
</ul>
然後在ResearchPartialController.cs加入1個ActionResult,
這個Action取得從.cshtml傳過來的字串參數以及數字參數,並且隨便取得5筆資料庫抓出來的聯絡人資料,並以PartialView的形式回傳
public ActionResult GetActionRenderActionInfo(string stringValue, int intValue)
{
string stringValueGet = stringValue;
int intValueGet = intValue;
AdventureWorksEntities1 db = new AdventureWorksEntities1();
var contacts = db.Contact.Take(5);//隨便取得五筆聯絡人的資料
return PartialView("_EasyDynamicRazorPartial",contacts.ToList());
}
在~/Views/ResearchPartial資料夾下面新增一個View叫做TestActionRenderAction.cshtml, 主版版面一樣套用剛剛新增的_LayoutResearchPartial即可:
這個view的html如下:他示範了@Html.Action傳參數的用法,傳入字串777以及數字888,並且指定ResearchPartialController的GetActionRenderActionInfor這個Action來
執行伺服器端行為
@{
ViewBag.Title = "TestActionRenderAction";
Layout = "~/Views/Shared/_LayoutResearchPartial.cshtml";
}
<h2>TestActionRenderAction</h2>
<p>以下是@@Html.Action以partialview的方式到Controller取得的資料庫資料:</p>
@Html.Action("GetActionRenderActionInfo", "ResearchPartial", new { stringValue = "777", intValue = 888 })
<p>以下是@@Html.RenderAction以partialview的方式到Controller取得的資料庫資料</p>
@{
Html.RenderAction("GetActionRenderActionInfo", "ResearchPartial", new { stringValue = "777", intValue = 888 });
}
執行結果很順利的:電腦版+手機版:
然後當然也要介紹在@section裡面如何使用@Html.Action以及@Html.RenderAction:
經過實驗證明,在@section裡面只能用@Html.Action,不能使用@Html.RenderAction,網路上的說明是因為@Html.Action是直接輸出string,不是mvchtmlstring, 因此無法使用
但是這樣的理由在@Html.Partial, @Html.RenderPartial便無法成立,因此...我也不知道為什麼無法使用@Html.RenderAction XD
總之至少要知道如何使用@Html.Action,請看範例囉,以下是TestActionRenderAction.cshtml的html(避免畫面太過混亂,把剛剛部分的程式碼註解掉了):
@{
ViewBag.Title = "TestActionRenderAction";
Layout = "~/Views/Shared/_LayoutResearchPartial.cshtml";
}
<h2>TestActionRenderAction</h2>
@*<p>以下是@@Html.Action以partialview的方式到Controller取得的資料庫資料:</p>
@Html.Action("GetActionRenderActionInfo", "ResearchPartial", new { stringValue = "777", intValue = 888 })
<p>以下是@@Html.RenderAction以partialview的方式到Controller取得的資料庫資料</p>
@{
Html.RenderAction("GetActionRenderActionInfo", "ResearchPartial", new { stringValue = "777", intValue = 888 });
}*@
@section contentSection
{
@Html.Action("GetActionRenderActionInfo", "ResearchPartial", new { stringValue = "777", intValue = 888 });
@*無法使用Html.RenderAction,網路上說是因為他是直接輸出string,不是mvchtmlstring, 因此無法使用*@
@*Html.RenderAction("GetActionRenderActionInfo", "ResearchPartial", new { stringValue = "777", intValue = 888 });*@
}
執行結果為:電腦版+手機版:
最後是RenderPage:
功用與RenderPartial完全一樣,差異處只在於,RenderPartial可以傳入整個model或是使用ViewData(Session), 而RenderPage只能使用傳入的參數。然而,本文中為了讓各種部分檢視的定位分明,因此暫且當成RenderPage與RenderPartial是一樣的部分檢視,同樣為不傳入任何參數的HtmlHelper,功用既然相同,因此便不再做範例囉。
本篇大概是這樣。
參考文章:
ASP.NET MVC 部分视图详解
Html.Partial vs Html.RenderPartial & Html.Action vs Html.RenderAction
ASP.NET MVC 3: Multiple Html.RenderAction() Problem
http://stackoverflow.com/questions/6590767/asp-net-mvc-3-multiple-html-renderaction-problem
ASP.NET MVC - Html.Partial 與 Html.RenderPartial
http://kevintsengtw.blogspot.tw/2013/07/aspnet-mvc-htmlpartial-htmlrenderpartial.html
Razor: @Html.Partial() vs @RenderPage()
http://stackoverflow.com/questions/4501736/razor-html-partial-vs-renderpage