CSHTML Layout Page、Partial View 執行順序實驗
7 |
維護 ASP.NET MVC 專案遇上巢狀 Layout 引用 Partial View 的情境,無法斷定執行先後順序,想必是自己觀念不清,做了以下實驗驗證,順手分享之。
假設有 ASP.NET MVC 巢狀 Layout 並混用 Partial View 結構如下:
_Layout.cshtml
@{
System.Diagnostics.Debug.WriteLine("_Layout.cshtml");
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>@ViewBag.Title</title>
</head>
<body>
@Html.Partial("_PartView1")
@RenderBody()
</body>
</html>
_PartView1.cshtml (_PartView2.cshtml 及 _PartView3.cshtml 做法相同,只有數字不同)
@{
System.Diagnostics.Debug.WriteLine("PartialView1");
}
<div>Partial View 1</div>
_NestedLayout.cshtml
@{
Layout = "~/Views/Shared/_Layout.cshtml";
System.Diagnostics.Debug.WriteLine("_NestedLayout.cshtml");
}
@Html.Partial("_PartView2")
@RenderBody()
Index.cshtml
@{
Layout = "~/Views/Shared/_NestedLayout.cshtml";
System.Diagnostics.Debug.WriteLine("Index.cshtml");
}
@Html.Partial("_PartView3")
<h2>Index</h2>
HomeController.cs
public class HomeController : Controller
{
// GET: Home
public ActionResult Index()
{
System.Diagnostics.Debug.WriteLine("Index Action");
return View();
}
}
執行結果不難預期:
問題來了,HomeController.cs、Index.cshtml、_PartView1.cshtml、_PartView2.cshtml、_PartView3.cshtml、_NestedLayout.cshtml、_Layout.cshtml 都埋了 System.Diagnostics.Debug.WriteLine(),將以什麼順序執行?
給大家 20 秒自我測驗。
答案揭曉:
HomeController Index Action –> Index.cshtml –> Partial View 3 –> _NestedLayout –> Partial View 2 -> _Layout –> Partial View 1
這順序不難理解,基本上就是從 HomeController.cs 開始,從 Index.cshtml、_NestedLayout.cshtml 到 _Layout.cshtml,由內而外的順序將 Razor View 轉為 HTML,生成 HTML 過程才載入 Partial View。
(原想找到官方文件證實,搜索未獲,十方大德如有知悉懇請不吝補充)
Using experiment to test and prove the execution sequence of controller server-side code, layout, view, partial view in nested scenarios.
Comments
# by 布萊恩
https://docs.microsoft.com/zh-tw/aspnet/web-pages/overview/ui-layouts-and-themes/3-creating-a-consistent-look 可供參考
# by Jeffrey
to 布萊恩, 感謝補充。
# by Rex
請問把專案升級到asp.net core 6.0後,_layout.cshtml內的相關<partial name >(目的:sidebar/header等),只要點相關網頁都會變成整頁(_layout)刷新;不知道是哪裡與asp.net core 5.0不一樣?
# by Jeffrey
to Rex, 能做出可重現問題的小專案丟上 Github 讓大家幫看嗎?
# by Rex
https://stackoverflow.com/questions/65586221/asp-net-core-client-side-validation-is-there-a-validation-succeeded-dom-event 如果照上面文章的說法, 似乎是我對_layout.cshtml的認知有錯, _layout.cshtml上<partial name>所link的網頁其實皆是同步(也就是皆會整頁更新); 若要點選<partial name>製成的sidebar內的item不同步,需另外搭配jquery的語法去解決; 請問不知如此解讀是否正確, 謝謝
# by Jeffrey
to Rex, 是的,PartialView 是伺服器端的技術,.cshtml 重新產生時才會再次執行,你期望的非同步部分頁面更新要靠 AJAX、IFrame 等前端技巧實現。
# by Rex
Thanks a lot ,受益良多