1、引言
開發人員經常希望應用程序可以在多個不同的地方使用同樣的Razor標簽和HTML標記代碼。這並不需要我們在多個地方重復這些標簽,使用MVC中的分部視圖和子動作可以讓我們很好的解決類似的情況。
2、Partial、RenderPartial的使用
使用MVC中的Html.RenderPartial、Html.RenderAction都可以在主界面中嵌入分部視圖,下面就來介紹這兩種技術。
我們創建一個視圖文件MyPartialView.cshtml。保存在Views/Home/文件夾下。與主界面放在一個文件夾下。其HTML標簽:
@model List<string> <div> <hr /> <p>我是分部視圖MyPartialView.cshtml</p> @*<p>傳遞的數據如下:</p>*@ <ul> @if(Model!=null){ foreach(var item in Model) { <li>@item</li> } } </ul> @*<p>傳遞的字符串是:</p> @ViewData["Para"]*@ <hr /> </div>
主界面Views/Home/Index.cshtml的HTML標簽如下:
@{ Layout = "~/Views/Shared/_Layout.cshtml"; } <h2> 當前頁面是:Home/Index.cshtml,調用分部視圖MyPartialView.cshtml <br /> @{ ViewData["Parameter"]="Values"; var data = new ViewDataDictionary(); data.Add("Para", ViewData["Parameter"]); } @*@Html.Partial("MyPartialView",new List<string>{"str1","str2","str3"},data)*@ @Html.Partial("MyPartialView") </h2>
在瀏覽器運行后可以看到有如下的效果:

可以看到我的代碼中有一些注釋。Html.Partial通過傳遞參數將數據傳遞到分部視圖。如上圖。這時候我嗎刷新瀏覽器就可以看到從主界面傳遞到分部視圖的參數了。

注意點:
1、Partial("MyPartialView")調用時,Razor引擎會在常規位置進行分部視圖的查找。先查找Views/Controller中查找,如果找不到到Views/Shared文件夾下進行查找。當然分部視圖也可以在這些常規位置以外的地方定義。例如:在Views/Menus/文件夾下定義MyPartialView.cshtml。主界面在調用時需要指定完整的路徑。如:Partial("~/Views/Menus/MyPartialView.cshtml")。
2、Html.Partial用於將分部視圖渲染為字符串,{Html.RenderPartial}將分布視圖直接寫入響應輸出流,所以只能直接放在代碼塊中,不能放在表達式中(返回值是void)。RenderPartial因為是直接寫在響應流中,所以性能會更好(微量影響),而Partial不用寫在代碼塊中,所以更方便。
3、Partial、RenderPartial在執行時都只是把一個個的View嵌入到調用界面中,其中不涉及到控制器的操作。不需要經過控制器View()來進行視圖的渲染操作。
3、Action、RenderAction的使用(子動作)
子動作是通過視圖來調用的動作方法。如果希望將某種控制器邏輯在應用程序的多處進行復用時,可以通過子動作來解決。
我們在Views/Home/文件夾下新建一個MyChildAction.cshtml視圖文件。其HTML標簽及代碼如下:
@model DateTime @{ ViewBag.Title = "MyChildAction"; } <h2>子動作界面</h2> <p>當前服務器時間是:</p> <p>@Model.ToShortDateString()</p>
我們現在來看HomeController中對於子動作的方法。代碼如下:
public class HomeController : Controller { public ActionResult Index() { return View(); } /** * 只能被子動作調用 * */ [ChildActionOnly] public ActionResult MyChildAction() { return PartialView(DateTime.Now); } }
我們看到HomeController中這個子動作只是簡單的返回一個服務端的當前時間。然后對MyChildAction視圖文件進行渲染。通過在主界面調用@{Html.RenderAction("MyChildAction");}。在使用分部視圖時推薦使用PartialView()。因為View()返回會讓框架認為這是一個標准視圖,會自動加上Layout布局文件。使用PartialView不會自動加上布局文件。

我們看到Html.RenderAction("MyChildAction")會導致MVC框架在處理當前請求的控制器中(例子中是:HomeController)查找一個動作方法。如果在其他控制器中定義了一個子動作。可以指定控制器的名稱。
例如:Html.RenderAction("MyChildAction","MySimple")。這樣MVC框架就會在MySimpleController控制器中查找MyChildAction方法進行執行。
在子動作中,可以在調用的時候進行參數的傳遞。如下所示:
[ChildActionOnly] public ActionResult MyChildAction(DateTime time) { time = time.AddYears(2); return PartialView(time); }
調用界面在調用時可以通過匿名對象來傳遞參數。如: @{Html.RenderAction("MyChildAction", new { time = DateTime.Now });}

注意點:
1、子動作是通過控制器來執行動作方法。處理ViewResult,然后注入到發送給客戶端的響應流中。這個方法相對於Partial比較靈活,它可以利用控制器的上下文。
2、ChildActionOnly注釋可以確定一個視圖方法只能在視圖中作為子動作進行調用。防止該子動作作為一個用戶請求的結果被調用。
4、Partial、Action兩者的異同點
相同點:
通常都被用來顯示一個功能相對獨立的“塊”,比如說顯示菜單或者導航條。 兩者輸出的結果都被作為調用的View的一部分顯示
不同點:
RenderPatial的數據來自於調用的View,而RenderAction來自自己。
RenderAction會發起一個新的Request,而RenderPatial不會。
最后給出一張圖來直觀的比較兩者的不同吧
