一、公共模板
1、@RenderBody()
在網站公用部分通過一個占位符@RenderBody()來為網站獨立部分預留一個位置。然后私有頁面頂部通過@{Layout="公用模板路徑"}來引入公用模板,並在自身放到公用模板的位置。同時也可以設置ViewData或ViewBag設置網站標題,關鍵詞等信息。
@{
Layout = "~/Views/Shared/_Layout.cshtml";
ViewBag.Title = "從這里可以設置網站標題";
}
<!DOCTYPE html> <html> <head> <title>@ViewBag.Title</title> </head> <body> <div>下面是頁面私有部分</div> @RenderBody() </body> </html>
這樣引入了公用的頁面其它部分,同時還設置了標題。
二、section-節
節:@section
通過在頁面中加入節可以設置多個公用模板部分,
@RenderSection("Footer") 定義一個節,當視圖不提供這個節的代碼時會報錯:節未定義:“xxxxxx”。
@RenderSection("Footer",false) 重載,如果設置了第二個參數為false,則說明這個節不是必須的,當視圖不提供這個節的代碼時也不會報錯。
下面演示一個頁腳節,下面是公用頁面模板
<!DOCTYPE html> <html> <head> <title>@ViewBag.Title</title> </head> <body> <div>下面是頁面私有部分</div> @RenderBody() @*<footer>@RenderSection("Footer")</footer>*@ //如果第二個參數不設置,那么如果當視圖沒有設置節的時候,則會提示錯誤。 <footer>@RenderSection("Footer",false)</footer> //如果設置了第二個參數為flase,那么視圖可以設置節也可以不設置節都沒問題。 </body> </html>
//這個是視圖
@{
Layout = "~/Views/Shared/_Layout.cshtml";
ViewBag.Title = "設置頂部標題";
}
你在他鄉還好嗎?
@section Footer{
這是頁腳節
}
這是整個頁面會包含公用模板,主體和頁腳節。
當頁面多個頁面都使用到了同一個布局時,每個頁面都要通過Layout屬性來指定它的布局,會造成冗余,_ViewStart.cshtml可以用來消除這種冗余,在Views目錄下又一個_ViewStart.cshtml文件,這個文件優先於同目錄下任何視圖的執行,可以用它來指定一個默認布局。
@{
Layout = "~/Views/Shared/_Layout.cshtml";
}
這樣所有的視圖都會將此布局作為默認布局,如果有視圖不想要此布局,可以在視圖中重寫Layout屬性。如果不想要布局,則設置Layout=""即可。
三、分部視圖
分部視圖顧名思義是一個視圖的一部分,它允許程序員將視圖中的一部分獨立出來,在某些需要的頁面引用。能夠減少代碼重復,提高頁面代碼重用性。
例如:下面這個是返回一個分部視圖的Action
public ActionResult GetName() { return PartialView(); }
在其它任意視圖中,只要寫如下代碼:
@Html.Partial("GetName")
//或者可以寫成這樣
@{
Html.RenderPartial("GetName");
}
就能夠在頁面中加載GetName視圖的完整代碼了。一般來說,分部視圖當中不應該包括js,或css因為這樣,等於在大視圖中到處都是分部視圖的JS與CSS了,一個好的做法是私有JS與CSS通過一個節來引入,這樣比較好。都是最好也不要有<head></head>里面的內容,以及<body></body>標簽。因為如果有了這些,還不如搞成布局呢。分部視圖這個東西最有用的地方在於能夠把頁面中共同的部分提取出來,在用的時候簡單引入就行,而實際上,分部視圖除了不能指定布局之外,幾乎跟普通視圖一樣,很爽的一個東西。引用視圖可以通過:
@Html.Partial("分部視圖名稱") //有或者下面三行
@{
Html.RenderPartial("分部視圖名稱");
}
另外分部視圖中要注意@Html.Partial()中的重載,這些重載常常有用,如果實在欠缺,就自己寫擴展方法來實現。來看看這些重載方法的方法簽名。
public static MvcHtmlString Partial(this HtmlHelper htmlHelper, string partialViewName);
public static MvcHtmlString Partial(this HtmlHelper htmlHelper, string partialViewName, object model);
public static MvcHtmlString Partial(this HtmlHelper htmlHelper, string partialViewName, ViewDataDictionary viewData);
public static MvcHtmlString Partial(this HtmlHelper htmlHelper, string partialViewName, object model, ViewDataDictionary viewData);
由方法簽名中可以看出來,這些都是擴展方法,@Html.Partial是可以將數據實體和數據字典給分部視圖的,然后分部視圖那邊可以通過主視圖傳過去的數據再生成視圖。
給個例子:傳遞一個Model過去分部視圖,然后分部視圖那邊根據傳入的數據再解釋視圖。來看Controller代碼
namespace MvcStart.Controllers { public class HomeController : Controller { public ActionResult Index() { Man_Model man = new Man_Model(); man.Id = 1; man.Name = "張飛"; man.Age = 23; return View(man); } public ActionResult getName(object o) { Man_Model man = o as Man_Model; return PartialView(man); } } public class Man_Model { public int Id { get; set; } public string Name { get; set; } public int Age { get; set; } } }
視圖代碼:Index.cshtml
@model MvcStart.Controllers.Man_Model
@Model.Id
@Model.Age
@Html.Partial("getId",Model);
getName.cshtml
@model MvcStart.Controllers.Man_Model <div style="background-color:red">@Model.Name</div>
生成的HTML代碼為:
<html> <head> <title>Index</title> </head> <body> 1 23 <div style="background-color:red">張飛</div> </body> </html>
例子寫的有點牽強,看不出有什么作用,但是真的是通過主視圖傳遞一個man_Model到分部視圖,再由分部視圖解析返回的Html代碼,這個東西能夠實現什么呢?舉個簡單的例子,如果分部視圖里面的代碼是由SEO人員操作的話,例如網頁標題,關鍵詞,描述,這個東西值提供了一個框在后台讓SEO人員設置,而設置的結果就是保存到分部視圖的代碼里面的話?那么只需要給傳入一個Model到分部視圖,分部視圖的標簽如Model.Name就能夠自動解析出真正的"張飛"數據。
2013-5-5,可能之前的理解有些錯誤,是可以傳遞Model到分部視圖這點不假,但是如果一個視圖加載了一個分部視圖,那么這個分部視圖所得到的數據會和原來頁面中的數據一模一樣。
舉個例子說明
Controller代碼:
namespace MvcApplication1.Controllers { public class HomeController : Controller { public ActionResult Index() { Person p = new Person(); p.Id = 1; p.Name = "張三"; ViewData["abc"] = "測試ViewData"; return View(p); } public ActionResult IndexPartial() { return View(); } } public class Person { public int Id { get; set; } public string Name { get; set; } } }
主視圖代碼:
@model MvcApplication1.Controllers.Person
@{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
@Model.Id
@Model.Name
@ViewData["abc"] = "123"
@Html.Partial("IndexPartial");
分部視圖代碼:
@model MvcApplication1.Controllers.Person @{ ViewBag.Title = "IndexPartial"; Layout = "~/Views/Shared/_Layout.cshtml"; } <br/> 分部視圖的內容 @Model.Name @Model.Id @ViewData["abc"] 分部視圖的內容 <br/>
留意到以上主視圖並未傳遞任何數據給分部視圖,但是執行結果如下,你可以看到分部視圖的確可以獲得主視圖中的數據:
再來記錄一個技巧,例如一個網站在調試的時候用的是一個測試路徑,上傳之后用的是真正的域名,這個時候我們可以將域名寫在配置文件或XML文件里,運行是讀取,這時候我們可以定義一個靜態屬性,該屬性返回真正的域名。在所有的視圖中都可以@命名空間.類.靜態變量 獲得真正的域名。也就是說,在視圖中一些小的可變化片段都可以這樣來獲取。
另外,特別需要注意Html.RenderAction()之類的方法還支持傳入參數,具體方式如下:
@Html.RenderAction("Left_Nav", "Nav", new{ ParentId = 3 });
跨區域調用的方式:
@{ Html.RenderAction("Datagrid", "DataList", new { area = "Common" }); }
在Action里面直接加個參數ActionResult(int ParentId)就能夠取得參數值。area會被MVC所截取,分析為跨區域調用。
區別:
Partial 分部視圖
另外還有Html.RenderPartial和Html.RenderAction,都是用於在模板頁中顯示一個功能相對獨立的塊。
Partial與RenderPartial的相同點
兩者都用於獲取一個分部視圖。
Partial與RenderPartial的區別
1. Partial有返回值(MvcHtmlString);RenderPartial沒有返回值(Void)。
有返回值可以@Html.Partial()
而沒有返回值就直接@{ Html.Partial(); }
Partial返回字符串,因此你可以用一個變量來接收返回的Html字符串。但是RenderPartial是將結果寫入到Response中,因此沒有辦法用變量來接收。
以上兩種寫法等價。
Action與RenderAction的區別
都用於引入一個Action的代碼,其區別與上面Partial和RenderPartial的區別相同
兩者的相同點
RenderPartial和RenderAction通常都被用來顯示一個功能相對獨立的“塊”,比如說顯示菜單或者導航條。 兩者輸出的結果都被作為調用的View的一部分顯示。
兩者的不同點
- RenderPatial的數據來自於調用的View,而RenderAction來自自己。
- RenderAction會發起一個新的Request,而RenderPatial不會。
- RenderPartial方法是return PartialView();而RenderAction是return View()。